diff options
author | Timo Teräs <timo.teras@iki.fi> | 2011-11-10 09:36:44 +0200 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2011-12-23 15:49:02 +0100 |
commit | 9d28002b230eb01a5db7aecab263d38bf0d6d6c7 (patch) | |
tree | f17505b5757bfe08cc8e55f31731f36b6647cdd1 /libc/sysdeps/linux/i386/clone.S | |
parent | eb5d129b641c644d82089c3ded3d36288c66123c (diff) | |
download | uClibc-alpine-9d28002b230eb01a5db7aecab263d38bf0d6d6c7.tar.bz2 uClibc-alpine-9d28002b230eb01a5db7aecab263d38bf0d6d6c7.tar.xz |
libc/x86: fix stack unwinding and backtrace information
When compiled without framepointer, the DWARF-2 CFI data is required
for proper stack unwinding.
This patch adds the CFI information to:
* syscalls (so we get proper backtrace even for release builds)
the ebx hack was removed as it would complicate the CFI generation
* new thread stub function (so the backtrace is clean for user
created threads)
Also pads the signal return trampolines separate from other functions.
If CFI info was found for signal return code (which seems to happen if
it's located right next a valid function), it will not be recognized
as signal trampoline (gcc unwinder and gdb check first CFI info, and
only if it does not exists it compares the exact opcode sequence to
see if we are at signal return code block). This fixes a real crash
if thread is cancelled and the cancellation handler fails to detect the
signal return frame.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Diffstat (limited to 'libc/sysdeps/linux/i386/clone.S')
-rw-r--r-- | libc/sysdeps/linux/i386/clone.S | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S index a7de3fe27..cf6cd35ec 100644 --- a/libc/sysdeps/linux/i386/clone.S +++ b/libc/sysdeps/linux/i386/clone.S @@ -25,6 +25,7 @@ #define _ERRNO_H 1 #include <bits/errno.h> +#include <sysdep.h> #include <sys/syscall.h> /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, @@ -45,6 +46,7 @@ .global clone .type clone,%function clone: + cfi_startproc; /* Sanity check arguments. */ movl $-EINVAL,%eax @@ -86,17 +88,28 @@ clone: /* Do the system call */ pushl %ebx + cfi_adjust_cfa_offset (4) pushl %esi + cfi_adjust_cfa_offset (4) pushl %edi + cfi_adjust_cfa_offset (4) + movl TLS+12(%esp),%esi + cfi_rel_offset (esi, 4) movl PTID+12(%esp),%edx movl FLAGS+12(%esp),%ebx + cfi_rel_offset (ebx, 8) movl CTID+12(%esp),%edi + cfi_rel_offset (edi, 0) movl $__NR_clone,%eax #ifdef RESET_PID /* Remember the flag value. */ movl %ebx, (%ecx) #endif + /* End FDE now, because in the child the unwind info will be + wrong. */ + cfi_endproc + int $0x80 popl %edi popl %esi @@ -108,6 +121,9 @@ clone: ret .Lthread_start: + cfi_startproc; + /* Clearing frame pointer is insufficient, use CFI. */ + cfi_undefined (eip); /* Note: %esi is zero. */ movl %esi,%ebp /* terminate the stack frame */ call *%ebx @@ -120,6 +136,7 @@ clone: movl %eax, %ebx movl $__NR_exit, %eax int $0x80 + cfi_endproc; /* Need to indirect jump to syscall error * or we end up with TEXTREL's |