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
This commit is contained in:
parent
857fc9eab9
commit
9d40326830
@ -515,8 +515,8 @@ else
|
|||||||
libc_common_cflags += -DANDROID_SMP=0
|
libc_common_cflags += -DANDROID_SMP=0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Needed to access private/__dso_handle.S from
|
# Needed to access private/__dso_handle.h from
|
||||||
# crtbegin_xxx.S and crtend_xxx.S
|
# crtbegin_xxx.c and crtend_xxx.c
|
||||||
#
|
#
|
||||||
libc_crt_target_cflags += -I$(LOCAL_PATH)/private
|
libc_crt_target_cflags += -I$(LOCAL_PATH)/private
|
||||||
|
|
||||||
@ -531,9 +531,8 @@ libc_common_c_includes := \
|
|||||||
$(LOCAL_PATH)/string \
|
$(LOCAL_PATH)/string \
|
||||||
$(LOCAL_PATH)/stdio
|
$(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
|
# 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
|
libc_crt_target_cflags += -I$(LOCAL_PATH)/private -I$(LOCAL_PATH)/arch-$(TARGET_ARCH)/include
|
||||||
|
|
||||||
@ -555,12 +554,16 @@ ifneq ($(filter arm x86,$(TARGET_ARCH)),)
|
|||||||
#
|
#
|
||||||
|
|
||||||
libc_crt_target_so_cflags := $(libc_crt_target_cflags)
|
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)
|
ifeq ($(TARGET_ARCH),x86)
|
||||||
# This flag must be added for x86 targets, but not for ARM
|
# This flag must be added for x86 targets, but not for ARM
|
||||||
libc_crt_target_so_cflags += -fPIC
|
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
|
endif
|
||||||
GEN := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
|
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 $@)
|
@mkdir -p $(dir $@)
|
||||||
$(TARGET_CC) $(libc_crt_target_so_cflags) -o $@ -c $<
|
$(TARGET_CC) $(libc_crt_target_so_cflags) -o $@ -c $<
|
||||||
ALL_GENERATED_SOURCES += $(GEN)
|
ALL_GENERATED_SOURCES += $(GEN)
|
||||||
@ -574,13 +577,13 @@ endif # TARGET_ARCH == x86 || TARGET_ARCH == arm
|
|||||||
|
|
||||||
|
|
||||||
GEN := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
|
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 $@)
|
@mkdir -p $(dir $@)
|
||||||
$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
|
$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
|
||||||
ALL_GENERATED_SOURCES += $(GEN)
|
ALL_GENERATED_SOURCES += $(GEN)
|
||||||
|
|
||||||
GEN := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
|
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 $@)
|
@mkdir -p $(dir $@)
|
||||||
$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
|
$(TARGET_CC) $(libc_crt_target_cflags) -o $@ -c $<
|
||||||
ALL_GENERATED_SOURCES += $(GEN)
|
ALL_GENERATED_SOURCES += $(GEN)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 The Android Open Source Project
|
* Copyright (C) 2012 The Android Open Source Project
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -25,61 +25,29 @@
|
|||||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
.text
|
|
||||||
.align 4
|
|
||||||
.type _start,#function
|
|
||||||
.globl _start
|
|
||||||
|
|
||||||
# this is the small startup code that is first run when
|
/* CRT_LEGACY_WORKAROUND should only be defined when building
|
||||||
# any executable that is linked with Bionic runs.
|
* this file as part of the platform's C library.
|
||||||
#
|
*
|
||||||
# it's purpose is to call __libc_init with appropriate
|
* The C library already defines a function named 'atexit()'
|
||||||
# arguments, which are:
|
* for backwards compatibility with older NDK-generated binaries.
|
||||||
#
|
*
|
||||||
# - the address of the raw data block setup by the Linux
|
* For newer ones, 'atexit' is actually embedded in the C
|
||||||
# kernel ELF loader
|
* runtime objects that are linked into the final ELF
|
||||||
#
|
* binary (shared library or executable), and will call
|
||||||
# - address of an "onexit" function, not used on any
|
* __cxa_atexit() in order to un-register any atexit()
|
||||||
# platform supported by Bionic
|
* handler when a library is unloaded.
|
||||||
#
|
*
|
||||||
# - address of the "main" function of the program.
|
* This function must be global *and* hidden. Only the
|
||||||
#
|
* code inside the same ELF binary should be able to access it.
|
||||||
# - 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__
|
#ifndef CRT_LEGACY_WORKAROUND
|
||||||
.long __INIT_ARRAY__
|
extern void *__dso_handle;
|
||||||
.long __FINI_ARRAY__
|
|
||||||
.long __CTOR_LIST__
|
|
||||||
|
|
||||||
.section .preinit_array, "aw"
|
__attribute__ ((visibility ("hidden")))
|
||||||
.globl __PREINIT_ARRAY__
|
int atexit(void (*func)(void))
|
||||||
__PREINIT_ARRAY__:
|
{
|
||||||
.long -1
|
return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
|
||||||
|
}
|
||||||
.section .init_array, "aw"
|
#endif
|
||||||
.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"
|
|
73
libc/arch-arm/bionic/crtbegin.c
Normal file
73
libc/arch-arm/bionic/crtbegin.c
Normal file
@ -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"
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 The Android Open Source Project
|
* Copyright (C) 2012 The Android Open Source Project
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -26,39 +26,18 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <machine/asm.h>
|
extern void __cxa_finalize(void *);
|
||||||
|
extern void *__dso_handle;
|
||||||
|
|
||||||
# Implement static C++ destructors when the shared
|
__attribute__((visbility("hidden")))
|
||||||
# library is unloaded through dlclose().
|
void __on_dlclose() {
|
||||||
#
|
__cxa_finalize(&__dso_handle);
|
||||||
# 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
|
#ifdef CRT_LEGACY_WORKAROUND
|
||||||
#include "__dso_handle.S"
|
#include "__dso_handle.h"
|
||||||
#else
|
#else
|
||||||
#include "__dso_handle_so.S"
|
#include "__dso_handle_so.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "atexit.S"
|
#include "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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -26,37 +26,9 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRT_LEGACY_WORKAROUND
|
#ifndef CRT_LEGACY_WORKAROUND
|
||||||
.arch armv5te
|
__attribute__ ((visibility ("hidden")))
|
||||||
.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
|
#endif
|
||||||
|
__attribute__ ((section (".bss")))
|
||||||
|
void *__dso_handle = (void *) 0;
|
32
libc/private/__dso_handle_so.c
Normal file
32
libc/private/__dso_handle_so.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__ ((visibility ("hidden")))
|
||||||
|
__attribute__ ((section (".data")))
|
||||||
|
void *__dso_handle;
|
Loading…
x
Reference in New Issue
Block a user