Skip to content

Commit c424ad1

Browse files
Andrew Hsiehandroid code review
Andrew Hsieh
authored and
android code review
committed
Merge "ndk: Remove prebuilt C runtime objects. Add sources instead."
2 parents 86ef5ca + 5e7c4e6 commit c424ad1

34 files changed

+1370
-1
lines changed

ndk/platforms/README.CRT.TXT

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
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 all *assembly* files with an .S extension, which means that
12+
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.S
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.S
26+
This is equivalent to crtbegin_static.S, for 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.S
35+
This is equivalent to crtbegin_dynamic.S, 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.S or crtbegin_dynamic.S
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.S only.
54+
55+
Content of these files:
56+
57+
ELF section (lists);
58+
59+
crtbegin_static.S + crtbegin_dynamic.S contain a '_start' entry point for
60+
the corresponding executable. crtbegin_so.S doesn't need any.
61+
62+
all crtbegin_XXX.s 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_shared.S and crtbegin_static.S 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.S 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/toolchain-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.S and crtbegin_so.S 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.S 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_shared.S, crtbegin_so.S 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.S 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+
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-716 Bytes
Binary file not shown.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (C) 2010 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+
# The __dso_handle global variable is used by static
30+
# C++ constructors and destructors in the binary.
31+
# See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor
32+
#
33+
.data
34+
.align 4
35+
36+
/* CRT_LEGACY_WORKAROUND is only defined when building this file
37+
* for the C library. This forces __dso_handle to be exported by
38+
* it. This is only required to ensure binary compatibility with
39+
* old NDK application machine code that contains reference to
40+
* the symbol, but do not have a proper definition for it.
41+
*
42+
* These binaries cannot call their destructorson dlclose(), but
43+
* at least they will not fail to load.
44+
*
45+
* When this file is built for the NDK, CRT_LEGACY_WORKAROUND
46+
* should never be defined.
47+
*/
48+
49+
#ifndef CRT_LEGACY_WORKAROUND
50+
.hidden __dso_handle
51+
#endif
52+
53+
.globl __dso_handle
54+
__dso_handle:
55+
.long __dso_handle
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (C) 2010 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+
# The __dso_handle global variable is used by static
30+
# C++ constructors and destructors in the binary.
31+
# See http://www.codesourcery.com/public/cxx-abi/abi.html#dso-dtor
32+
#
33+
.data
34+
.align 4
35+
.hidden __dso_handle
36+
.globl __dso_handle
37+
__dso_handle:
38+
.long __dso_handle

0 commit comments

Comments
 (0)