@@ -407,7 +407,74 @@ _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+ .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
413480EOF
0 commit comments