blob: 0be9be45c89a43970a7ef50d580b9003e739e0cb [file] [log] [blame]
David 'Digit' Turner82156792009-05-18 14:37:41 +02001Android Dynamic Linker Design Notes
2===================================
3
4Introduction:
5-------------
6
7This document provides several notes related to the design of the Android
8dynamic linker.
9
10
11Prelinking:
12-----------
13
14System libraries in Android are internally prelinked, which means that
15any internal relocations within them are stripped from the corresponding
16shared object, in order to reduce size and speed up loading.
17
18Such libraries can only be loaded at the very specific virtual memory address
19they have been prelinked to (during the build process). The list of prelinked
20system libraries and their corresponding virtual memory address is found in
21the file:
22
23 build/core/prelink-linux-<arch>.map
24
25It should be updated each time a new system library is added to the
26system.
27
28The prelink step happens at build time, and uses the 'soslim' and 'apriori'
29tools:
30
31 - 'apriori' is the real prelink tool which removes relocations from the
32 shared object, however, it must be given a list of symbols to remove
33 from the file.
34
35 - 'soslim' is used to find symbols in an executable ELF file
36 and generate a list that can be passed to 'apriori'.
37
38By default, these tools are only used to remove internal symbols from
39libraries, though they have been designed to allow more aggressive
40optimizations (e.g. 'global' prelinking and symbol stripping, which
41prevent replacing individual system libraries though).
42
43You can disable prelinking at build time by modifying your Android.mk with
44a line like:
45
46 LOCAL_PRELINK_MODULE := false
47
48
49Initialization and Termination functions:
50-----------------------------------------
51
52The Unix Sys V Binary Interface standard states that an
53executable can have the following entries in its .dynamic
54section:
55
56 DT_INIT
57 Points to the address of an initialization function
58 that must be called when the file is loaded.
59
60 DT_INIT_ARRAY
61 Points to an array of function addresses that must be
62 called, in-order, to perform initialization. Some of
63 the entries in the array can be 0 or -1, and should
64 be ignored.
65
66 Note: this is generally stored in a .init_array section
67
68 DT_INIT_ARRAYSZ
69 The size of the DT_INITARRAY, if any
70
71 DT_FINI
72 Points to the address of a finalization function which
73 must be called when the file is unloaded or the process
74 terminated.
75
76 DT_FINI_ARRAY
77 Same as DT_INITARRAY but for finalizers. Note that the
78 functions must be called in reverse-order though
79
80 Note: this is generally stroed in a .fini_array section
81
82 DT_FINI_ARRAYSZ
83 Size of FT_FINIARRAY
84
85 DT_PREINIT_ARRAY
86 An array similar to DT_INIT_ARRAY which must *only* be
87 present in executables, not shared libraries, which contains
88 a list of functions that need to be called before any other
89 initialization function (i.e. DT_INIT and/or DT_INIT_ARRAY)
90
91 Note: this is generally stroed in a .preinit_array section
92
93 DT_PREINIT_ARRAYSZ
94 The size of DT_PREINIT_ARRAY
95
96If both a DT_INIT and DT_INITARRAY entry are present, the DT_INIT
97function must be called before the DT_INITARRAY functions.
98
99Consequently, the DT_FINIARRAY must be parsed in reverse order before
100the DT_FINI function, if both are available.
101
102Note that the implementation of static C++ constructors is very
103much processor dependent, and may use different ELF sections.
104
105On the ARM (see "C++ ABI for ARM" document), the static constructors
106must be called explicitely from the DT_INIT_ARRAY, and each one of them
107shall register a destructor by calling the special __eabi_atexit()
108function (provided by the C library). The DT_FINI_ARRAY is not used
109by static C++ destructors.
110
111On x86, the lists of constructors and destructors are placed in special
112sections named ".ctors" and ".dtors", and the DT_INIT / DT_FINI functions
113are in charge of calling them explicitely.
114
David 'Digit' Turner03eabfe2009-05-28 15:54:03 +0200115
116C Library Usage Restrictions:
117-----------------------------
118
119The dynamic linker executable (/system/bin/linker) is built using the
120static version of the C library (libc.a), in order to use various functions
121and system calls provided by it.
122
123However, it will normally, at runtime, map the shared library version
124of the C library (/system/lib/libc.so) as well in the process' address
125space. This means that:
126
127- any global variable defined by the C library will appear twice in
128 the process address space, at different addresses.
129
130- some functions will be duplicated too, though those that refer to
131 global variables will refer to distinct addresses.
132
133This can lead to subtle conflicts, typically for process-specific data that
134is managed through the kernel. A good example is the handling of the
135end of the data segment, which is normally done through the 'sbrk' or
136'brk' system call by the malloc implementation.
137
138If two similar, but distinct, malloc implementations run at the same time,
139and if each one thinks it exclusively manages some process settings, hideous
140corruption or crashes may occur.
141
142For this very reason, THE DYNAMIC LINKER CANNOT USE malloc()/free() !
143That's why it is linked to a special version of the C library that will
144abort when any of these functions (or calloc()/realloc()) is called.
145
146Moreover, it cannot use any C library feature that could use these
147indirectly. Experience as shown that this meant:
148
149- avoiding any FILE* - related stdio function (fopen, fread, fprintf, etc...)
150- avoiding snprintf() with any floating-point formatter ("%f", "%g")
151
152There are probably other cases that haven't been discovered yet, so the
153code needs to be very frugal in its use of the C library.
154
155This also explains why the linker's tracing macros are all disabled by
156default. Enabling them sometimes creates problems, depending on the process
157being loaded, so they should be considered an experimental feature for now.