1 This directory contains the sources of the C runtime object files 2 required by the Android NDK toolchains. This document explains 3 what they are, as well as a few important details about them. 4 5 The files are located under the following directories: 6 7 android-3/arch-arm/src/ 8 android-9/arch-x86/src/ 9 android-9/arch-mips/src/ 10 11 They are either C files, or assembly files with an .S extension, which means 12 that they'll be sent to the C-preprocessor before being assembled into 13 object files. They have the following names and usage: 14 15 crtbegin_static.[cS] 16 This file contains a tiny ELF startup entry point (named '_start') 17 that is linked into every Android _static_ executable. These binaries can 18 run on any Linux ARM system, but cannot perform dynamic linking at all. 19 20 Note that the kernel calls the '_start' entry point directly when it 21 launches such an executable. The _start stub is used to call the 22 C library's runtime initialization, passing it the address of the 23 'main' function. 24 25 crtbegin_dynamic.[cS] 26 This is equivalent to crtbegin_static.[cS] but for _dynamic_ executables. 27 These executables always link to the system C library dynamically. 28 29 When the kernel launches such an executable, it actually starts the 30 dynamic linker (/system/bin/linker), which loads and relocates the 31 executable (possibly loading any dependent system libraries as well), 32 then call the _start stub. 33 34 crtbegin_so.[cS] 35 This is equivalent to crtbegin_dynamic.[cS], but shall be used for 36 shared libraries. One major difference is that there is no _start 37 entry point. 38 39 crtend_android.S 40 This source file shall be used when generating an executable, i.e. used 41 in association with either crtbegin_static.[cS] or crtbegin_dynamic.[cS] 42 43 crtend.S 44 This source file is _strictly_ equivalent to crtend_android.S. 45 Actually, it *must* be compiled into an object named 'crtend_android.o' 46 because that's the hard-coded name that the toolchain binaries expect. 47 48 (the naming difference for this source file is purely historical, it 49 could probably be removed in the future). 50 51 crtend_so.S 52 This source's object file shall be used when generating a shared library, 53 i.e. used in association with crtbegin_so.[cS] only. 54 55 Content of these files: 56 57 ELF section (lists); 58 59 crtbegin_static.[cS] and crtbegin_dynamic.[cS] contain a '_start' entry point 60 for the corresponding executable. crtbegin_so.[cS] doesn't need any. 61 62 all crtbegin_XXX.[cS] files contain the head of various ELF sections, which are 63 used to list of ELF constructors and destructors. The sections are: 64 65 .init_array: 66 Contains a list of function addresses that are run at load time. 67 This means they are run *before* 'main', in the case of executables, 68 or during 'dlopen()' for shared libraries (either implicit or explicit). 69 70 The functions are called in list order (from first to last). 71 72 .fini_array: 73 Contains a list of destructor addresses that are run at unload time. 74 This means they are run *after* 'exit', in the case of executables, 75 or during 'dlclose()' for shared libraries (either implicit or explicit). 76 77 The functions are called in _reverse_ list order (from last to first). 78 79 .preinit_array: 80 This section can *only* appear in executables. It contains a list of 81 constructors that are run _before_ the ones in .init_array, or those 82 of any dependent shared library (if any). 83 84 .ctors 85 This section shall *not* be used on Android. Used on some GLibc-based 86 Linux systems to hold list of constructors. The toolchains should 87 place all constructors in .init_array instead. 88 89 .dtors 90 This section shall *not* be used on Android. Used on some GLibc-based 91 Linux systems to hold a list of destructors. The toolchains should 92 place all destructors in .fini_array instead. 93 94 95 __dso_handle symbol: 96 97 To properly support the C++ ABI, a unique *local* *hidden* symbol named 98 '__dso_handle' must be defined in each shared library. 99 100 This is used to implement static C++ object initialization in a shared 101 library, as in: 102 103 static Foo foo(10); 104 105 The statement above creates a hidden function, which address will be added 106 to the .init_array section described above. Its compiler-generated code 107 will perform the object construction, and also register static destructor 108 using a call that looks like: 109 110 __cxa_atexit( Foo::~Foo, &foo, &__dso_handle ); 111 112 Where '__cxa_atexit' is a special C++ support function provided by the 113 C library. Doing this ensures that the destructor for 'foo' will be 114 automatically called when the shared library containing this code is 115 unloaded (i.e. either through 'dlclose' or at program exit). 116 117 The value of __dso_handle is normally never taken directly. 118 119 See http://sourcery.mentor.com/public/cxx-abi/abi.html#dso-dtor 120 121 WARNING: There is a big caveat regarding this symbol. Read the section 122 named 'IMPORTANT BACKWARDS COMPATIBILITY ISSUES' below. 123 124 125 atexit() implementation: 126 127 The Posix standard doesn't mandate the program behaviour's when a shared 128 library which registered a function with 'atexit' is unloaded explicitely 129 (e.g. with 'dlclose()'). 130 131 On most BSD systems (including OS X), unloading the library succeeds, but 132 the program will crash when it calls exit() or returns from main(). 133 134 On Linux, GLibc provides an implementation that automatically unregisters 135 such atexit() handlers when the corresponding shared library is unloaded. 136 137 However, this requires that the atexit() implementation be part of the 138 shared library itself, rather than the C library. 139 140 The crtbegin_dynamic.[cS] and crtbegin_so.[cS] files contain an tiny 141 implementation of atexit() in assembler that essentially does: 142 143 void atexit(void(*myfunc)(void)) 144 { 145 __cxa_atexit(myfunc, NULL, &__dso_handle); 146 } 147 148 Because it references the shared library's hidden __dso_handle symbol, 149 this code cannot be in the C library itself. 150 151 Note that crtbegin_static.[cS] should *not* provide an atexit() function 152 (the latter should be provided by libc.a instead). 153 154 See 'BACKWARDS COMPATIBILITY ISSUES' section below. 155 156 157 158 BACKWARDS COMPATIBILITY ISSUES: 159 ------------------------------- 160 161 To maintain binary compatibility to all existing NDK-generated machine code, 162 the system's C library (i.e. /system/lib/libc.so) needs to exports symbols 163 that shall *not* be exported by the NDK-provided link-time libraries (i.e. 164 $NDK/platforms/android-$LEVEL/arch-$ARCH/usr/lib/libc.so). 165 166 Starting from NDK r7, the NDK libc.so is itself generated by a script 167 (gen-platforms.sh) from a list of symbol files (see libc.so.functions.txt 168 and libc.so.variables.txt) and does not contain any implementation code. 169 170 The NDK libc.a, on the other hand, is a copy of a given version of the system 171 C static library, and shall only be used to generate static executables (it 172 is also required to build gdbserver). 173 174 1. libgcc compatibility symbols: 175 176 None of the link-time NDK shared libraries should export any libgcc symbol. 177 178 However, on ARM, the system C library needs to export some of them to 179 maintain binary compatibility with 'legacy' NDK machine code. Details are 180 under bionic/libc/arch-arm/bionic/libgcc_compat.c. 181 182 Note that gen-platforms.sh takes care of this by explicitely removing any 183 libgcc symbol from the link-time shared libraries it generates. This is done 184 by using the lists under: 185 186 $NDK/build/tools/unwanted-symbols/$ARCH/libgcc.a.functions.txt 187 188 You will need to update these files when the toolchain changes. 189 190 Note that all libgcc releases should be backwards-compatible, i.e. newer 191 releases always contain all the symbols from previous ones). 192 193 194 2. __dso_handle compatibility symbol: 195 196 Earlier versions of the C library exported a __dso_handle symbol 197 *incorrectly*. As such: 198 199 - the system's libc.so shall always export its __dso_handle, as *global* 200 and *public* (in ELF visibility terms). A weak symbol definition is ok 201 but not necessary. This is only to ensure binary compatibility with 202 'legacy' NDK machine code. 203 204 - the NDK link-time libc.so shall *never* export or contain any 205 __dso_handle symbol. 206 207 - The NDK's crtbegin_dynamic.[cS] and crtbegin_so.[cS] shall provide a *local* 208 and *hidden* __dso_handle symbol. 209 210 - The NDK's libc.a will containg a *global* and *public* __dso_handle, since 211 it is a copy of a release-specific system libc.so. 212 213 - crtbegin_static.[cS] shall not provide any __dso_handle symbol, since static 214 executables will use the one in libc.a instead. 215 216 Note that existing NDK machine code that links against the system libc's 217 __dso_handle will not have their C++ destructors run correctly when the 218 library is unloaded. However, this bug can be solved by simply recompiling 219 /relinking against a newer NDK release, without touching the original 220 sources. 221 222 223 224 3. atexit compatibility symbol: 225 226 Earlier versions of the C library implemented and exported an atexit() 227 function. While this is compliant with Posix, this doesn't allow a useful 228 GLibc extension which automatically un-registers atexit() handlers when 229 a shared library is unloaded with dlclose(). 230 231 To support this, while providing binary compatibility, the following 232 must apply: 233 234 - The platform's /system/lib/libc.so should *always* export a working 235 atexit() implementation (used by 'legacy' NDK machine code). 236 237 - The NDK link-time libc.so should *never* export atexit() 238 239 - crtbegin_dynamic.[cS] and crtbegin_so.[cS] shall define a *local* *hidden* 240 symbol for atexit(), with a tiny implementation that amounts to the 241 following code: 242 243 void atexit( void(*handler)(void) ) 244 { 245 __cxa_atexit( handler, NULL, &__dso_handle ); 246 } 247 248 - The NDK libc.a shall provide an atexit() implementation, and 249 crtbegin_static.[cS] shall *not* provide one to avoid conflicts. 250 251 Note that existing NDK machine code that links against the system libc's 252 atexit symbol will not have their atexit-handler automatically unregistered 253 when the library is unloaded. However, this bug can be solved by simply 254 recompiling/relinking against a newer NDK release, without touching the 255 original sources. 256 257 4. __atomic_xxx sompatibility symbols: 258 259 This issues is detailed in ndk/docs/ANDROID-ATOMICS.html and 260 bionic/libc/arch-arm/bionic/atomics_arm.c. In a nutshell: 261 262 - The system C library *shall* always export on *ARM* the __atomic_cmpxchg, 263 __atomic_inc and __atomic_dec functions to support legacy NDK machine code. 264 Their implementation should have full (i.e. acquire+release) memory ordering 265 semantics. 266 267 - The system C library for other CPU architectures (e.g. x86 or mips) *shall* 268 *not* export any of these symbols. 269 270 - The NDK libc.so *shall* *not* export these symbols at all. 271 272 - The NDK <sys/atomics.h> header shall provide inlined-static versions of 273 these functions that use the built-in GCC atomic functions instead. 274 275