Skip to content

Commit 3089c70

Browse files
committed
Implement stabilize_sig_stack
1 parent 0221d8f commit 3089c70

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

winsup/cygwin/scripts/gendef

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,74 @@ _ZN7_cygtls3popEv:
407407
408408
.seh_proc stabilize_sig_stack
409409
stabilize_sig_stack:
410+
// prologue
411+
stp fp, lr, [sp, #-0x10]! // save FP and LR registers
412+
.seh_save_fplr_x+ 16
410413
.seh_endprologue
414+
415+
ldr x10, [x18, #0x8] // keep thread local storage base address in x10
416+
417+
// try to acquire the lock
418+
mov w9, #1 // set up value for atomic exchange
419+
ldr x11, =_cygtls.stacklock // load the symbol address/offset
420+
add x12, x10, x11 // calculate final address
421+
1:
422+
ldaxr w13, [x12] // load with acquire semantics
423+
stlxr w14, w9, [x12] // store with release semantics
424+
cbnz w14, 1b // if store failed, retry
425+
cbz w13, 2f // if lock was acquired, continue
426+
yield // yield to allow other threads to run
427+
b 1b // retry acquiring the lock
428+
2:
429+
// lock acquired, increment incyg counter
430+
ldr x11, =_cygtls.incyg // load the symbol address/offset
431+
add x12, x10, x11 // calculate final address
432+
ldr w9, [x12] // load current value of incyg counter
433+
add w9, w9, #1 // increment incyg counter
434+
str w9, [x12] // store incremented value back
435+
436+
// check if there is a current signal to handle
437+
ldr x11, =_cygtls.current_sig // load the symbol address/offset
438+
ldr w9, [x10, x11] // load current value of current_sig
439+
cbz w9, 3f // if no current signal, jump to cleanup
440+
441+
// release lock before calling signal handler
442+
ldr x11, =_cygtls.stacklock // load the symbol address/offset
443+
add x12, x10, x11 // calculate final address
444+
ldr w9, [x12] // load current value of stacklock counter
445+
sub w9, w9, #1 // decrement stacklock counter
446+
stlr w9, [x12] // store with release semantics
447+
448+
// prepare arguments and call signal handler
449+
ldr x0, =_cygtls.start_offset // load the symbol address/offset
450+
add x0, x10, x0 // calculate final address
451+
bl _ZN7_cygtls19call_signal_handlerEv
452+
ldr x10, [x18, #0x8] // restore x10 that may have been modified by the call
453+
454+
// decrement incyg counter
455+
ldr x11, =_cygtls.incyg // load the symbol address/offset
456+
add x12, x10, x11 // calculate final address
457+
ldr w9, [x12] // load current value of incyg counter
458+
sub w9, w9, #1 // decrement incyg counter
459+
str w9, [x12] // store decremented value back
460+
461+
// go to the beginning to handle another signal
462+
b 1b
463+
3:
464+
// no signal to handle, decrement incyg counter
465+
ldr x11, =_cygtls.incyg // load the symbol address/offset
466+
add x12, x10, x11 // calculate final address
467+
ldr w9, [x12] // load current value of incyg counter
468+
sub w9, w9, #1 // decrement incyg counter
469+
str w9, [x12] // store decremented value back
470+
471+
mov x0, x10 // return TLS address in x0 (return value)
472+
473+
// epilogue
474+
.seh_startepilogue
475+
ldp fp, lr, [sp], #0x10
476+
.seh_save_fplr_x+ 16
477+
.seh_endepilogue
411478
ret
412479
.seh_endproc
413480
EOF

0 commit comments

Comments
 (0)