From: Flavio Cruz <flaviocruz@gmail.com>
To: bug-hurd@gnu.org, gcc-patches@gcc.gnu.org
Cc: thomas@codesourcery.com
Subject: [PATCH gcc] Hurd x86_64: add unwind support for signal trampoline code
Date: Wed, 28 Feb 2024 22:59:09 -0500 [thread overview]
Message-ID: <ZeABDXA82kA3UvEJ@mars.tail36e24.ts.net> (raw)
Tested with some simple toy examples where an exception is thrown in the
signal handler.
libgcc/ChangeLog:
* config/i386/gnu-unwind.h: Support unwinding x86_64 signal frames.
Signed-off-by: Flavio Cruz <flaviocruz@gmail.com>
---
libgcc/config/i386/gnu-unwind.h | 97 ++++++++++++++++++++++++++++++++-
1 file changed, 94 insertions(+), 3 deletions(-)
diff --git a/libgcc/config/i386/gnu-unwind.h b/libgcc/config/i386/gnu-unwind.h
index 0751b5593d4..02b060ab4a5 100644
--- a/libgcc/config/i386/gnu-unwind.h
+++ b/libgcc/config/i386/gnu-unwind.h
@@ -32,9 +32,100 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifdef __x86_64__
-/*
- * TODO: support for 64 bits needs to be implemented.
- */
+#define MD_FALLBACK_FRAME_STATE_FOR x86_gnu_fallback_frame_state
+
+static _Unwind_Reason_Code
+x86_gnu_fallback_frame_state
+(struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+ static const unsigned char gnu_sigtramp_code[] =
+ {
+ /* rpc_wait_trampoline: */
+ 0x48, 0xc7, 0xc0, 0xe7, 0xff, 0xff, 0xff, /* mov $-25,%rax */
+ 0x0f, 0x05, /* syscall */
+ 0x49, 0x89, 0x04, 0x24, /* mov %rax,(%r12) */
+ 0x48, 0x89, 0xdc, /* mov %rbx,%rsp */
+
+ /* trampoline: */
+ 0x5f, /* pop %rdi */
+ 0x5e, /* pop %rsi */
+ 0x5a, /* pop %rdx */
+ 0x48, 0x83, 0xc4, 0x08, /* add $0x8,%rsp */
+ 0x41, 0xff, 0xd5, /* call *%r13 */
+
+ /* RA HERE */
+ 0x48, 0x8b, 0x7c, 0x24, 0x10, /* mov 0x10(%rsp),%rdi */
+ 0xc3, /* ret */
+
+ /* firewall: */
+ 0xf4, /* hlt */
+ };
+
+ const size_t gnu_sigtramp_len = sizeof gnu_sigtramp_code;
+ const size_t gnu_sigtramp_tail = 7; /* length of tail after RA */
+
+ struct stack_contents {
+ void *sigreturn_addr;
+ void *sigreturn_returns_here;
+ struct sigcontext *return_scp;
+ } *stack_contents;
+ struct sigcontext *scp;
+ unsigned long usp;
+
+ unsigned char *adjusted_pc = (unsigned char*)(context->ra) +
+ gnu_sigtramp_tail - gnu_sigtramp_len;
+ if (memcmp (adjusted_pc, gnu_sigtramp_code, gnu_sigtramp_len))
+ return _URC_END_OF_STACK;
+
+ stack_contents = context->cfa;
+
+ scp = stack_contents->return_scp;
+ usp = scp->sc_ursp;
+
+ fs->regs.reg[0].loc.offset = (unsigned long)&scp->sc_rax - usp;
+ fs->regs.reg[1].loc.offset = (unsigned long)&scp->sc_rdx - usp;
+ fs->regs.reg[2].loc.offset = (unsigned long)&scp->sc_rcx - usp;
+ fs->regs.reg[3].loc.offset = (unsigned long)&scp->sc_rbx - usp;
+ fs->regs.reg[4].loc.offset = (unsigned long)&scp->sc_rsi - usp;
+ fs->regs.reg[5].loc.offset = (unsigned long)&scp->sc_rdi - usp;
+ fs->regs.reg[6].loc.offset = (unsigned long)&scp->sc_rbp - usp;
+ fs->regs.reg[8].loc.offset = (unsigned long)&scp->sc_r8 - usp;
+ fs->regs.reg[9].loc.offset = (unsigned long)&scp->sc_r9 - usp;
+ fs->regs.reg[10].loc.offset = (unsigned long)&scp->sc_r10 - usp;
+ fs->regs.reg[11].loc.offset = (unsigned long)&scp->sc_r11 - usp;
+ fs->regs.reg[12].loc.offset = (unsigned long)&scp->sc_r12 - usp;
+ fs->regs.reg[13].loc.offset = (unsigned long)&scp->sc_r13 - usp;
+ fs->regs.reg[14].loc.offset = (unsigned long)&scp->sc_r14 - usp;
+ fs->regs.reg[15].loc.offset = (unsigned long)&scp->sc_r15 - usp;
+ fs->regs.reg[16].loc.offset = (unsigned long)&scp->sc_rip - usp;
+
+ /* Register 7 is rsp */
+ fs->regs.cfa_how = CFA_REG_OFFSET;
+ fs->regs.cfa_reg = 7;
+ fs->regs.cfa_offset = usp - (unsigned long) context->cfa;
+
+ fs->regs.how[0] = REG_SAVED_OFFSET;
+ fs->regs.how[1] = REG_SAVED_OFFSET;
+ fs->regs.how[2] = REG_SAVED_OFFSET;
+ fs->regs.how[3] = REG_SAVED_OFFSET;
+ fs->regs.how[4] = REG_SAVED_OFFSET;
+ fs->regs.how[5] = REG_SAVED_OFFSET;
+ fs->regs.how[6] = REG_SAVED_OFFSET;
+ fs->regs.how[8] = REG_SAVED_OFFSET;
+ fs->regs.how[9] = REG_SAVED_OFFSET;
+ fs->regs.how[10] = REG_SAVED_OFFSET;
+ fs->regs.how[11] = REG_SAVED_OFFSET;
+ fs->regs.how[12] = REG_SAVED_OFFSET;
+ fs->regs.how[13] = REG_SAVED_OFFSET;
+ fs->regs.how[14] = REG_SAVED_OFFSET;
+ fs->regs.how[15] = REG_SAVED_OFFSET;
+ fs->regs.how[16] = REG_SAVED_OFFSET;
+
+ fs->retaddr_column = 16;
+ fs->signal_frame = 1;
+
+ return _URC_NO_REASON;
+}
#else /* ifdef __x86_64__ */
--
2.43.0
next reply other threads:[~2024-02-29 3:59 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-29 3:59 Flavio Cruz [this message]
2024-03-01 1:33 ` Samuel Thibault
2024-03-20 19:36 ` Thomas Schwinge
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZeABDXA82kA3UvEJ@mars.tail36e24.ts.net \
--to=flaviocruz@gmail.com \
--cc=bug-hurd@gnu.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=thomas@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).