[PATCH] x86_64: add CFI annotations to swapcontext (bug 34575)

Andreas Schwab <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
The annotations allow the unwinder to always find the return address in
one of the contexts.  Also mark __start_context as outermost frame, which
is used by makecontext as the return address for the context.
---
 .../unix/sysv/linux/x86_64/__start_context.S  |  2 ++
 sysdeps/unix/sysv/linux/x86_64/swapcontext.S  | 20 +++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
index 2eb5e16d02..5943a84f7c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/__start_context.S
+++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
@@ -75,6 +75,8 @@ END(__push___start_context)
 
 
 ENTRY(__start_context)
+	/* Mark as outermost frame.  */
+	cfi_undefined (rip)
 	/* This removes the parameters passed to the function given to
 	   'makecontext' from the stack.  RBX contains the address
 	   on the stack pointer for the next context.  */
diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
index 4c9c08a828..258c75562c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
@@ -54,6 +54,14 @@ ENTRY(__swapcontext)
 	movq	%rcx, oRIP(%rdi)
 	leaq	8(%rsp), %rcx		/* Exclude the return address.  */
 	movq	%rcx, oRSP(%rdi)
+	cfi_def_cfa (%rdi, oRIP)
+	cfi_offset (%rbx, oRBX-oRIP)
+	cfi_offset (%rbp, oRBP-oRIP)
+	cfi_offset (%r12, oR12-oRIP)
+	cfi_offset (%r13, oR13-oRIP)
+	cfi_offset (%r14, oR14-oRIP)
+	cfi_offset (%r15, oR15-oRIP)
+	cfi_offset (%rip, 0)
 
 	/* We have separate floating-point register content memory on the
 	   stack.  We use the __fpregs_mem block in the context.  Set the
@@ -68,6 +76,7 @@ ENTRY(__swapcontext)
 	/* The syscall destroys some registers, save them.  */
 	movq	%rsi, %r12
 	movq	%rdi, %r9
+	cfi_def_cfa (%r9, oRIP)
 
 	/* Save the current signal mask and install the new one with
 	   rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8).  */
@@ -84,6 +93,7 @@ ENTRY(__swapcontext)
 	   but leaving RDI and RSI available for use later can avoid
 	   shuffling values.  */
 	movq	%r12, %rdx
+	cfi_def_cfa (%rdx, oRIP)
 
 	/* Restore the floating-point context.  Not the registers, only the
 	   rest.  */
@@ -99,6 +109,12 @@ ENTRY(__swapcontext)
 	movq	oR13(%rdx), %r13
 	movq	oR14(%rdx), %r14
 	movq	oR15(%rdx), %r15
+	cfi_restore (%rbx)
+	cfi_restore (%rbp)
+	cfi_restore (%r12)
+	cfi_restore (%r13)
+	cfi_restore (%r14)
+	cfi_restore (%r15)
 
 #if SHSTK_ENABLED
 	/* Check if shadow stack is enabled.  */
@@ -191,6 +207,7 @@ L(skip_unwind_shadow_stack):
 
 	/* Get the return address set with getcontext.  */
 	movq	oRIP(%rdx), %r10
+	cfi_register (%rip, %r10)
 
 	/* Setup finally %rdx.  */
 	movq	oRDX(%rdx), %rdx
@@ -210,6 +227,7 @@ L(skip_unwind_shadow_stack):
 L(jmp):
 	/* Jump to the new context directly.  */
 	jmp	*%r10
+	cfi_offset (%rip, 0)
 
 L(no_shstk):
 #endif
@@ -217,6 +235,8 @@ L(no_shstk):
 	getcontext.  Therefore push the address on the stack.  */
 	movq	oRIP(%rdx), %rcx
 	pushq	%rcx
+	cfi_def_cfa (%rsp, 8)
+	cfi_offset (%rip, -8)
 
 	/* Setup registers used for passing args.  */
 	movq	oRDI(%rdx), %rdi
-- 
2.55.0


-- 
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.