-
Notifications
You must be signed in to change notification settings - Fork 0
Implement stabilize_sig_stack
#27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: woarm64
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -399,7 +399,48 @@ _sigdelayed_end: | |
|
|
||
| .seh_proc stabilize_sig_stack | ||
| stabilize_sig_stack: | ||
| // prologue | ||
| stp fp, lr, [sp, #-0x10]! // save FP and LR registers | ||
eukarpov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .seh_save_fplr_x 16 | ||
| stp x19, x20, [sp, #-0x10]! | ||
| .seh_save_regp_x x19, 16 | ||
| .seh_endprologue | ||
|
|
||
| ldr x9, [x18, #0x8] // load thread local storage base address | ||
| mov x19, #_cygtls.current_sig // load the _cygtls.current_sig offset | ||
thiru-mcw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| add x19, x9, x19 // final address of current_sig | ||
| mov x20, #_cygtls.incyg // load the _cygtls.incyg offset | ||
| add x20, x9, x20 // final address of incyg | ||
|
|
||
| 1: | ||
Blackhex marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // check if there is a current signal to handle | ||
| ldr w9, [x19] // load current_sig | ||
| cbz w9, 2f // if no current signal, jump to cleanup | ||
|
|
||
| mov w9, #1 // specify increment | ||
| staddl w9, [x20] // atomically increment incyg with a lock | ||
|
|
||
| // prepare arguments and call signal handler | ||
| mov x0, #_cygtls.start_offset // load the _cygtls.start_offset offset | ||
| add x0, x10, x0 // final address of start_offset | ||
| bl _ZN7_cygtls19call_signal_handlerEv | ||
eukarpov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // decrement incyg counter | ||
| mov w9, #-1 // specify decrement | ||
| staddl w9, [x20] // atomically decrement incyg with a lock | ||
|
|
||
| // go to the beginning to handle another signal | ||
| b 1b | ||
| 2: | ||
| ldr x0, [x18, #0x8] // return TLS address in x0 (return value) | ||
|
|
||
| // epilogue | ||
| .seh_startepilogue | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. .seh commands are not needed here
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, thanks. I believe that you know far more about this topic. Could you possibly share link to some documentation where I can learn why?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only available documentation is https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#unwind-codes in short, for a single instruction like this, not having seh_endepilogue or duplicating seh commands is not changing anything. Both options are acceptable.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From this answer I'd deduce that the fact that it has no effect is an implementation detail of GCC/binutils so it makes sense to keep it for consistency with the prologue and accross the compilers (Regardled that Cygwin is build only with GCC, one never know who will copy&paste this code elsewhere).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Coming back to this thread, it is worth mentioning again that .seh_startepilogue is not needed here and unwinding should be fully covered by prolog. Current implementation emits duplicated unwinding codes. |
||
| ldp x19, x20, [sp], #0x10 | ||
| .seh_save_regp_x x19, 16 | ||
| ldp fp, lr, [sp], #0x10 | ||
| .seh_save_fplr_x 16 | ||
| .seh_endepilogue | ||
| ret | ||
| .seh_endproc | ||
| EOF | ||
|
|
@@ -555,8 +596,43 @@ sigsetjmp: | |
| .globl setjmp | ||
| .seh_proc setjmp | ||
| setjmp: | ||
| // prologue | ||
| stp fp, lr, [sp, #-0x10]! // save FP and LR registers | ||
| .seh_endprologue | ||
| mov x0, 0 | ||
|
|
||
| // save callee-saved registers from jump buffer | ||
| stp x19, x20, [x0, #0x08] // save x19 and x20 | ||
| stp x21, x22, [x0, #0x18] // save x21 and x22 | ||
| stp x23, x24, [x0, #0x28] // save x23 and x24 | ||
| stp x25, x26, [x0, #0x38] // save x25 and x26 | ||
| stp x27, x28, [x0, #0x48] // save x27 and x28 | ||
| stp fp, lr, [x0, #0x58] // save x29 (frame pointer) and x30 (link register) | ||
| mov x1, sp // get the current stack pointer | ||
| str x1, [x0, #0x68] // save SP | ||
| mrs x1, fpcr // get floating-point control register | ||
| str x1, [x0, #0x70] // save FPCR | ||
| mrs x1, fpsr // get floating-point status register | ||
| str x1, [x0, #0x78] // save FPSR | ||
|
|
||
|
|
||
| // save floating-point registers (d8-d15) | ||
| stp d8, d9, [x0, #0x80] | ||
| stp d10, d11, [x0, #0x90] | ||
| stp d12, d13, [x0, #0xA0] | ||
| stp d14, d15, [x0, #0xB0] | ||
|
|
||
| bl stabilize_sig_stack // call stabilize_sig_stack (returns TLS in x0) | ||
|
|
||
| // store the stack pointer to ... | ||
| ldr x2, =_cygtls.stackptr | ||
| add x2, x0, x2 | ||
| ldr x3, [x2] | ||
| // TODO: Save the value somewhere. | ||
|
|
||
| mov w0, #0 // return 0 | ||
|
|
||
| // epilogue | ||
| ldp fp, lr, [sp], #0x10 // restore saved FP and LR registers | ||
| ret | ||
| .seh_endproc | ||
|
|
||
|
|
@@ -570,7 +646,56 @@ siglongjmp: | |
| .globl longjmp | ||
| .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 | ||
|
|
||
| // restore stack pointer in TLS | ||
| ldr x11, =_cygtls.stackptr | ||
| add x11, x0, x11 | ||
| str x10, [x11] | ||
|
|
||
| // we're not in cygwin anymore, clear "in cygwin" flag | ||
| ldr x11, =_cygtls.incyg | ||
| add x11, x0, x11 | ||
| mov w12, #0 | ||
| str w12, [x11] | ||
|
|
||
| // get saved return value before SP is restored | ||
| ldr x0, [sp, #0x10] | ||
|
|
||
| // 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 | ||
|
|
||
| // 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] | ||
|
|
||
| // ensure return value is non-zero (C standard requirement) | ||
| cbnz x0, 0f | ||
| mov x0, #1 | ||
| 0: | ||
| // epilogue | ||
| add sp, sp, #0x10 // FP and LR are already restored, just restore SP as it would be popped | ||
| ret | ||
| .seh_endproc | ||
| EOF | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.