Loader ld in Linker-android
In order to debug this kind of base library, it is useless to use printf, which is a general term.
android debugging is basically output through logcat, of course, you can open a file to write, but that will cause a variety of privilege problems, prevent you from crashing!
Linker's debug relies mainly on printf
It is divided into three files.
#define PRINT(x...) _PRINTVF(-1, x)
#define INFO(x...) _PRINTVF(0, x)
#define TRACE(x...) _PRINTVF(1, x)
It can be output in two directions.
#if LINKER_DEBUG_TO_LOG
#define _PRINTVF(v, x...) \
do { \
if (g_ld_debug_verbosity > (v)) __libc_format_log(5-(v), "linker", x); \
} while (0)
#else /* !LINKER_DEBUG_TO_LOG */
#define _PRINTVF(v, x...) \
do { \
if (g_ld_debug_verbosity > (v)) { __libc_format_fd(1, x); write(1, "\n", 1); } \
} while (0)
#endif /* !LINKER_DEBUG_TO_LOG */
If LINKER_DEBUG_TO_LOG is a non-zero value, output to logcat or stdout
But android's stdout is basically redirected to / dev/null, so it's basically invalid here.
Notice that there's another variable in it.
The value g_ld_debug_verbosity is declared in linker_debug.h and defined in linker.cpp.
The default value is 0, which means that only the macro PRINT is output by default.
Linker initializes this g_ld_debug_verbosity value with the following code
// Get a few environment variables.
const char* LD_DEBUG = getenv("LD_DEBUG");
if (LD_DEBUG != nullptr) {
g_ld_debug_verbosity = atoi(LD_DEBUG);
}
This setting should be required
Here add aosp/system/core/rootdir/init.environ.rc.in
Then brush system mimge
It's obviously too expensive.
The simplest way is to use the following modifications, push /system/bin/linker /system/bin/link64 directly to the machine, requiring adb reboot to restart the machine for the change to take effect
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 573bcf8..be1d175 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1595,6 +1595,8 @@ static int open_library(android_namespace_t* ns,
const char* name, soinfo *needed_by,
off64_t* file_offset, std::string* realpath) {
TRACE("[ opening %s ]", name);
+ INFO("[ opening %s ]", name);
+ PRINT("[ opening %s ]", name);
// If the name contains a slash, we should attempt to open it directly and not search the paths.
if (strchr(name, '/') != nullptr) {
@@ -4216,6 +4218,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
if (LD_DEBUG != nullptr) {
g_ld_debug_verbosity = atoi(LD_DEBUG);
}
+ g_ld_debug_verbosity = 1;
#if defined(__LP64__)
INFO("[ Android dynamic linker (64-bit) ]");
Note that it is not recommended to change g_ld_debug_verbosity to 2, so that the machine will not start for a long time because it has been printing.
This means that TRACE debugging is basically impossible without redirecting to files.
init is a program that does not use linker
Subprocesses using linker execute u linker_init
Maybe static links are not needed?
readelf -h objfile
type | Need linker |
---|---|
DYN (Shared Object File) | yes |
EXEC (Executable File) | no |