1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include "../../bionic/libc_init_common.h"
30 #include <stddef.h>
31 #include <stdint.h>
32
33 extern init_func_t* __preinit_array_start[];
34 extern init_func_t* __preinit_array_end[];
35 extern init_func_t* __init_array_start[];
36 extern init_func_t* __init_array_end[];
37 extern fini_func_t* __fini_array_start[];
38 extern fini_func_t* __fini_array_end[];
39
40 #if !defined(CRTBEGIN_STATIC)
41 /* This function will be called during normal program termination
42 * to run the destructors that are listed in the .fini_array section
43 * of the executable, if any.
44 *
45 * 'fini_array' points to a list of function addresses.
46 */
call_fini_array()47 static void call_fini_array() {
48 fini_func_t** array = __fini_array_start;
49 size_t count = __fini_array_end - __fini_array_start;
50 // Call fini functions in reverse order.
51 while (count-- > 0) {
52 fini_func_t* function = array[count];
53 (*function)();
54 }
55 }
56
57 // libc.so needs fini_array with sentinels. So create a fake fini_array with sentinels.
58 // It contains a function to call functions in real fini_array.
59 static fini_func_t* fini_array_with_sentinels[] = {
60 (fini_func_t*)-1,
61 &call_fini_array,
62 (fini_func_t*)0,
63 };
64 #endif // !defined(CRTBEGIN_STATIC)
65
_start_main(void * raw_args)66 __used static void _start_main(void* raw_args) {
67 structors_array_t array = {};
68 #if defined(CRTBEGIN_STATIC)
69 array.preinit_array = __preinit_array_start;
70 array.preinit_array_count = __preinit_array_end - __preinit_array_start;
71 array.init_array = __init_array_start;
72 array.init_array_count = __init_array_end - __init_array_start;
73 array.fini_array = __fini_array_start;
74 array.fini_array_count = __fini_array_end - __fini_array_start;
75 #else
76 if (__fini_array_end - __fini_array_start > 0) {
77 array.fini_array = fini_array_with_sentinels;
78 }
79 #endif // !defined(CRTBEGIN_STATIC)
80
81 __libc_init(raw_args, NULL, &main, &array);
82 }
83
84 #define PRE ".text; .global _start; .type _start,%function; _start:"
85 #define POST "; .size _start, .-_start"
86
87 #if defined(__aarch64__)
88 __asm__(PRE "bti j; mov x29,#0; mov x30,#0; mov x0,sp; b _start_main" POST);
89 #elif defined(__arm__)
90 __asm__(PRE "mov fp,#0; mov lr,#0; mov r0,sp; b _start_main" POST);
91 #elif defined(__i386__)
92 __asm__(PRE
93 "xorl %ebp,%ebp; movl %esp,%eax; andl $~0xf,%esp; subl $12,%esp; pushl %eax;"
94 "call _start_main" POST);
95 #elif defined(__riscv)
96 __asm__(PRE "li fp,0; li ra,0; mv a0,sp; tail _start_main" POST);
97 #elif defined(__x86_64__)
98 __asm__(PRE "xorl %ebp, %ebp; movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST);
99 #else
100 #error unsupported architecture
101 #endif
102
103 #undef PRE
104 #undef POST
105
106 // On arm32 and arm64, when targeting Q and up, overalign the TLS segment to
107 // (8 * sizeof(void*)), which reserves enough space between the thread pointer
108 // and the executable's TLS segment for Bionic's TLS slots. It has the side
109 // effect of placing a 0-sized TLS segment into Android executables that don't
110 // use TLS, but this should be harmless.
111 //
112 // To ensure that the .tdata input section isn't deleted (e.g. by
113 // --gc-sections), the .text input section (which contains _start) has a
114 // relocation to the .tdata input section.
115 #if __ANDROID_API__ >= 29
116 #if defined(__arm__)
117 asm(" .section .tdata,\"awT\",%progbits\n"
118 " .p2align 5\n"
119 " .text\n"
120 " .reloc 0, R_ARM_NONE, .tdata\n");
121 #elif defined(__aarch64__)
122 asm(" .section .tdata,\"awT\",@progbits\n"
123 " .p2align 6\n"
124 " .text\n"
125 " .reloc 0, R_AARCH64_NONE, .tdata\n");
126 #endif
127 #endif
128
129 #include "__dso_handle.h"
130 #include "atexit.h"
131 #include "pthread_atfork.h"
132