Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/arch/mips Decorate the MIPS signal trampoline with ...



details:   https://anonhg.NetBSD.org/src/rev/f121aa60d2b0
branches:  trunk
changeset: 1026308:f121aa60d2b0
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Thu Nov 18 04:33:20 2021 +0000

description:
Decorate the MIPS signal trampoline with the appropriate .cfi
directives to allow exception unwind / backtrace across a signal
handler.

diffstat:

 lib/libc/arch/mips/genassym.cf       |  39 ++++++++++++++++++-
 lib/libc/arch/mips/sys/__sigtramp2.S |  76 ++++++++++++++++++++++++++++++++++-
 2 files changed, 110 insertions(+), 5 deletions(-)

diffs (157 lines):

diff -r 69de4f2f1b64 -r f121aa60d2b0 lib/libc/arch/mips/genassym.cf
--- a/lib/libc/arch/mips/genassym.cf    Thu Nov 18 04:20:11 2021 +0000
+++ b/lib/libc/arch/mips/genassym.cf    Thu Nov 18 04:33:20 2021 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: genassym.cf,v 1.4 2020/10/15 05:27:53 skrll Exp $
+#      $NetBSD: genassym.cf,v 1.5 2021/11/18 04:33:20 thorpej Exp $
 
 #
 # Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -40,9 +40,46 @@
 define _UC_GREGS_GP    offsetof(ucontext_t, uc_mcontext.__gregs[_REG_GP])
 define _UC_GREGS_SP    offsetof(ucontext_t, uc_mcontext.__gregs[_REG_SP])
 define _UC_GREGS_EPC   offsetof(ucontext_t, uc_mcontext.__gregs[_REG_EPC])
+define _UC_GREGS       offsetof(ucontext_t, uc_mcontext.__gregs[0])
 define _UC_LINK                offsetof(ucontext_t, uc_link)
 define UCONTEXT_SIZE   sizeof(ucontext_t)
 
+define _REG_R0         _REG_R0
+define _REG_AT         _REG_AT
+define _REG_V0         _REG_V0
+define _REG_V1         _REG_V1
+define _REG_A0         _REG_A0
+define _REG_A1         _REG_A1
+define _REG_A2         _REG_A2
+define _REG_A3         _REG_A3
+define _REG_T0         _REG_T0
+define _REG_T1         _REG_T1
+define _REG_T2         _REG_T2
+define _REG_T3         _REG_T3
+define _REG_T4         _REG_T4
+define _REG_T5         _REG_T5
+define _REG_T6         _REG_T6
+define _REG_T7         _REG_T7
+define _REG_S0         _REG_S0
+define _REG_S1         _REG_S1
+define _REG_S2         _REG_S2
+define _REG_S3         _REG_S3
+define _REG_S4         _REG_S4
+define _REG_S5         _REG_S5
+define _REG_S6         _REG_S6
+define _REG_S7         _REG_S7
+define _REG_T8         _REG_T8
+define _REG_T9         _REG_T9
+define _REG_K0         _REG_K0
+define _REG_K1         _REG_K1
+define _REG_GP         _REG_GP
+define _REG_SP         _REG_SP
+define _REG_S8         _REG_S8
+define _REG_RA         _REG_RA
+define _REG_EPC                _REG_EPC
+define _REG_MDLO       _REG_MDLO
+define _REG_MDHI       _REG_MDHI
+
 define _SC_REGS                offsetof(struct sigcontext, sc_regs[0])
 define _SC_REGS_V0     offsetof(struct sigcontext, sc_regs[_R_V0])
 define _SC_REGS_S0     offsetof(struct sigcontext, sc_regs[_R_S0])
diff -r 69de4f2f1b64 -r f121aa60d2b0 lib/libc/arch/mips/sys/__sigtramp2.S
--- a/lib/libc/arch/mips/sys/__sigtramp2.S      Thu Nov 18 04:20:11 2021 +0000
+++ b/lib/libc/arch/mips/sys/__sigtramp2.S      Thu Nov 18 04:33:20 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: __sigtramp2.S,v 1.3 2009/12/14 01:07:42 matt Exp $     */
+/*     $NetBSD: __sigtramp2.S,v 1.4 2021/11/18 04:33:20 thorpej Exp $  */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #include "assym.h"
 
 #if defined(SYSLIBC_SCCS) && !defined(lint)
-       RCSID("$NetBSD: __sigtramp2.S,v 1.3 2009/12/14 01:07:42 matt Exp $")
+       RCSID("$NetBSD: __sigtramp2.S,v 1.4 2021/11/18 04:33:20 thorpej Exp $")
 #endif /* SYSLIBC_SCCS and not lint */
 
 
@@ -43,12 +43,80 @@
  *
  * On entry, stack looks like:
  *
- *     sp                      ->      siginfo_t structure
- *     sp + SIGINFO_SIZE       ->      ucontext_t structure
+ *             ucontext structure      sp + sizeof(siginfo_t)
+ *     sp->    siginfo structure
+ *
+ * The DWARF register numbers for the general purpose registers are the
+ * same as the architected register numbers.  For MIPS, there is a DWARF
+ * psuedo-register for signal handler return addresses, as well as for the
+ * MDLO and MDHI registers.
  */
+
+#define        DWARF_MDHI_REG                  64
+#define        DWARF_MDLO_REG                  65
+
+#if defined(__LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__)
+#define        DWARF_SIGRETURN_REG             __LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__
+#else
+#define        DWARF_SIGRETURN_REG             66
+#endif
+
+#define        CFI_OFFSET_DWARF_REG(d, r)      .cfi_offset d, r * SZREG
+#define        CFI_OFFSET(r)                   CFI_OFFSET_DWARF_REG(r, r)
+
+       .text
+       .cfi_startproc
+       .cfi_signal_frame
+       .cfi_def_cfa _REG_SP, SIGINFO_SIZE + _UC_GREGS
+       CFI_OFFSET(_REG_R0)
+       CFI_OFFSET(_REG_AT)
+       CFI_OFFSET(_REG_V0)
+       CFI_OFFSET(_REG_V1)
+       CFI_OFFSET(_REG_A0)
+       CFI_OFFSET(_REG_A1)
+       CFI_OFFSET(_REG_A2)
+       CFI_OFFSET(_REG_A3)
+       CFI_OFFSET(_REG_T0)
+       CFI_OFFSET(_REG_T1)
+       CFI_OFFSET(_REG_T2)
+       CFI_OFFSET(_REG_T3)
+       CFI_OFFSET(_REG_T4)
+       CFI_OFFSET(_REG_T5)
+       CFI_OFFSET(_REG_T6)
+       CFI_OFFSET(_REG_T7)
+       CFI_OFFSET(_REG_S0)
+       CFI_OFFSET(_REG_S1)
+       CFI_OFFSET(_REG_S2)
+       CFI_OFFSET(_REG_S3)
+       CFI_OFFSET(_REG_S4)
+       CFI_OFFSET(_REG_S5)
+       CFI_OFFSET(_REG_S6)
+       CFI_OFFSET(_REG_S7)
+       CFI_OFFSET(_REG_T8)
+       CFI_OFFSET(_REG_T9)
+       CFI_OFFSET(_REG_K0)
+       CFI_OFFSET(_REG_K1)
+       CFI_OFFSET(_REG_GP)
+       CFI_OFFSET(_REG_SP)
+       CFI_OFFSET(_REG_S8)
+       CFI_OFFSET(_REG_RA)
+       CFI_OFFSET_DWARF_REG(DWARF_MDHI_REG, _REG_MDHI)
+       CFI_OFFSET_DWARF_REG(DWARF_MDLO_REG, _REG_MDLO)
+       .cfi_return_column DWARF_SIGRETURN_REG
+       CFI_OFFSET_DWARF_REG(DWARF_SIGRETURN_REG, _REG_EPC)
+
+/*
+ * The unwind entry includes one instruction slot prior to the trampoline
+ * because the unwinder will look up to (return PC - 1 insn) while unwinding.
+ * Normally this would be the jump / branch, but since there isn't one in
+ * this case, we place an explicit nop there instead.
+ */
+       nop
+
 LEAF_NOPROFILE(__sigtramp_siginfo_2)
        PTR_ADDU        a0, sp, SIGINFO_SIZE    /* address of ucontext */
        SYSTRAP(setcontext)                     /* and do setcontext */
        move            a0, v0                  /* exit with errno */
        SYSTRAP(exit)                           /* if sigreturn fails */
+       .cfi_endproc
 END(__sigtramp_siginfo_2)



Home | Main Index | Thread Index | Old Index