• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1This directory contains the sources of the C runtime object files
2required by the Android NDK toolchains. This document explains
3what they are, as well as a few important details about them.
4
5The 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
11They are either C files, or assembly files with an .S extension, which means
12that they'll be sent to the C-preprocessor before being assembled into
13object 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 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
55Content of these files:
56
57ELF 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
125atexit() 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
158BACKWARDS COMPATIBILITY ISSUES:
159-------------------------------
160
161To maintain binary compatibility to all existing NDK-generated machine code,
162the system's C library (i.e. /system/lib/libc.so) needs to exports symbols
163that 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
166Starting 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
168and libc.so.variables.txt) and does not contain any implementation code.
169
170The NDK libc.a, on the other hand, is a copy of a given version of the system
171C static library, and shall only be used to generate static executables (it
172is also required to build gdbserver).
173
1741. 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
1942. __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
216Note 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
218library is unloaded. However, this bug can be solved by simply recompiling
219/relinking against a newer NDK release, without touching the original
220sources.
221
222
223
2243. 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
251Note that existing NDK machine code that links against the system libc's
252atexit symbol will not have their atexit-handler automatically unregistered
253when the library is unloaded. However, this bug can be solved by simply
254recompiling/relinking against a newer NDK release, without touching the
255original sources.
256
2574. __atomic_xxx sompatibility symbols:
258
259This issues is detailed in ndk/docs/ANDROID-ATOMICS.html and
260bionic/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