arm: rewrite crtbegin* as C files.
Rewrite
crtbegin.S -> crtbegin.c
crtbegin_so.S -> crtbegin_so.c
This change allows us to generate PIC code without relying
on text relocations.
As a consequence of this rewrite, also rewrite
__dso_handle.S -> __dso_handle.c
__dso_handle_so.S -> __dso_handle_so.c
atexit.S -> atexit.c
In crtbegin.c _start, place the __PREINIT_ARRAY__, __INIT_ARRAY__,
__FINI_ARRAY__, and __CTOR_LIST__ variables onto the stack, instead of
passing a pointer to the text section of the binary.
This change appears sorta wonky, as I attempted to preserve,
as much as possible, the structure of the original assembly.
As a result, you have C files including other C files, and other
programming uglyness.
Result: This change reduces the number of files with text-relocations
from 315 to 19 on my Android build.
Before:
$ scanelf -aR $OUT/system | grep TEXTREL | wc -l
315
After:
$ scanelf -aR $OUT/system | grep TEXTREL | wc -l
19
Change-Id: Ib9f98107c0eeabcb606e1ddc7ed7fc4eba01c9c4
diff --git a/libc/Android.mk b/libc/Android.mk
index 77da9c8..9887589 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -515,8 +515,8 @@
libc_common_cflags += -DANDROID_SMP=0
endif
-# Needed to access private/__dso_handle.S from
-# crtbegin_xxx.S and crtend_xxx.S
+# Needed to access private/__dso_handle.h from
+# crtbegin_xxx.c and crtend_xxx.c
#
libc_crt_target_cflags += -I$(LOCAL_PATH)/private
@@ -531,9 +531,8 @@
$(LOCAL_PATH)/string \
$(LOCAL_PATH)/stdio
-# Needed to access private/__dso_handle.S from
+# Needed to access private/__dso_handle.h from
# crtbegin_xxx.S and crtend_xxx.S
-# and machine/asm.h
#
libc_crt_target_cflags += -I$(LOCAL_PATH)/private -I$(LOCAL_PATH)/arch-$(TARGET_ARCH)/include
@@ -555,12 +554,16 @@
#
libc_crt_target_so_cflags := $(libc_crt_target_cflags)
+libc_crt_target_crtstart_file := $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin.c
+libc_crt_target_crtstart_so_file := $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.c
ifeq ($(TARGET_ARCH),x86)
# This flag must be added for x86 targets, but not for ARM
libc_crt_target_so_cflags += -fPIC
+ libc_crt_target_crtstart_file := $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin.S
+ libc_crt_target_crtstart_so_file := $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.S
endif
GEN := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin_so.S
+$(GEN): $(libc_crt_target_crtstart_so_file)
@mkdir -p $(dir $@)
$(TARGET_CC) $(libc_crt_target_so_cflags) -o $@ -c $<
ALL_GENERATED_SOURCES += $(GEN)
@@ -574,13 +577,13 @@
GEN := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin.S
+$(GEN): $(libc_crt_target_crtstart_file)
@mkdir -p $(dir $@)
$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
ALL_GENERATED_SOURCES += $(GEN)
GEN := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
-$(GEN): $(LOCAL_PATH)/arch-$(TARGET_ARCH)/bionic/crtbegin.S
+$(GEN): $(libc_crt_target_crtstart_file)
@mkdir -p $(dir $@)
$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
ALL_GENERATED_SOURCES += $(GEN)
diff --git a/libc/arch-arm/bionic/atexit.S b/libc/arch-arm/bionic/atexit.h
similarity index 61%
copy from libc/arch-arm/bionic/atexit.S
copy to libc/arch-arm/bionic/atexit.h
index beea685..d567bfc 100644
--- a/libc/arch-arm/bionic/atexit.S
+++ b/libc/arch-arm/bionic/atexit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,37 +26,28 @@
* SUCH DAMAGE.
*/
+/* CRT_LEGACY_WORKAROUND should only be defined when building
+ * this file as part of the platform's C library.
+ *
+ * The C library already defines a function named 'atexit()'
+ * for backwards compatibility with older NDK-generated binaries.
+ *
+ * For newer ones, 'atexit' is actually embedded in the C
+ * runtime objects that are linked into the final ELF
+ * binary (shared library or executable), and will call
+ * __cxa_atexit() in order to un-register any atexit()
+ * handler when a library is unloaded.
+ *
+ * This function must be global *and* hidden. Only the
+ * code inside the same ELF binary should be able to access it.
+ */
+
#ifndef CRT_LEGACY_WORKAROUND
- .arch armv5te
- .fpu softvfp
- .eabi_attribute 20, 1
- .eabi_attribute 21, 1
- .eabi_attribute 23, 3
- .eabi_attribute 24, 1
- .eabi_attribute 25, 1
- .eabi_attribute 26, 2
- .eabi_attribute 30, 4
- .eabi_attribute 18, 4
- .hidden atexit
- .code 16
- .thumb_func
-ENTRY(atexit)
-.LFB0:
- .save {r4, lr}
- push {r4, lr}
-.LCFI0:
- ldr r3, .L3
- mov r1, #0
- @ sp needed for prologue
-.LPIC0:
- add r3, pc
- ldr r2, [r3]
- bl __cxa_atexit
- pop {r4, pc}
-.L4:
- .align 2
-.L3:
- .word __dso_handle-(.LPIC0+4)
-.LFE0:
-END(atexit)
+extern void *__dso_handle;
+
+__attribute__ ((visibility ("hidden")))
+int atexit(void (*func)(void))
+{
+ return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
+}
#endif
diff --git a/libc/arch-arm/bionic/crtbegin.S b/libc/arch-arm/bionic/crtbegin.S
deleted file mode 100644
index 8843204..0000000
--- a/libc/arch-arm/bionic/crtbegin.S
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- .text
- .align 4
- .type _start,#function
- .globl _start
-
-# this is the small startup code that is first run when
-# any executable that is linked with Bionic runs.
-#
-# it's purpose is to call __libc_init with appropriate
-# arguments, which are:
-#
-# - the address of the raw data block setup by the Linux
-# kernel ELF loader
-#
-# - address of an "onexit" function, not used on any
-# platform supported by Bionic
-#
-# - address of the "main" function of the program.
-#
-# - address of the constructor list
-#
-_start:
- mov r0, sp
- mov r1, #0
- ldr r2, =main
- adr r3, 1f
- ldr r4, =__libc_init
- blx r4
- mov r0, #0
- bx r0
-
-1: .long __PREINIT_ARRAY__
- .long __INIT_ARRAY__
- .long __FINI_ARRAY__
- .long __CTOR_LIST__
-
- .section .preinit_array, "aw"
- .globl __PREINIT_ARRAY__
-__PREINIT_ARRAY__:
- .long -1
-
- .section .init_array, "aw"
- .globl __INIT_ARRAY__
-__INIT_ARRAY__:
- .long -1
-
- .section .fini_array, "aw"
- .globl __FINI_ARRAY__
-__FINI_ARRAY__:
- .long -1
-
- .section .ctors, "aw"
- .globl __CTOR_LIST__
-__CTOR_LIST__:
- .long -1
-
-#include "__dso_handle.S"
-#include "atexit.S"
diff --git a/libc/arch-arm/bionic/crtbegin.c b/libc/arch-arm/bionic/crtbegin.c
new file mode 100644
index 0000000..9dcd254
--- /dev/null
+++ b/libc/arch-arm/bionic/crtbegin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+typedef struct
+{
+ void (**preinit_array)(void);
+ void (**init_array)(void);
+ void (**fini_array)(void);
+ void (**ctors_array)(void);
+} structors_array_t;
+
+extern int main(int argc, char **argv, char **env);
+
+extern void __libc_init(
+ unsigned int *elfdata,
+ void (*onexit)(void),
+ int (*slingshot)(int, char**, char**),
+ structors_array_t const * const structors
+);
+
+__attribute__ ((section (".preinit_array")))
+void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".init_array")))
+void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".fini_array")))
+void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
+
+__attribute__ ((section (".ctors")))
+void (*__CTOR_LIST__)(void) = (void (*)(void)) -1;
+
+__attribute__((visbility("hidden")))
+void _start() {
+ structors_array_t array;
+ void *elfdata;
+
+ array.preinit_array = &__PREINIT_ARRAY__;
+ array.init_array = &__INIT_ARRAY__;
+ array.fini_array = &__FINI_ARRAY__;
+ array.ctors_array = &__CTOR_LIST__;
+
+ elfdata = __builtin_frame_address(0) + sizeof(void *);
+ __libc_init(elfdata, (void *) 0, &main, &array);
+}
+
+#include "__dso_handle.h"
+#include "atexit.h"
diff --git a/libc/arch-arm/bionic/crtbegin_so.S b/libc/arch-arm/bionic/crtbegin_so.S
deleted file mode 100644
index 104d214..0000000
--- a/libc/arch-arm/bionic/crtbegin_so.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-
-# Implement static C++ destructors when the shared
-# library is unloaded through dlclose().
-#
-# A call to this function must be the first entry
-# in the .fini_array. See 3.3.5.3.C of C++ ABI
-# standard.
-#
-ENTRY(__on_dlclose)
- adr r0, 0f
- ldr r0, [r0]
- b __cxa_finalize
-END(__on_dlclose)
-
-0:
- .long __dso_handle
-
- .section .init_array, "aw"
- .globl __INIT_ARRAY__
-__INIT_ARRAY__:
- .long -1
-
- .section .fini_array, "aw"
- .globl __FINI_ARRAY__
-__FINI_ARRAY__:
- .long -1
- .long __on_dlclose
-
-#ifdef CRT_LEGACY_WORKAROUND
-#include "__dso_handle.S"
-#else
-#include "__dso_handle_so.S"
-#endif
-
-#include "atexit.S"
diff --git a/libc/arch-arm/bionic/atexit.S b/libc/arch-arm/bionic/crtbegin_so.c
similarity index 69%
copy from libc/arch-arm/bionic/atexit.S
copy to libc/arch-arm/bionic/crtbegin_so.c
index beea685..57d19bf 100644
--- a/libc/arch-arm/bionic/atexit.S
+++ b/libc/arch-arm/bionic/crtbegin_so.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,37 +26,18 @@
* SUCH DAMAGE.
*/
-#ifndef CRT_LEGACY_WORKAROUND
- .arch armv5te
- .fpu softvfp
- .eabi_attribute 20, 1
- .eabi_attribute 21, 1
- .eabi_attribute 23, 3
- .eabi_attribute 24, 1
- .eabi_attribute 25, 1
- .eabi_attribute 26, 2
- .eabi_attribute 30, 4
- .eabi_attribute 18, 4
- .hidden atexit
- .code 16
- .thumb_func
-ENTRY(atexit)
-.LFB0:
- .save {r4, lr}
- push {r4, lr}
-.LCFI0:
- ldr r3, .L3
- mov r1, #0
- @ sp needed for prologue
-.LPIC0:
- add r3, pc
- ldr r2, [r3]
- bl __cxa_atexit
- pop {r4, pc}
-.L4:
- .align 2
-.L3:
- .word __dso_handle-(.LPIC0+4)
-.LFE0:
-END(atexit)
+extern void __cxa_finalize(void *);
+extern void *__dso_handle;
+
+__attribute__((visbility("hidden")))
+void __on_dlclose() {
+ __cxa_finalize(&__dso_handle);
+}
+
+#ifdef CRT_LEGACY_WORKAROUND
+#include "__dso_handle.h"
+#else
+#include "__dso_handle_so.h"
#endif
+
+#include "atexit.h"
diff --git a/libc/private/__dso_handle.S b/libc/arch-x86/bionic/__dso_handle.S
similarity index 100%
rename from libc/private/__dso_handle.S
rename to libc/arch-x86/bionic/__dso_handle.S
diff --git a/libc/private/__dso_handle_so.S b/libc/arch-x86/bionic/__dso_handle_so.S
similarity index 100%
rename from libc/private/__dso_handle_so.S
rename to libc/arch-x86/bionic/__dso_handle_so.S
diff --git a/libc/arch-arm/bionic/atexit.S b/libc/private/__dso_handle.h
similarity index 70%
rename from libc/arch-arm/bionic/atexit.S
rename to libc/private/__dso_handle.h
index beea685..e67ce7c 100644
--- a/libc/arch-arm/bionic/atexit.S
+++ b/libc/private/__dso_handle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,37 +26,9 @@
* SUCH DAMAGE.
*/
+
#ifndef CRT_LEGACY_WORKAROUND
- .arch armv5te
- .fpu softvfp
- .eabi_attribute 20, 1
- .eabi_attribute 21, 1
- .eabi_attribute 23, 3
- .eabi_attribute 24, 1
- .eabi_attribute 25, 1
- .eabi_attribute 26, 2
- .eabi_attribute 30, 4
- .eabi_attribute 18, 4
- .hidden atexit
- .code 16
- .thumb_func
-ENTRY(atexit)
-.LFB0:
- .save {r4, lr}
- push {r4, lr}
-.LCFI0:
- ldr r3, .L3
- mov r1, #0
- @ sp needed for prologue
-.LPIC0:
- add r3, pc
- ldr r2, [r3]
- bl __cxa_atexit
- pop {r4, pc}
-.L4:
- .align 2
-.L3:
- .word __dso_handle-(.LPIC0+4)
-.LFE0:
-END(atexit)
+__attribute__ ((visibility ("hidden")))
#endif
+__attribute__ ((section (".bss")))
+void *__dso_handle = (void *) 0;
diff --git a/libc/arch-arm/bionic/atexit.S b/libc/private/__dso_handle_so.c
similarity index 68%
copy from libc/arch-arm/bionic/atexit.S
copy to libc/private/__dso_handle_so.c
index beea685..198e64b 100644
--- a/libc/arch-arm/bionic/atexit.S
+++ b/libc/private/__dso_handle_so.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,37 +26,7 @@
* SUCH DAMAGE.
*/
-#ifndef CRT_LEGACY_WORKAROUND
- .arch armv5te
- .fpu softvfp
- .eabi_attribute 20, 1
- .eabi_attribute 21, 1
- .eabi_attribute 23, 3
- .eabi_attribute 24, 1
- .eabi_attribute 25, 1
- .eabi_attribute 26, 2
- .eabi_attribute 30, 4
- .eabi_attribute 18, 4
- .hidden atexit
- .code 16
- .thumb_func
-ENTRY(atexit)
-.LFB0:
- .save {r4, lr}
- push {r4, lr}
-.LCFI0:
- ldr r3, .L3
- mov r1, #0
- @ sp needed for prologue
-.LPIC0:
- add r3, pc
- ldr r2, [r3]
- bl __cxa_atexit
- pop {r4, pc}
-.L4:
- .align 2
-.L3:
- .word __dso_handle-(.LPIC0+4)
-.LFE0:
-END(atexit)
-#endif
+
+__attribute__ ((visibility ("hidden")))
+__attribute__ ((section (".data")))
+void *__dso_handle;