Skip to content

Commit 2e7d7e9

Browse files
committed
Implement stabilize_sig_stack
1 parent f38f237 commit 2e7d7e9

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

winsup/cygwin/scripts/gendef

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,75 @@ _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+
stp x9, x10, [sp, #-0x10]! // save x9 and x10 registers used next
413+
stp x11, x12, [sp, #-0x10]! // save x11 and x12 registers used next
414+
stp x13, x14, [sp, #-0x10]! // save x13 register used next and x14 just to keep stack orientation and alignment
410415
.seh_endprologue
416+
417+
ldr x10, [x18, #0x8] // keep thread local storage base address in x10
418+
419+
// try to acquire the lock
420+
mov w9, #1 // set up value for atomic exchange
421+
ldr x11, =_cygtls.stacklock // load the symbol address/offset
422+
add x11, x10, x11 // calculate final address
423+
1:
424+
ldaxr w12, [x11] // load with acquire semantics
425+
stlxr w13, w9, [x11] // store with release semantics
426+
cbnz w13, 1b // if store failed, retry
427+
cbz w12, 2f // if lock was acquired, continue
428+
yield // yield to allow other threads to run
429+
b 1b // retry acquiring the lock
430+
2:
431+
// lock acquired, increment incyg counter
432+
ldr x11, =_cygtls.incyg // load the symbol address/offset
433+
add x11, x10, x11 // calculate final address
434+
ldr w9, [x11] // load current value of incyg counter
435+
add w9, w9, #1 // increment incyg counter
436+
str w9, [x11] // store incremented value back
437+
438+
// check if there is a current signal to handle
439+
ldr x11, =_cygtls.current_sig // load the symbol address/offset
440+
ldr w9, [x10, x11] // load current value of current_sig
441+
cbz w9, 3f // if no current signal, jump to cleanup
442+
443+
// release lock before calling signal handler
444+
ldr x11, =_cygtls.stacklock // load the symbol address/offset
445+
add x11, x10, x11 // calculate final address
446+
ldr w9, [x11] // load current value of stacklock counter
447+
sub w9, w9, #1 // decrement stacklock counter
448+
stlr w9, [x11] // store with release semantics
449+
450+
// prepare arguments and call signal handler
451+
ldr x0, =_cygtls.start_offset // load the symbol address/offset
452+
add x0, x10, x0 // calculate final address
453+
bl _ZN7_cygtls19call_signal_handlerEv
454+
455+
// decrement incyg counter
456+
ldr x11, =_cygtls.incyg // load the symbol address/offset
457+
add x11, x10, x11 // calculate final address
458+
ldr w9, [x11] // load current value of incyg counter
459+
sub w9, w9, #1 // decrement incyg counter
460+
str w9, [x11] // store incremented value back
461+
462+
// go to the beginning to handle another signal
463+
b 1b
464+
3:
465+
// no signal to handle, decrement incyg counter
466+
ldr x11, =_cygtls.incyg // load the symbol address/offset
467+
add x11, x10, x11 // calculate final address
468+
ldr w9, [x11] // load current value of incyg counter
469+
sub w9, w9, #1 // decrement incyg counter
470+
str w9, [x11] // store incremented value back
471+
472+
mov x0, x10 // return TLS address in x0 (return value)
473+
474+
// epilogue
475+
ldp x13, x14, [sp], #0x10
476+
ldp x11, x12, [sp], #0x10
477+
ldp x9, x10, [sp], #0x10
478+
ldp fp, lr, [sp], #0x10
411479
ret
412480
.seh_endproc
413481
EOF

0 commit comments

Comments
 (0)