@@ -407,7 +407,75 @@ _ZN7_cygtls3popEv:
407407
408408 .seh_proc stabilize_sig_stack
409409stabilize_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
413481EOF
0 commit comments