Skip to content

Commit fac5e8b

Browse files
committed
Implement longjmp
1 parent 7bbfec3 commit fac5e8b

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

winsup/cygwin/scripts/gendef

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,63 @@ siglongjmp:
687687
.globl longjmp
688688
.seh_proc longjmp
689689
longjmp:
690+
// prologue
691+
stp fp, lr, [sp, #-0x20]! // save FP and LR registers, allocate additional 16 bytes for function arguments
692+
stp x0, x1, [sp, #0x10] // save function arguments (jump buffer and return value)
693+
mov fp, sp // establishing frame chain
690694
.seh_endprologue
695+
1:
696+
bl stabilize_sig_stack // call stabilize_sig_stack which returns TLS pointer in x0
697+
ldr x2, [sp, #0x10] // get jump buffer pointer from stack
698+
ldr x10, [x2] // get old signal stack from jump buffer
699+
700+
// restore stack pointer in TLS
701+
ldr x11, =_cygtls.stackptr
702+
add x11, x0, x11
703+
str x10, [x11]
704+
705+
// release lock by decrementing counter
706+
ldr x11, =_cygtls.stacklock
707+
add x11, x0, x11
708+
ldr w12, [x11]
709+
sub w12, w12, #1
710+
str w12, [x11]
711+
712+
// we're not in cygwin anymore, clear "in cygwin" flag
713+
ldr x11, =_cygtls.incyg
714+
add x11, x0, x11
715+
mov w12, #0
716+
str w12, [x11]
717+
718+
// get saved return value before SP is restored
719+
ldr x0, [sp, #0x10]
720+
721+
// restore callee-saved registers from jump buffer
722+
ldp x19, x20, [x2, #0x08] // restore x19, x20
723+
ldp x21, x22, [x2, #0x18] // restore x21, x22
724+
ldp x23, x24, [x2, #0x28] // restore x23, x24
725+
ldp x25, x26, [x2, #0x38] // restore x25, x26
726+
ldp x27, x28, [x2, #0x48] // restore x27, x28
727+
ldp fp, lr, [x2, #0x58] // restore x29 (frame pointer) and x30 (link register)
728+
ldr x10, [x2, #0x68] // get saved stack pointer
729+
mov sp, x10 // restore stack pointer
730+
ldr x10, [x2, #0x70] // load floating-point control register
731+
msr fpcr, x10 // restore FPCR
732+
ldr x10, [x2, #0x78] // load floating-point status register
733+
msr fpsr, x10 // restore FPSR
734+
735+
// restore floating-point registers (d8-d15)
736+
ldp d8, d9, [x2, #0x80]
737+
ldp d10, d11, [x2, #0x90]
738+
ldp d12, d13, [x2, #0xA0]
739+
ldp d14, d15, [x2, #0xB0]
740+
741+
// ensure return value is non-zero (C standard requirement)
742+
cbnz x0, 0f
743+
mov x0, #1
744+
0:
745+
// epilogue
746+
add sp, sp, #0x10 // FP and LR are already restored, just restore SP as it would be popped
691747
ret
692748
.seh_endproc
693749
EOF

0 commit comments

Comments
 (0)