summaryrefslogtreecommitdiffstats
path: root/libc/arch-arm
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugenis@google.com>2012-04-10 14:10:11 +0400
committerEvgeniy Stepanov <eugenis@google.com>2012-04-10 16:45:54 +0400
commitcd15bacf334ab254a5f61c3bba100adde1b6b80a (patch)
treec01939f5d40d2827551840475b0453affe575f11 /libc/arch-arm
parent8c4f3ce8d084e3949d77ad8743593b5c83c3d41c (diff)
downloadbionic-cd15bacf334ab254a5f61c3bba100adde1b6b80a.zip
bionic-cd15bacf334ab254a5f61c3bba100adde1b6b80a.tar.gz
bionic-cd15bacf334ab254a5f61c3bba100adde1b6b80a.tar.bz2
Fix segv when unwinding stack past __libc_init.
This change fixes a segmentation fault in the libc unwinder when it goes past __libc_init. Unwind instructions for __libc_init direct it to grab the return address from the stack frame. Without this change, the unwinder gets a wild address and looks up further unwind instructions for the routine at that address. If it's unlucky enough to hit an existing function, it will try to unwind it. Bad things happen then. With this change, the return address always points to the _start function, which does not have unwind instructions associated with it. This stop the unwind process. __libc_init never returns, so this does not affect program execution, other than adding 4 bytes on the main thread stack. Change-Id: Id58612172e8825c8729cccd081541a13bff96bd0
Diffstat (limited to 'libc/arch-arm')
-rw-r--r--libc/arch-arm/bionic/crtbegin_dynamic.S4
1 files changed, 3 insertions, 1 deletions
diff --git a/libc/arch-arm/bionic/crtbegin_dynamic.S b/libc/arch-arm/bionic/crtbegin_dynamic.S
index 6ca0845..ec6d482 100644
--- a/libc/arch-arm/bionic/crtbegin_dynamic.S
+++ b/libc/arch-arm/bionic/crtbegin_dynamic.S
@@ -53,7 +53,9 @@ _start:
ldr r2, =main
adr r3, 1f
ldr r4, =__libc_init
- bx r4
+ blx r4
+ mov r0, #0
+ bx r0
1: .long __PREINIT_ARRAY__
.long __INIT_ARRAY__