Module Name:    src
Committed By:   thorpej
Date:           Sun Nov 21 21:31:25 UTC 2021

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

Log Message:
Decorate the powerpc 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.5 -r1.6 src/lib/libc/arch/powerpc/genassym.cf
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/arch/powerpc/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/powerpc/genassym.cf
diff -u src/lib/libc/arch/powerpc/genassym.cf:1.5 src/lib/libc/arch/powerpc/genassym.cf:1.6
--- src/lib/libc/arch/powerpc/genassym.cf:1.5	Wed Feb 28 21:00:02 2018
+++ src/lib/libc/arch/powerpc/genassym.cf	Sun Nov 21 21:31:24 2021
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.5 2018/02/28 21:00:02 uwe Exp $
+#	$NetBSD: genassym.cf,v 1.6 2021/11/21 21:31:24 thorpej Exp $
 
 #
 # Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -42,11 +42,50 @@ define CALLFRAME_LR	offsetof(struct call
 define CALLFRAME_R30	offsetof(struct callframe, cf_r30)
 define CALLFRAME_R31	offsetof(struct callframe, cf_r31)
 
+define UC_GREGS		offsetof(ucontext_t, uc_mcontext.__gregs[0])
 define UC_GREGS_R1	offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R1])
 define UC_GREGS_R3	offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R3])
 define UC_GREGS_R30	offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R30])
 define UC_GREGS_PC	offsetof(ucontext_t, uc_mcontext.__gregs[_REG_PC])
 
+define _REG_R0		_REG_R0
+define _REG_R1		_REG_R1
+define _REG_R2		_REG_R2
+define _REG_R3		_REG_R3
+define _REG_R4		_REG_R4
+define _REG_R5		_REG_R5
+define _REG_R6		_REG_R6
+define _REG_R7		_REG_R7
+define _REG_R8		_REG_R8
+define _REG_R9		_REG_R9
+define _REG_R10		_REG_R10
+define _REG_R11		_REG_R11
+define _REG_R12		_REG_R12
+define _REG_R13		_REG_R13
+define _REG_R14		_REG_R14
+define _REG_R15		_REG_R15
+define _REG_R16		_REG_R16
+define _REG_R17		_REG_R17
+define _REG_R18		_REG_R18
+define _REG_R19		_REG_R19
+define _REG_R20		_REG_R20
+define _REG_R21		_REG_R21
+define _REG_R22		_REG_R22
+define _REG_R23		_REG_R23
+define _REG_R24		_REG_R24
+define _REG_R25		_REG_R25
+define _REG_R26		_REG_R26
+define _REG_R27		_REG_R27
+define _REG_R28		_REG_R28
+define _REG_R29		_REG_R29
+define _REG_R30		_REG_R30
+define _REG_R31		_REG_R31
+define _REG_CR		_REG_CR
+define _REG_LR		_REG_LR
+define _REG_PC		_REG_PC
+define _REG_CTR		_REG_CTR
+define _REG_XER		_REG_XER
+
 define SIG_BLOCK	SIG_BLOCK
 define SIG_SETMASK	SIG_SETMASK
 

Index: src/lib/libc/arch/powerpc/sys/__sigtramp2.S
diff -u src/lib/libc/arch/powerpc/sys/__sigtramp2.S:1.3 src/lib/libc/arch/powerpc/sys/__sigtramp2.S:1.4
--- src/lib/libc/arch/powerpc/sys/__sigtramp2.S:1.3	Sat Jan 15 07:31:12 2011
+++ src/lib/libc/arch/powerpc/sys/__sigtramp2.S	Sun Nov 21 21:31:24 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: __sigtramp2.S,v 1.3 2011/01/15 07:31:12 matt Exp $	*/
+/*	$NetBSD: __sigtramp2.S,v 1.4 2021/11/21 21:31:24 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,9 +30,10 @@
  */
 
 #include "SYS.h"
+#include "assym.h"
 
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: __sigtramp2.S,v 1.3 2011/01/15 07:31:12 matt Exp $")
+__RCSID("$NetBSD: __sigtramp2.S,v 1.4 2021/11/21 21:31:24 thorpej Exp $")
 #endif /* LIBC_SCCS && !lint */
 
 /*
@@ -45,9 +46,86 @@ __RCSID("$NetBSD: __sigtramp2.S,v 1.3 20
  *	srr0	address of handler
  *	lr	address of this trampoline
  *
+ * We use r30 as the CFA base register since it's been conveniently set up
+ * for us that way.  The DWARF register numbers used in the .eh_frame are:
+ *
+ *   0 - 31	GPRs
+ *  32 - 63	FPRs
+ *  65		LR
+ *  66		CTR
+ *  68-75	CRs
+ *  76		XER
+ *  77 - 108	AltiVec regs
+ *  99		signal trampoline return address
+ * 109		VRSAVE
+ * 110		VCSR
+ *
+ * N.B. Only one CR slot is used (CR2) in the SVR4 ABI.
  */
+
+#define	DWARF_LR_REG			65
+#define	DWARF_CTR_REG			66
+#define	DWARF_CR2_REG			70
+#define	DWARF_XER_REG			76
+#define	DWARF_SIGRETURN_REG		99
+
+#define	CFI_OFFSET_DWARF_REG(d, r)	.cfi_offset d, r * 4
+#define	CFI_OFFSET(r)			CFI_OFFSET_DWARF_REG(r, r)
+
+	.text
+	.cfi_startproc simple
+	.cfi_signal_frame
+	.cfi_def_cfa _REG_R30, UC_GREGS
+	CFI_OFFSET(_REG_R0)
+	CFI_OFFSET(_REG_R1)
+	CFI_OFFSET(_REG_R2)
+	CFI_OFFSET(_REG_R3)
+	CFI_OFFSET(_REG_R4)
+	CFI_OFFSET(_REG_R5)
+	CFI_OFFSET(_REG_R6)
+	CFI_OFFSET(_REG_R7)
+	CFI_OFFSET(_REG_R8)
+	CFI_OFFSET(_REG_R9)
+	CFI_OFFSET(_REG_R10)
+	CFI_OFFSET(_REG_R11)
+	CFI_OFFSET(_REG_R12)
+	CFI_OFFSET(_REG_R13)
+	CFI_OFFSET(_REG_R14)
+	CFI_OFFSET(_REG_R15)
+	CFI_OFFSET(_REG_R16)
+	CFI_OFFSET(_REG_R17)
+	CFI_OFFSET(_REG_R18)
+	CFI_OFFSET(_REG_R19)
+	CFI_OFFSET(_REG_R20)
+	CFI_OFFSET(_REG_R21)
+	CFI_OFFSET(_REG_R22)
+	CFI_OFFSET(_REG_R23)
+	CFI_OFFSET(_REG_R24)
+	CFI_OFFSET(_REG_R25)
+	CFI_OFFSET(_REG_R26)
+	CFI_OFFSET(_REG_R27)
+	CFI_OFFSET(_REG_R28)
+	CFI_OFFSET(_REG_R29)
+	CFI_OFFSET(_REG_R30)
+	CFI_OFFSET(_REG_R31)
+	CFI_OFFSET_DWARF_REG(DWARF_CR2_REG, _REG_CR)
+	CFI_OFFSET_DWARF_REG(DWARF_LR_REG, _REG_LR)
+	CFI_OFFSET_DWARF_REG(DWARF_CTR_REG, _REG_CTR)
+	CFI_OFFSET_DWARF_REG(DWARF_XER_REG, _REG_XER)
+	.cfi_return_column DWARF_SIGRETURN_REG
+	CFI_OFFSET_DWARF_REG(DWARF_SIGRETURN_REG, _REG_PC)
+
+/*      
+ * 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
+
 ENTRY_NOPROFILE(__sigtramp_siginfo_2)
 	mr	%r3,%r30		/* restore ucontext pointer */
 	_DOSYSCALL(setcontext)		/* restore machine state */
 	_DOSYSCALL(exit)		/* or exit with errno if failed */
+	.cfi_endproc
 END(__sigtramp_siginfo_2)

Reply via email to