android bionic linker debug enable

Keywords: Linker Android git

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

Posted by vandalite on Fri, 14 Dec 2018 21:57:04 -0800