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
|
||||
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 @@ libc_common_c_includes := \
|
||||
$(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 @@ ifneq ($(filter arm x86,$(TARGET_ARCH)),)
|
||||
#
|
||||
|
||||
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 @@ endif # TARGET_ARCH == x86 || TARGET_ARCH == arm
|
||||
|
||||
|
||||
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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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
|
||||
@ -25,61 +25,29 @@
|
||||
* 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
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
1: .long __PREINIT_ARRAY__
|
||||
.long __INIT_ARRAY__
|
||||
.long __FINI_ARRAY__
|
||||
.long __CTOR_LIST__
|
||||
#ifndef CRT_LEGACY_WORKAROUND
|
||||
extern void *__dso_handle;
|
||||
|
||||
.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"
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
int atexit(void (*func)(void))
|
||||
{
|
||||
return (__cxa_atexit((void (*)(void *))func, (void *)0, &__dso_handle));
|
||||
}
|
||||
#endif
|
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.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,39 +26,18 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
extern void __cxa_finalize(void *);
|
||||
extern void *__dso_handle;
|
||||
|
||||
# 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
|
||||
__attribute__((visbility("hidden")))
|
||||
void __on_dlclose() {
|
||||
__cxa_finalize(&__dso_handle);
|
||||
}
|
||||
|
||||
#ifdef CRT_LEGACY_WORKAROUND
|
||||
#include "__dso_handle.S"
|
||||
#include "__dso_handle.h"
|
||||
#else
|
||||
#include "__dso_handle_so.S"
|
||||
#include "__dso_handle_so.h"
|
||||
#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.
|
||||
*
|
||||
* 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;
|
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