OSDN Git Service

Fix -fstack-protector-strong for x86.
authorElliott Hughes <enh@google.com>
Tue, 8 Dec 2015 20:43:13 +0000 (12:43 -0800)
committerElliott Hughes <enh@google.com>
Tue, 8 Dec 2015 20:48:42 +0000 (12:48 -0800)
We need to ensure %gs:20 is set up early enough for -fstack-protector-strong
on x86, and that __set_tls doesn't get stack protector checks because it's a
prerequisite for them. x86 devices/emulators won't boot without this.

Bug: http://b/26073874
Change-Id: Icf0d34294648cc0c8cb406a3617befe0d45c525a

libc/Android.mk
libc/arch-x86/x86.mk
libc/bionic/libc_init_common.cpp

index ba3e5aa..456527a 100644 (file)
@@ -697,6 +697,9 @@ endef
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := bionic/__stack_chk_fail.cpp
+# On x86, the __set_tls implementation is complex enough that
+# -fstack-protector-strong inserts a check.
+LOCAL_SRC_FILES_x86 := arch-x86/bionic/__set_tls.c
 LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
index b4056bb..1d717aa 100644 (file)
@@ -109,7 +109,6 @@ libc_bionic_src_files_x86 += \
     arch-x86/bionic/libgcc_compat.c \
     arch-x86/bionic/__restore.S \
     arch-x86/bionic/setjmp.S \
-    arch-x86/bionic/__set_tls.c \
     arch-x86/bionic/syscall.S \
     arch-x86/bionic/vfork.S \
 
index 8f1ee95..b0c62d6 100644 (file)
@@ -79,6 +79,10 @@ void __libc_init_main_thread(KernelArgumentBlock& args) {
 
   static pthread_internal_t main_thread;
 
+  // The x86 -fstack-protector implementation uses TLS, so make sure that's
+  // set up before we call any function that might get a stack check inserted.
+  __set_tls(main_thread.tls);
+
   // Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
   // As a side-effect, this tells us our pid (which is the same as the main thread's tid).
   main_thread.tid = __set_tid_address(&main_thread.tid);
@@ -97,7 +101,6 @@ void __libc_init_main_thread(KernelArgumentBlock& args) {
 
   __init_thread(&main_thread);
   __init_tls(&main_thread);
-  __set_tls(main_thread.tls);
 
   // Store a pointer to the kernel argument block in a TLS slot to be
   // picked up by the libc constructor.