xref: /aosp_15_r20/bionic/libc/arch-common/bionic/crtbegin.c (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
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