android linker重定位后初始化

Posted malihom

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android linker重定位后初始化相关的知识,希望对你有一定的参考价值。

Linker重定位后初始化

linker重定位后,进行一系列初始化工作,这个阶段,linker已经可以引用外部的符号和全局变量了。

源码

/*
 * This code is called after the linker has linked itself and fixed its own
 * GOT. It is safe to make references to externs and other non-local data at
 * this point. The compiler sometimes moves GOT references earlier in a
 * function, so avoid inlining this function (http://b/80503879).
 */
static ElfW(Addr) __attribute__((noinline))
__linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) {
  // Finish initializing the main thread.
  __libc_init_main_thread_late();//继续main thread初始化

  //设置gnu_relro段为read-only
  // We didn't protect the linker's RELRO pages in link_image because we
  // couldn't make system calls on x86 at that point, but we can now...
  if (!tmp_linker_so.protect_relro()) __linker_cannot_link(args.argv[0]);

  // And we can set VMA name for the bss section now
  set_bss_vma_name(&tmp_linker_so);//为bss段的vma设置名字

  // Initialize the linker's static libc's globals
  __libc_init_globals();//调用libc.so的external函数,对libc一些全局变量进行初始化,主要是vdso的初始化

  // Initialize the linker's own global variables
  tmp_linker_so.call_constructors();//linker DSO内部的初始化,执行.init,.init_array等section的初始化函数

  // When the linker is run directly rather than acting as PT_INTERP, parse
  // arguments and determine the executable to load. When it's instead acting
  // as PT_INTERP, AT_ENTRY will refer to the loaded executable rather than the
  // linker's _start.
  const char* exe_to_load = nullptr;
  if (getauxval(AT_ENTRY) == reinterpret_cast<uintptr_t>(&_start)) {
    if (args.argc == 3 && !strcmp(args.argv[1], "--list")) {
      // We're being asked to behave like ldd(1).
      g_is_ldd = true;
      exe_to_load = args.argv[2];
    } else if (args.argc <= 1 || !strcmp(args.argv[1], "--help")) {
      async_safe_format_fd(STDOUT_FILENO,
         "Usage: %s [--list] PROGRAM [ARGS-FOR-PROGRAM...]\\n"
         "       %s [--list] path.zip!/PROGRAM [ARGS-FOR-PROGRAM...]\\n"
         "\\n"
         "A helper program for linking dynamic executables. Typically, the kernel loads\\n"
         "this program because it's the PT_INTERP of a dynamic executable.\\n"
         "\\n"
         "This program can also be run directly to load and run a dynamic executable. The\\n"
         "executable can be inside a zip file if it's stored uncompressed and at a\\n"
         "page-aligned offset.\\n"
         "\\n"
         "The --list option gives behavior equivalent to ldd(1) on other systems.\\n",
         args.argv[0], args.argv[0]);
      _exit(EXIT_SUCCESS);
    } else {
      exe_to_load = args.argv[1];//执行文件的名字,例如app_process64
      __libc_shared_globals()->initial_linker_arg_count = 1;
    }
  }

  // store argc/argv/envp to use them for calling constructors
  g_argc = args.argc - __libc_shared_globals()->initial_linker_arg_count;
  g_argv = args.argv + __libc_shared_globals()->initial_linker_arg_count;
  g_envp = args.envp;
  __libc_shared_globals()->init_progname = g_argv[0];//执行文件的名字,例如app_process64

  // Initialize static variables. Note that in order to
  // get correct libdl_info we need to call constructors
  // before get_libdl_info().
  sonext = solist = solinker = get_libdl_info(tmp_linker_so);//初始化进程的全局dl info
  g_default_namespace.add_soinfo(solinker);

  ElfW(Addr) start_address = linker_main(args, exe_to_load);//对进程的可执行文件进行一系列操作(例如:加载exe到用户空间,获取exe phdr, 对exe进行符号解释和重定位,初始化环境变量,系统属性等),然后返回可执行文件的入口地址,一般情况下,就是main函数

  if (g_is_ldd) _exit(EXIT_SUCCESS);

  INFO("[ Jumping to _start (%p)... ]", reinterpret_cast<void*>(start_address));

  // Return the address that the calling assembly stub should jump to.
  return start_address;
}

__linker_init_post_relocation函数,主要完成下列工作:

  1. 继续完成main thread的部分初始化工作;(详细参考:Linker和主线程初始化
  2. 完成libc DSO全局变量的初始化;
  3. 完成linker的内部的初始化;
  4. 执行linker_main,完成一系列,包括:属性初始化,exe加载、加载依赖,符号解释,重定位等等;(详细参考:Linker和Exe加载 : linker_main函数解释

以上是关于android linker重定位后初始化的主要内容,如果未能解决你的问题,请参考以下文章

android linker和主线程初始化

适当修改LIO-SAM_based_relocalization解决初始重定位显示错误

Android片段布局完成膨胀

UBOOT启动流程——向量表重定位命令处理——学习笔记

Android 逆向Android 进程注入工具开发 ( 注入代码分析 | 获取 linker 中的 dlopen 函数地址 并 通过 远程调用 执行该函数 )

在 Android 中使用片段时处理后按