4688279db5
Also make the errors more readable, since none of us seemed to know what they actually meant. The new style is still as verbose as the old, but that's probably necessary in the absence of chained exceptions in C. Here's what you'd see if you try to boot after removing libsurfaceflinger.so: 32267 32267 E AndroidRuntime: java.lang.UnsatisfiedLinkError: Cannot load library: (linker.c:1629, pid 32259) soinfo_link_image: could not load library "libsystem_server.so" needed by "libandroid_servers.so"; caused by (linker.c:1629, pid 32259) soinfo_link_image: could not load library "libsurfaceflinger.so" needed by "libsystem_server.so"; caused by (linker.c:709, pid 32259) load_library: library "libsurfaceflinger.so" not found This patch also fixes almost all of the compiler warnings. Change-Id: I64bb59aed6d4e039c15ea45be2367f319ef879f8
106 lines
3.2 KiB
Text
106 lines
3.2 KiB
Text
Android Dynamic Linker Design Notes
|
|
===================================
|
|
|
|
Introduction:
|
|
-------------
|
|
|
|
This document provides several notes related to the design of the Android
|
|
dynamic linker.
|
|
|
|
|
|
Initialization and Termination functions:
|
|
-----------------------------------------
|
|
|
|
The Unix Sys V Binary Interface standard states that an
|
|
executable can have the following entries in its .dynamic
|
|
section:
|
|
|
|
DT_INIT
|
|
Points to the address of an initialization function
|
|
that must be called when the file is loaded.
|
|
|
|
DT_INIT_ARRAY
|
|
Points to an array of function addresses that must be
|
|
called, in-order, to perform initialization. Some of
|
|
the entries in the array can be 0 or -1, and should
|
|
be ignored.
|
|
|
|
Note: this is generally stored in a .init_array section
|
|
|
|
DT_INIT_ARRAYSZ
|
|
The size of the DT_INITARRAY, if any
|
|
|
|
DT_FINI
|
|
Points to the address of a finalization function which
|
|
must be called when the file is unloaded or the process
|
|
terminated.
|
|
|
|
DT_FINI_ARRAY
|
|
Same as DT_INITARRAY but for finalizers. Note that the
|
|
functions must be called in reverse-order though
|
|
|
|
Note: this is generally stored in a .fini_array section
|
|
|
|
DT_FINI_ARRAYSZ
|
|
Size of FT_FINIARRAY
|
|
|
|
DT_PREINIT_ARRAY
|
|
An array similar to DT_INIT_ARRAY which must *only* be
|
|
present in executables, not shared libraries, which contains
|
|
a list of functions that need to be called before any other
|
|
initialization function (i.e. DT_INIT and/or DT_INIT_ARRAY)
|
|
in the executable or any of its libraries.
|
|
|
|
Note: this is generally stored in a .preinit_array section
|
|
|
|
DT_PREINIT_ARRAYSZ
|
|
The size of DT_PREINIT_ARRAY
|
|
|
|
If both a DT_INIT and DT_INITARRAY entry are present, the DT_INIT
|
|
function must be called before the DT_INITARRAY functions.
|
|
|
|
Consequently, the DT_FINIARRAY must be parsed in reverse order before
|
|
the DT_FINI function, if both are available.
|
|
|
|
Note that the implementation of static C++ constructors is very
|
|
much processor dependent, and may use different ELF sections.
|
|
|
|
On the ARM (see "C++ ABI for ARM" document), the static constructors
|
|
must be called explicitly from the DT_INIT_ARRAY, and each one of them
|
|
shall register a destructor by calling the special __eabi_atexit()
|
|
function (provided by the C library). The DT_FINI_ARRAY is not used
|
|
by static C++ destructors.
|
|
|
|
On x86, the lists of constructors and destructors are placed in special
|
|
sections named ".ctors" and ".dtors", and the DT_INIT / DT_FINI functions
|
|
are in charge of calling them explicitly.
|
|
|
|
|
|
Debugging:
|
|
----------
|
|
|
|
It is possible to enable debug output in the dynamic linker. To do so,
|
|
follow these steps:
|
|
|
|
1/ Modify the line in Android.mk that says:
|
|
|
|
LOCAL_CFLAGS += -DLINKER_DEBUG=0
|
|
|
|
Into the following:
|
|
|
|
LOCAL_CFLAGS += -DLINKER_DEBUG=1
|
|
|
|
2/ Force-rebuild the dynamic linker:
|
|
|
|
cd bionic/linker
|
|
mm -B
|
|
|
|
3/ Rebuild a new system image.
|
|
|
|
You can increase the verbosity of debug traces by defining the DEBUG
|
|
environment variable to a numeric value from 0 to 2. This will only
|
|
affect new processes being launched.
|
|
|
|
By default, traces are sent to logcat, with the "linker" tag. You can
|
|
change this to go to stdout instead by setting the definition of
|
|
LINKER_DEBUG_TO_LOG to 0 in "linker_debug.h".
|