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:
		@@ -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;
 | 
			
		||||
		Reference in New Issue
	
	Block a user