From 98616434d7117b42cf1b7c650104b937e084db52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 10 Nov 2011 10:24:14 +0200 Subject: main/libc0.9.32: fix stack unwinding and backtraces on x86 --- ...x-stack-unwinding-and-backtrace-informati.patch | 190 +++++++++++++++++++++ main/libc0.9.32/APKBUILD | 4 +- 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 main/libc0.9.32/0001-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch diff --git a/main/libc0.9.32/0001-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch b/main/libc0.9.32/0001-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch new file mode 100644 index 000000000..87a175852 --- /dev/null +++ b/main/libc0.9.32/0001-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch @@ -0,0 +1,190 @@ +From 80db5b343bd44806881d400a8627cb526ffccee7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Thu, 10 Nov 2011 09:36:44 +0200 +Subject: [PATCH] libc/x86: fix stack unwinding and backtrace information +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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) + * 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 +--- + libc/sysdeps/linux/i386/bits/syscalls.h | 13 +++++++++---- + libc/sysdeps/linux/i386/clone.S | 17 +++++++++++++++++ + libc/sysdeps/linux/i386/sigaction.c | 4 ++++ + 3 files changed, 30 insertions(+), 4 deletions(-) + +diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h +index eeafb3a..47d0b4c 100644 +--- a/libc/sysdeps/linux/i386/bits/syscalls.h ++++ b/libc/sysdeps/linux/i386/bits/syscalls.h +@@ -13,6 +13,7 @@ + #ifndef __ASSEMBLER__ + + #include ++#include + + #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ +@@ -71,6 +72,8 @@ __asm__ ( + ".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 */ ++ CFI_ADJUST_CFA_OFFSET(4) "\n\t" ++ CFI_REL_OFFSET(ebx, 0) "\n\t" + ".else\n\t" + "xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx */ + ".endif\n\t" +@@ -89,6 +92,8 @@ __asm__ ( + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "popl %ebx\n\t" /* restore ebx from stack */ ++ CFI_ADJUST_CFA_OFFSET(-4) "\n\t" ++ CFI_RESTORE(ebx) "\n\t" + ".else\n\t" + "xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */ + ".endif\n\t" +@@ -106,7 +111,7 @@ __asm__ ( + #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" +@@ -114,7 +119,7 @@ __asm__ ( + #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 +167,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 +175,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) \ +diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S +index a7de3fe..cf6cd35 100644 +--- a/libc/sysdeps/linux/i386/clone.S ++++ b/libc/sysdeps/linux/i386/clone.S +@@ -25,6 +25,7 @@ + + #define _ERRNO_H 1 + #include ++#include + #include + + /* 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 +diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c +index de0c75d..f9af3f7 100644 +--- a/libc/sysdeps/linux/i386/sigaction.c ++++ b/libc/sysdeps/linux/i386/sigaction.c +@@ -112,6 +112,9 @@ libc_hidden_weak(sigaction) + #define RESTORE2(name, syscall) \ + __asm__ ( \ + ".text\n" \ ++ ".align 8\n" \ ++ " nop\n" \ ++ ".align 16\n" \ + "__" #name ":\n" \ + " movl $" #syscall ", %eax\n" \ + " int $0x80\n" \ +@@ -128,6 +131,7 @@ RESTORE(restore_rt, __NR_rt_sigreturn) + # define RESTORE2(name, syscall) \ + __asm__ ( \ + ".text\n" \ ++ ".align 8\n" \ + "__" #name ":\n" \ + " popl %eax\n" \ + " movl $" #syscall ", %eax\n" \ +-- +1.7.7 + diff --git a/main/libc0.9.32/APKBUILD b/main/libc0.9.32/APKBUILD index eded79b32..54d69866c 100644 --- a/main/libc0.9.32/APKBUILD +++ b/main/libc0.9.32/APKBUILD @@ -4,7 +4,7 @@ pkgname=libc$_abiver _gitver= pkgver=0.9.32 _ver=${pkgver/_/-} -pkgrel=6 +pkgrel=7 pkgdesc="C library for developing embedded Linux systems" url=http://uclibc.org license="LGPL-2" @@ -32,6 +32,7 @@ source="http://uclibc.org/downloads/uClibc-${_ver}.tar.bz2 0001-malloc-standard-synchronize-on-fork.patch 0001-time-fix-parsing-of-tzdata-files-where-off_t-is-64-b.patch 0001-getaddrinfo-allow-numeric-service-without-any-hints.patch + 0001-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch libm-cabsf.patch libm-cexp.patch uclibc-ubacktrace-asneeded-fix.patch @@ -144,6 +145,7 @@ b4fb68ad3d0e8331b1b40c30eb21dfdc 0002-stdlib-fix-arc4random-return-type-to-u_in 30f27fe51fdc4d121166ad2af18dfb8d 0001-malloc-standard-synchronize-on-fork.patch 2548d9f470c9a5b2c117ec3d6f35c105 0001-time-fix-parsing-of-tzdata-files-where-off_t-is-64-b.patch 9e1ffc8dae55f4489c770f284734804f 0001-getaddrinfo-allow-numeric-service-without-any-hints.patch +1aed313e59ca9bc15f87273d4b3d4fde 0001-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch 40e9c7f017cc81ee5b19ead000b9b6b7 libm-cabsf.patch 42416385763f7cd50775ed9bfaf2d59e libm-cexp.patch 7c47e9cb284b0da8df6ed2096b2c9c66 uclibc-ubacktrace-asneeded-fix.patch -- cgit v1.2.3