https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=84a608608969523b9ef374cd0f5383bbcd020b39

commit 84a608608969523b9ef374cd0f5383bbcd020b39
Author:     Igor Podgainoi <[email protected]>
AuthorDate: Thu Feb 19 08:44:01 2026 +0000
Commit:     Corinna Vinschen <[email protected]>
CommitDate: Wed Mar 11 15:49:34 2026 +0100

    Cygwin: signal: Fix stabilize_sig_stack/setjmp/longjmp on AArch64
    
    This commit fixes the AArch64 implementation of the following three
    functions: stabilize_sig_stack, setjmp and longjmp.
    
    Changes made:
    
    * Fixed code indentation in all three functions.
    * Corrected some comments and added additional ones.
    * Added missing SEH directives.
    * Changed the locking algorithm in stabilize_sig_stack to Test and
      Test-and-Set (TTAS).
    * Stopped returning a value in x0 in stabilize_sig_stack to avoid
      unnecessary clobbering. This should make it more similar to the
      x86_64 version.
    * Using x10 instead of x0 in setjmp and longjmp where needed as per
      the previous change.
    * Fixed bug in setjmp where the SP value after the prologue was used,
      instead of the original one.
    * Fixed bug in setjmp where the stackptr was saved at the wrong offset
      into jmp_buf (should be 0).
    * Now saving and restoring x0 in setjmp and x0/x1 in longjmp around the
      call to stabilize_sig_stack. This should make it more similar to the
      x86_64 version.
    * Removed the prologue and epilogue in longjmp, as the function never
      returns.
    * Changed logic in longjmp to take the return value directly from the
      second argument. This should make it more similar to the x86_64
      version.
    * Fixed bug in longjmp where the TLS stack pointer restoration used an
      invalid base register.
    * Using zero registers instead of an immediate 0 where possible.
    
    Tests fixed on AArch64:
    winsup.api/mmaptest02.exe
    winsup.api/mmaptest03.exe
    winsup.api/ltp/mmap05.exe
    
    Signed-off-by: Igor Podgainoi <[email protected]>

Diff:
---
 winsup/cygwin/scripts/gendef | 277 ++++++++++++++++++++++---------------------
 1 file changed, 142 insertions(+), 135 deletions(-)

diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
index fb325ea01f73..7097da2e61c6 100755
--- a/winsup/cygwin/scripts/gendef
+++ b/winsup/cygwin/scripts/gendef
@@ -624,81 +624,83 @@ _sigdelayed_end:
        .global _sigdelayed_end
        .seh_proc stabilize_sig_stack
 stabilize_sig_stack:
-    // prologue
-    stp     fp, lr, [sp, #-0x10]!        // save FP and LR registers
-    .seh_save_fplr_x 0x10
-    mov     fp, sp                       // set frame pointer for unwinder
-    .seh_set_fp
-    .seh_endprologue
+       // prologue
+       stp     fp, lr, [sp, #-0x10]!           // save FP and LR registers
+       .seh_save_fplr_x 0x10
+       mov     fp, sp                          // set frame pointer for 
unwinder
+       .seh_set_fp
+       .seh_endprologue
 
-    ldr     x10, [x18, #0x8]             // load TLS block base pointer into 
x10
+       ldr     x10, [x18, #0x8]                // load TLS block base pointer 
into x10
 
-    // try to acquire the lock
-    mov     w9, #1                       // value to store (1 == locked)
-    ldr     x11, =_cygtls.stacklock      // load the symbol offset
-    add     x12, x10, x11                // x12 = tls_base + &stacklock
+       // try to acquire the lock
+       mov     w9, #1                          // value to store (1 == locked)
+       ldr     x11, =_cygtls.stacklock         // load the symbol offset
+       add     x12, x10, x11                   // x12 = tls_base + &stacklock
 1:
-    ldaxr   w13, [x12]                   // load old lock value
-    stlxr   w14, w9, [x12]               // attempt to store 1
-    cbnz    w14, 1b                      // if store failed, retry
-    cbz     w13, 2f                      // if lock was acquired, continue
-    yield                                // yield to allow other threads to run
-    b       1b                           // retry acquiring the lock
+       ldaxr   w13, [x12]                      // load old lock value
+       cbnz    w13, 2f                         // if already locked, wait
+       stxr    w14, w9, [x12]                  // attempt to acquire the lock
+       cbnz    w14, 1b                         // if locking failed, retry
+       b       3f                              // lock acquired, continue
 
 2:
-    // lock acquired, increment incyg counter
-    ldr     x11, =_cygtls.incyg          // load the symbol offset
-    add     x12, x10, x11                // x12 = tls_base + &incyg
-    ldr     w9, [x12]                    // load current value of incyg
-    add     w9, w9, #1                   // increment incyg counter
-    str     w9, [x12]                    // store back incremented value
-
-    // check current_sig
-    ldr     x11, =_cygtls.current_sig    // load the symbol offset
-    ldr     w9, [x10, x11]               // load current value of current_sig
-    cbz     w9, 3f                       // if no current signal, jump to 
cleanup
-
-    // release lock before calling signal handler
-    ldr     x11, =_cygtls.stacklock      // load the symbol offset
-    add     x12, x10, x11                // x12 = tls_base + &stacklock
-    ldr     w9, [x12]                    // load current value of stacklock
-    sub     w9, w9, #1                   // decrement stacklock
-    stlr    w9, [x12]                    // store with release semantics
-
-    // prepare arg and call handler
-    ldr     x0, =_cygtls.start_offset    // load the symbol offset
-    add     x0, x10, x0                  // x0 = tls_base + &start_offset
-    bl      _ZN7_cygtls19call_signal_handlerEv
-
-    // call may clobber x10, restore TLS base
-    ldr     x10, [x18, #0x8]             // reload tls_base
-
-    // decrement incyg
-    ldr     x11, =_cygtls.incyg
-    add     x12, x10, x11
-    ldr     w9, [x12]
-    sub     w9, w9, #1
-    str     w9, [x12]
-
-    // loop to handle another signal
-    b       1b
+       yield                                   // yield to allow other threads 
to run
+       b       1b                              // retry acquiring the lock
 
 3:
-    // no signal to handle, decrement incyg counter
-    ldr     x11, =_cygtls.incyg
-    add     x12, x10, x11
-    ldr     w9, [x12]
-    sub     w9, w9, #1
-    str     w9, [x12]
-
-    mov     x0, x10                      // return TLS address in x0 (return 
register)
-
-    // epilogue
-    .seh_startepilogue
-    ldp     fp, lr, [sp], #0x10
-    .seh_endepilogue
-    ret
-    .seh_endproc
+       // lock acquired, increment incyg counter
+       ldr     x11, =_cygtls.incyg             // load the symbol offset
+       add     x12, x10, x11                   // x12 = tls_base + &incyg
+       ldr     w9, [x12]                       // load current value of incyg
+       add     w9, w9, #1                      // increment incyg counter
+       str     w9, [x12]                       // store back incremented value
+
+       // check current_sig
+       ldr     x11, =_cygtls.current_sig       // load the symbol offset
+       ldr     w9, [x10, x11]                  // load current value of 
current_sig
+       cbz     w9, 4f                          // if no current signal, jump 
to cleanup
+
+       // release lock before calling signal handler
+       ldr     x11, =_cygtls.stacklock         // load the symbol offset
+       add     x12, x10, x11                   // x12 = tls_base + &stacklock
+       ldr     w9, [x12]                       // load current value of 
stacklock
+       sub     w9, w9, #1                      // decrement stacklock
+       stlr    w9, [x12]                       // store with release semantics
+
+       // prepare arg and call handler
+       ldr     x0, =_cygtls.start_offset       // load the symbol offset
+       add     x0, x10, x0                     // x0 = tls_base + &start_offset
+       bl      _ZN7_cygtls19call_signal_handlerEv
+
+       // call may clobber x10, restore TLS base
+       ldr     x10, [x18, #0x8]                // reload tls_base, use as 
return value
+
+       // decrement incyg
+       ldr     x11, =_cygtls.incyg             // load the symbol offset
+       add     x12, x10, x11                   // x12 = tls_base + &incyg
+       ldr     w9, [x12]                       // load current value of incyg
+       sub     w9, w9, #1                      // decrement incyg counter
+       str     w9, [x12]                       // store back decremented value
+
+       // loop to handle another signal
+       b       1b
+
+4:
+       // no signal to handle, decrement incyg counter
+       ldr     x11, =_cygtls.incyg             // load the symbol offset
+       add     x12, x10, x11                   // x12 = tls_base + &incyg
+       ldr     w9, [x12]                       // load current value of incyg
+       sub     w9, w9, #1                      // decrement incyg counter
+       str     w9, [x12]                       // store back decremented value
+
+       // epilogue
+       .seh_startepilogue
+       ldp     fp, lr, [sp], #0x10             // restore FP and LR registers
+       .seh_save_fplr_x 0x10
+       .seh_endepilogue
+       ret
+       .seh_endproc
 EOF
        }
     }
@@ -867,19 +869,21 @@ sigsetjmp:
        .seh_proc setjmp
 setjmp:
        // prologue
-       stp     fp, lr, [sp, #-0x10]!           // push frame pointer (x29) and 
link register (x30)
-       mov     fp, sp                          // set frame pointer
+       stp     fp, lr, [sp, #-0x10]!           // save FP and LR registers
+       .seh_save_fplr_x 0x10
+       mov     fp, sp                          // set frame pointer for 
unwinder
+       .seh_set_fp
        .seh_endprologue
 
        // save callee-saved registers from jump buffer
-       stp     x19, x20, [x0, #0x08]           // save x19, x20
-       stp     x21, x22, [x0, #0x18]           // save x21, x22
-       stp     x23, x24, [x0, #0x28]           // save x23, x24
-       stp     x25, x26, [x0, #0x38]           // save x25, x26
-       stp     x27, x28, [x0, #0x48]           // save x27, x28
-       stp     x29, x30, [x0, #0x58]           // save frame ptr (x29) and 
return addr (x30)
-
-       mov     x1, sp                          // get the current stack pointer
+       stp     x19, x20, [x0, #0x08]           // save x19, x20
+       stp     x21, x22, [x0, #0x18]           // save x21, x22
+       stp     x23, x24, [x0, #0x28]           // save x23, x24
+       stp     x25, x26, [x0, #0x38]           // save x25, x26
+       stp     x27, x28, [x0, #0x48]           // save x27, x28
+       stp     x29, x30, [x0, #0x58]           // save x29 (FP) and x30 (LR)
+
+       add     x1, sp, #0x10                   // get the old stack pointer
        str     x1, [x0, #0x68]                 // save SP
 
        mrs     x1, fpcr                        // get fp control register
@@ -888,35 +892,39 @@ setjmp:
        str     x1, [x0, #0x78]                 // save FPSR
 
        // save fp registers (d8-d15)
-       stp     d8,  d9,  [x0, #0x80]           // save d8, d9
-       stp     d10, d11, [x0, #0x90]           // save d10, d11
-       stp     d12, d13, [x0, #0xA0]           // save d12, d13
-       stp     d14, d15, [x0, #0xB0]           // save d14, d15
+       stp     d8,  d9,  [x0, #0x80]           // save d8, d9
+       stp     d10, d11, [x0, #0x90]           // save d10, d11
+       stp     d12, d13, [x0, #0xA0]           // save d12, d13
+       stp     d14, d15, [x0, #0xB0]           // save d14, d15
 
-       mov x9, x0                              // save jmp_buf pointer in x9
-       # // save TLS stack pointer
-       # ldr   x1, [sp]
-       # str   x1, [x0, #0xB8]
+       // save TLS stack pointer
+       ldr     x1, [sp, #0x10]                 // get the TLS stack pointer
+       str     x1, [x0, #0xB8]                 // save TLS stack pointer
 
-       bl      stabilize_sig_stack             // call stabilize_sig_stack 
(returns TLS in x0)
+       str     x0, [sp, #-0x10]!               // save jmp_buf before call
+       bl      stabilize_sig_stack             // call stabilize_sig_stack 
(returns TLS in x10)
+       ldr     x0, [sp], #0x10                 // restore jmp_buf after call
 
        // store the stack pointer to jump_buf
-       ldr     x2, =_cygtls.stackptr           // load the symbol 
address/offset
-       add     x2, x0, x2                      // Final address of stackptr
+       ldr     x2, =_cygtls.stackptr           // load the symbol offset
+       add     x2, x10, x2                     // x2 = tls_base + &stackptr
        ldr     x3, [x2]                        // load current value of 
stackptr
-       str x3, [x0, #0xB8]                     // store stackptr into jmp_buf
+       str     x3, [x0]                        // store stackptr into jmp_buf
 
        // decrement the stack lock
-       ldr     x2, =_cygtls.stacklock          // load the symbol 
address/offset
-       add     x2, x0, x2                      // Final address of stacklock
+       ldr     x2, =_cygtls.stacklock          // load the symbol offset
+       add     x2, x10, x2                     // x2 = tls_base + &stacklock
        ldr     w3, [x2]                        // load current stacklock value
        sub     w3, w3, #1                      // decrement
-       str     w3, [x2]                        //store back
+       str     w3, [x2]                        // store back
 
-       mov     w0, #0                          // return 0
+       mov     w0, wzr                         // return 0
 
        // epilogue
+       .seh_startepilogue
        ldp     fp, lr, [sp], #0x10             // restore saved FP and LR 
registers
+       .seh_save_fplr_x 0x10
+       .seh_endepilogue
        ret
        .seh_endproc
 
@@ -952,66 +960,65 @@ siglongjmp:
        .seh_proc longjmp
 longjmp:
        // prologue
-       stp     fp, lr, [sp, #-0x20]!                   // save FP and LR 
registers, allocate additional 16 bytes for function arguments
-       stp     x0, x1, [sp, #0x10]                     // save function 
arguments (jump buffer and return value)
-       mov     fp, sp                                  // establishing frame 
chain
        .seh_endprologue
 1:
-       bl      stabilize_sig_stack                     // call 
stabilize_sig_stack which returns TLS pointer in x0
-       ldr     x2, [sp, #0x10]                         // get jump buffer 
pointer from stack
-       ldr     x10, [x2]                               // get old signal stack 
from jump buffer
+       stp     x0, x1, [sp, #-0x10]!           // save function args (jmp_buf 
and return value)
+       bl      stabilize_sig_stack             // call stabilize_sig_stack 
(returns TLS in x10)
+       ldp     x2, x3, [sp], #0x10             // restore jmp_buf and return 
value to x2 and x3
+       ldr     x9, [x2]                        // get old signal stack from 
jump buffer
 
        // restore stack pointer in TLS
-       ldr     x11, =_cygtls.stackptr
-       add     x11, x0, x11
-       str     x10, [x11]
+       ldr     x11, =_cygtls.stackptr          // load the symbol offset
+       add     x11, x10, x11                   // x11 = tls_base + &stackptr
+       str     x9, [x11]                       // store signal stack into 
stackptr
 
        // release lock by decrementing counter
-       ldr     x11, =_cygtls.stacklock
-       add     x11, x0, x11
-       ldr     w12, [x11]
-       sub     w12, w12, #1
-       str     w12, [x11]
+       ldr     x11, =_cygtls.stacklock         // load the symbol offset
+       add     x11, x10, x11                   // x11 = tls_base + &stacklock
+       ldr     w12, [x11]                      // load current stacklock value
+       sub     w12, w12, #1                    // decrement
+       str     w12, [x11]                      // store back
 
        // we're not in cygwin anymore, clear "in cygwin" flag
-       ldr     x11, =_cygtls.incyg
-       add     x11, x0, x11
-       mov     w12, #0
-       str     w12, [x11]
+       ldr     x11, =_cygtls.incyg             // load the symbol offset
+       add     x11, x10, x11                   // x11 = tls_base + &incyg
+       mov     w12, wzr                        // clear the incyg counter
+       str     w12, [x11]                      // store back the new value
 
-       // get saved return value before SP is restored
-       ldr     x0, [sp, #0x10]
+       // use second argument as the return value
+       mov     x0, x3                          // move saved return value to x0
 
        // restore callee-saved registers from jump buffer
-       ldp     x19, x20, [x2, #0x08]                   // restore x19, x20
-       ldp     x21, x22, [x2, #0x18]                   // restore x21, x22
-       ldp     x23, x24, [x2, #0x28]                   // restore x23, x24
-       ldp     x25, x26, [x2, #0x38]                   // restore x25, x26
-       ldp     x27, x28, [x2, #0x48]                   // restore x27, x28
-       ldp     fp, lr, [x2, #0x58]                     // restore x29 (frame 
pointer) and x30 (link register)
-       ldr     x10, [x2, #0x68]                        // get saved stack 
pointer
-       mov     sp, x10                                 // restore stack pointer
-       ldr     x10, [x2, #0x70]                        // load floating-point 
control register
-       msr     fpcr, x10                               // restore FPCR
-       ldr     x10, [x2, #0x78]                        // load floating-point 
status register
-       msr     fpsr, x10                               // restore FPSR
+       ldp     x19, x20, [x2, #0x08]           // restore x19, x20
+       ldp     x21, x22, [x2, #0x18]           // restore x21, x22
+       ldp     x23, x24, [x2, #0x28]           // restore x23, x24
+       ldp     x25, x26, [x2, #0x38]           // restore x25, x26
+       ldp     x27, x28, [x2, #0x48]           // restore x27, x28
+       ldp     x29, x30, [x2, #0x58]           // restore x29 (FP) and x30 (LR)
+       ldr     x10, [x2, #0x68]                // get saved stack pointer
+       mov     sp, x10                         // restore stack pointer
+       ldr     x10, [x2, #0x70]                // load floating-point control 
register
+       msr     fpcr, x10                       // restore FPCR
+       ldr     x10, [x2, #0x78]                // load floating-point status 
register
+       msr     fpsr, x10                       // restore FPSR
 
        // restore floating-point registers (d8-d15)
-       ldp     d8, d9, [x2, #0x80]
-       ldp     d10, d11, [x2, #0x90]
-       ldp     d12, d13, [x2, #0xA0]
-       ldp     d14, d15, [x2, #0xB0]
+       ldp     d8, d9, [x2, #0x80]             // restore d8, d9
+       ldp     d10, d11, [x2, #0x90]           // restore d10, d11
+       ldp     d12, d13, [x2, #0xA0]           // restore d12, d13
+       ldp     d14, d15, [x2, #0xB0]           // restore d14, d15
 
        // restore TLS stack pointer
-       ldr     x1, [x0, #0xB8]
-       str     x1, [sp]
+       ldr     x1, [x2, #0xB8]                 // get the saved TLS stack 
pointer
+       str     x1, [sp]                        // restore TLS stack pointer
 
        // ensure return value is non-zero (C standard requirement)
-       cbnz    x0, 0f
-       mov     x0, #1
+       cbnz    x0, 0f                          // if return value non-zero, 
return
+       mov     x0, #1                          // set return value to 1
 0:
        // epilogue
-       add     sp, sp, #0x10                           // FP and LR are 
already restored, just restore SP as it would be popped
+       .seh_startepilogue
+       .seh_endepilogue
        ret
        .seh_endproc
 EOF

Reply via email to