Module Name:    src
Committed By:   thorpej
Date:           Thu Nov 18 04:33:20 UTC 2021

Modified Files:
        src/lib/libc/arch/mips: genassym.cf
        src/lib/libc/arch/mips/sys: __sigtramp2.S

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


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/lib/libc/arch/mips/genassym.cf
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/arch/mips/sys/__sigtramp2.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/arch/mips/genassym.cf
diff -u src/lib/libc/arch/mips/genassym.cf:1.4 src/lib/libc/arch/mips/genassym.cf:1.5
--- src/lib/libc/arch/mips/genassym.cf:1.4	Thu Oct 15 05:27:53 2020
+++ src/lib/libc/arch/mips/genassym.cf	Thu Nov 18 04:33:20 2021
@@ -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_V0	offsetof(ucontext_t,
 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])

Index: src/lib/libc/arch/mips/sys/__sigtramp2.S
diff -u src/lib/libc/arch/mips/sys/__sigtramp2.S:1.3 src/lib/libc/arch/mips/sys/__sigtramp2.S:1.4
--- src/lib/libc/arch/mips/sys/__sigtramp2.S:1.3	Mon Dec 14 01:07:42 2009
+++ src/lib/libc/arch/mips/sys/__sigtramp2.S	Thu Nov 18 04:33:20 2021
@@ -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)

Reply via email to