Home | History | Annotate | only in /development/ndk/platforms
Up to higher level directory
NameDateSize
android-12/06-Dec-2017
android-13/06-Dec-2017
android-14/06-Dec-2017
android-15/06-Dec-2017
android-16/06-Dec-2017
android-17/06-Dec-2017
android-18/06-Dec-2017
android-19/06-Dec-2017
android-21/06-Dec-2017
android-22/06-Dec-2017
android-23/06-Dec-2017
android-24/06-Dec-2017
android-26/06-Dec-2017
android-9/06-Dec-2017
README.CRT.TXT06-Dec-201710.8K

README.CRT.TXT

      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 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