README.TXT
1 Android Dynamic Linker Design Notes
2 ===================================
3
4 Introduction:
5 -------------
6
7 This document provides several notes related to the design of the Android
8 dynamic linker.
9
10
11 Prelinking:
12 -----------
13
14 System libraries in Android are internally prelinked, which means that
15 any internal relocations within them are stripped from the corresponding
16 shared object, in order to reduce size and speed up loading.
17
18 Such libraries can only be loaded at the very specific virtual memory address
19 they have been prelinked to (during the build process). The list of prelinked
20 system libraries and their corresponding virtual memory address is found in
21 the file:
22
23 build/core/prelink-linux-<arch>.map
24
25 It should be updated each time a new system library is added to the
26 system.
27
28 The prelink step happens at build time, and uses the 'soslim' and 'apriori'
29 tools:
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
38 By default, these tools are only used to remove internal symbols from
39 libraries, though they have been designed to allow more aggressive
40 optimizations (e.g. 'global' prelinking and symbol stripping, which
41 prevent replacing individual system libraries though).
42
43 You can disable prelinking at build time by modifying your Android.mk with
44 a line like:
45
46 LOCAL_PRELINK_MODULE := false
47
48
49 Initialization and Termination functions:
50 -----------------------------------------
51
52 The Unix Sys V Binary Interface standard states that an
53 executable can have the following entries in its .dynamic
54 section:
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 stored 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 in the executable or any of its libraries.
91
92 Note: this is generally stored in a .preinit_array section
93
94 DT_PREINIT_ARRAYSZ
95 The size of DT_PREINIT_ARRAY
96
97 If both a DT_INIT and DT_INITARRAY entry are present, the DT_INIT
98 function must be called before the DT_INITARRAY functions.
99
100 Consequently, the DT_FINIARRAY must be parsed in reverse order before
101 the DT_FINI function, if both are available.
102
103 Note that the implementation of static C++ constructors is very
104 much processor dependent, and may use different ELF sections.
105
106 On the ARM (see "C++ ABI for ARM" document), the static constructors
107 must be called explicitly from the DT_INIT_ARRAY, and each one of them
108 shall register a destructor by calling the special __eabi_atexit()
109 function (provided by the C library). The DT_FINI_ARRAY is not used
110 by static C++ destructors.
111
112 On x86, the lists of constructors and destructors are placed in special
113 sections named ".ctors" and ".dtors", and the DT_INIT / DT_FINI functions
114 are in charge of calling them explicitly.
115
116
117 Debugging:
118 ----------
119
120 It is possible to enable debug output in the dynamic linker. To do so,
121 follow these steps:
122
123 1/ Modify the line in Android.mk that says:
124
125 LOCAL_CFLAGS += -DLINKER_DEBUG=0
126
127 Into the following:
128
129 LOCAL_CFLAGS += -DLINKER_DEBUG=1
130
131 2/ Force-rebuild the dynamic linker:
132
133 cd bionic/linker
134 mm -B
135
136 3/ Rebuild a new system image.
137
138 You can increase the verbosity of debug traces by defining the DEBUG
139 environment variable to a numeric value from 0 to 2. This will only
140 affect new processes being launched.
141
142 By default, traces are sent to logcat, with the "linker" tag. You can
143 change this to go to stdout instead by setting the definition of
144 LINKER_DEBUG_TO_LOG to 0 in "linker_debug.h".
145