1Android 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 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 91 Note: this is generally stored 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 explicitly 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 explicitly. 114 115 116Debugging: 117---------- 118 119It is possible to enable debug output in the dynamic linker. To do so, 120follow these steps: 121 1221/ Modify the line in Android.mk that says: 123 124 LOCAL_CFLAGS += -DLINKER_DEBUG=0 125 126 Into the following: 127 128 LOCAL_CFLAGS += -DLINKER_DEBUG=1 129 1302/ Force-rebuild the dynamic linker: 131 132 cd bionic/linker 133 mm -B 134 1353/ Rebuild a new system image. 136 137You can increase the verbosity of debug traces by defining the DEBUG 138environment variable to a numeric value from 0 to 2. This will only 139affect new processes being launched. 140 141By default, traces are sent to logcat, with the "linker" tag. You can 142change this to go to stdout instead by setting the definition of 143LINKER_DEBUG_TO_LOG to 0 in "linker_debug.h". 144