[PATCH 1/3] libc/x86: add dwarf-2 cfi unwinding information to syscalls

Timo Teräs timo.teras at iki.fi
Sun Nov 20 08:50:46 UTC 2011


Fixes unwinding of stack traces across system calls. Thus debuggers can show
proper backtrace when inside a syscall.

Additionally, this fixes a race condition: if a signal happens while inside
syscall, and the signal handler aborts the thread, we would have been unable
to unwind the stack and run the proper error handler.

This patch also removes the "xchg ebx, register" trickery - it's very hard
to add proper CFI info within macroes.  It apparently never worked 100%
reliably, and the speed gain is probably insignificant on modern processors.

Signed-off-by: Timo Teräs <timo.teras at iki.fi>
---
 libc/sysdeps/linux/i386/bits/syscalls.h |   82 +++----------------------------
 1 files changed, 7 insertions(+), 75 deletions(-)

diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h
index eeafb3a..1f60a44 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -13,6 +13,7 @@
 #ifndef __ASSEMBLER__
 
 #include <errno.h>
+#include <common/sysdep.h>
 
 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
 ({ \
@@ -31,90 +32,21 @@
 
 #if 1 /* defined __PIC__ || defined __pic__ */
 
-/* This code avoids pushing/popping ebx as much as possible.
- * I think the main reason was that older GCCs had problems
- * with proper saving/restoring of ebx if "b" constraint was used,
- * which was breaking -fPIC code really badly.
- * At least gcc 4.2.x seems to not need these tricks anymore,
- * but this code is still useful because it often avoids
- * using stack for saving ebx.
- * Keeping it unconditionally enabled for now.
- */
-
-/* We need some help from the assembler to generate optimal code.
- * We define some macros here which later will be used.  */
-/* gcc>=4.6 with LTO need the same guards as IMA (a.k.a --combine) did.
- * See gcc.gnu.org/PR47577  */
-/* FIXME: drop these b* macros! */
-
-__asm__ (
-#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
-	/* Protect against asm macro redefinition (happens in __DOMULTI__ mode).
-	 * Unfortunately, it ends up visible in .o files. */
-	".ifndef _BITS_SYSCALLS_ASM\n\t"
-	".set _BITS_SYSCALLS_ASM,1\n\t"
-#endif
-	".L__X'%ebx = 1\n\t"
-	".L__X'%ecx = 2\n\t"
-	".L__X'%edx = 2\n\t"
-	".L__X'%eax = 3\n\t"
-	".L__X'%esi = 3\n\t"
-	".L__X'%edi = 3\n\t"
-	".L__X'%ebp = 3\n\t"
-	".L__X'%esp = 3\n\t"
-
-	/* Loading param #1 (ebx) is done by loading it into
-	 * another register, and then performing bpushl+bmovl,
-	 * since we must preserve ebx */
-
-	".macro bpushl name reg\n\t"
-	".if 1 - \\name\n\t"    /* if reg!=ebx... */
-	".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
-	"pushl %ebx\n\t"        /* save ebx on stack */
-	".else\n\t"
-	"xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx */
-	".endif\n\t"
-	".endif\n\t"
-	".endm\n\t"
-
-	".macro bmovl name reg\n\t"
-	".if 1 - \\name\n\t"
-	".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
-	"movl \\reg, %ebx\n\t"  /* load reg to ebx */
-	".endif\n\t"
-	".endif\n\t"
-	".endm\n\t"
-
-	".macro bpopl name reg\n\t"
-	".if 1 - \\name\n\t"
-	".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
-	"popl %ebx\n\t"         /* restore ebx from stack */
-	".else\n\t"
-	"xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */
-	".endif\n\t"
-	".endif\n\t"
-	".endm\n\t"
-
-#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
-	".endif\n\t" /* _BITS_SYSCALLS_ASM */
-#endif
-);
-
 #define LOADARGS_0
-#define LOADARGS_1  "bpushl .L__X'%k2, %k2\n\t" "bmovl .L__X'%k2, %k2\n\t"
+#define LOADARGS_1  "push %%ebx\n\t" CFI_ADJUST_CFA_OFFSET(4) "\n\t" CFI_REL_OFFSET(ebx, 0) "\n\t" "movl %k2, %%ebx\n\t"
 #define LOADARGS_2  LOADARGS_1
 #define LOADARGS_3  LOADARGS_1
 #define LOADARGS_4  LOADARGS_1
 #define LOADARGS_5  LOADARGS_1
-#define LOADARGS_6  LOADARGS_1 "push %%ebp\n\t" "movl %7, %%ebp\n\t"
+#define LOADARGS_6  LOADARGS_1 "push %%ebp\n\t" CFI_ADJUST_CFA_OFFSET(4) "\n\t" CFI_REL_OFFSET(ebp, 0) "\n\t" "movl %7, %%ebp\n\t"
 
 #define RESTOREARGS_0
-#define RESTOREARGS_1  "bpopl .L__X'%k2, %k2\n\t"
+#define RESTOREARGS_1  "pop %%ebx\n\t" CFI_ADJUST_CFA_OFFSET(-4) "\n\t" CFI_RESTORE(ebx) "\n\t" RESTOREARGS_0
 #define RESTOREARGS_2  RESTOREARGS_1
 #define RESTOREARGS_3  RESTOREARGS_1
 #define RESTOREARGS_4  RESTOREARGS_1
 #define RESTOREARGS_5  RESTOREARGS_1
-#define RESTOREARGS_6  "pop %%ebp\n\t" RESTOREARGS_1
+#define RESTOREARGS_6  "pop %%ebp\n\t" CFI_ADJUST_CFA_OFFSET(-4) "\n\t" CFI_RESTORE(ebp) "\n\t" RESTOREARGS_1
 
 #define ASMFMT_0()
 /* "acdSD" constraint would work too, but "SD" would use esi/edi and cause
@@ -162,7 +94,7 @@ __asm__ (
 #define LOADARGS_3
 #define LOADARGS_4
 #define LOADARGS_5
-#define LOADARGS_6  "push %%ebp\n\t" "movl %7, %%ebp\n\t"
+#define LOADARGS_6  "push %%ebp\n\t" CFI_ADJUST_CFA_OFFSET(4) "\n\t" CFI_REL_OFFSET(ebp, 0) "\n\t" "movl %7, %%ebp\n\t"
 
 #define RESTOREARGS_0
 #define RESTOREARGS_1
@@ -170,7 +102,7 @@ __asm__ (
 #define RESTOREARGS_3
 #define RESTOREARGS_4
 #define RESTOREARGS_5
-#define RESTOREARGS_6  "pop %%ebp\n\t"
+#define RESTOREARGS_6  "pop %%ebp\n\t" CFI_ADJUST_CFA_OFFSET(-4) "\n\t" CFI_RESTORE(ebp) "\n\t"
 
 #define ASMFMT_0()
 #define ASMFMT_1(arg1) \
-- 
1.7.7.1



More information about the uClibc mailing list