Re: [PATCH V2] Cygwin: gendef: Implement _sigfe function for TLS handling on AArch64

Jon Turney <[email protected]> Tue, 30 Jun 2026 20:32:34 +0100
Newsgroups gmane.os.cygwin.patches
Message-ID <[email protected]>
On 16/01/2026 17:41, Thirumalai Nagalingam wrote:
> Hi,
> 
> No additional changes in this version.
> This V2 patch was regenerated on top of `cygwin/main` and applies cleanly as-is, without any additional dependencies.
> 
> Thanks,
> Thirumalai Nagalingam
> 
> In-lined Patch:
> 
> diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
> index 32ceb3578..ab57739fa 100755
> --- a/winsup/cygwin/scripts/gendef
> +++ b/winsup/cygwin/scripts/gendef
> @@ -385,7 +385,44 @@ _sigfe_maybe:                                      # stack is aligned on entry!
>          ret
>          .seh_endproc
> 
> +    .seh_proc _sigfe
>   _sigfe:
> +    .seh_endprologue
> +    ldr     x10, [x18, #0x8]           // Load TLS base into x10
> +    mov     w9, #1                     // constant value for lock acquisition
> +0:  ldr     x11, =_cygtls.stacklock    // Load offset of stacklock
> +    add     x12, x10, x11              // Compute final address of stacklock
> +    ldaxr   w13, [x12]                 // Load current stacklock value atomically
> +    stlxr   w14, w9, [x12]             // Attempt to store 1 to stacklock atomically
> +    cbnz    w14, 0b                    // Retry if atomic store failed
> +    cbz     w13, 1f                    // If lock was free, proceed
> +    yield
> +    b       0b                         // Retry acquiring the lock
> +1:
> +    ldr     x11, =_cygtls.incyg        // Load offset of incyg
> +    add     x12, x10, x11              // Compute final address of incyg
> +    ldr     w9, [x12]                  // Load current incyg value
> +    add     w9, w9, #1                 // Increment incyg
> +    str     w9, [x12]                  // Store updated incyg value
> +    mov     x9, #8                     // Set stack frame size increment (8 bytes)
> +2:  ldr     x11, =_cygtls.stackptr     // Load offset of stack pointer
> +    add     x12, x10, x11              // Compute final address of stack pointer
> +    ldaxr   x13, [x12]                 // Atomically load current stack pointer
> +    add     x14, x13, x9               // Compute new stack pointer value
> +    stlxr   w15, x14, [x12]            // Attempt to update stack pointer atomically
> +    cbnz    w15, 2b                    // Retry if atomic update failed

I'm wondering if this is an over-literal conversion of the x86_64 
implementation.

That does use '[lock] xchgq', but I'm guessing that's not because the 
change on the sigstack needs to be atomic (because nothing else should 
be manipulating the sigstack while cygtls.stacklock is held?), but 
because a memory barrier is needed here (since writing to the sigstack 
needs to be complete before stacklock is released)? Or maybe it's just 
more concise to use xchg there?

This atomic operation also seems to be replicated into sigbe.

> +    str     x30, [x13]                 // Save LR(return address) on stack
> +    adr     x11, _sigbe                // Load address of _sigbe
> +    mov     x30, x11                   // Set LR = _sigbe
> +    ldr     x11, =_cygtls.stacklock    // Load offset of stacklock TLS variable
> +    add     x12, x10, x11              // Compute final address of stacklock
> +    ldr     w9, [x12]                  // Load current stacklock value
> +    sub     w9, w9, #1                 // Decrement stacklock to release lock
> +    stlr    w9, [x12]                  // Store stacklock value (release lock)
> +    ldr     x9, [sp], #16              // Pop real func address from stack
> +    br      x9                         // Branch to real function
> +    .seh_endproc
> +