Linker和Exe加载 : linker_main函数解释
linker main
执行的任务前,在linker
重定位,libc
初始化,主线程初始化等一些列操作完成后,进程的用户空间已经具备动态链接的能力,开始可以动态链接exe相关的依赖了。
linker main源码
static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load) {
ProtectedDataGuard guard;
#if TIMING
struct timeval t0, t1;
gettimeofday(&t0, 0);
#endif
// Sanitize the environment.
//主要是stdin等重定向到/dev/null,排除掉非法/不安全的环境变量
__libc_init_AT_SECURE(args.envp);
// Initialize system properties
//系统属性初始化
__system_properties_init(); // may use 'environ'
// Register the debuggerd signal handler.
linker_debuggerd_init();
g_linker_logger.ResetState();
// Get a few environment variables.
const char* LD_DEBUG = getenv("LD_DEBUG");
if (LD_DEBUG != nullptr) {
g_ld_debug_verbosity = atoi(LD_DEBUG);
}
#if defined(__LP64__)
INFO("[ Android dynamic linker (64-bit) ]");
#else
INFO("[ Android dynamic linker (32-bit) ]");
#endif
// These should have been sanitized by __libc_init_AT_SECURE, but the test
// doesn't cost us anything.
const char* ldpath_env = nullptr;
const char* ldpreload_env = nullptr;
if (!getauxval(AT_SECURE)) {
ldpath_env = getenv("LD_LIBRARY_PATH");
if (ldpath_env != nullptr) {
INFO("[ LD_LIBRARY_PATH set to \"%s\" ]", ldpath_env);
}
ldpreload_env = getenv("LD_PRELOAD");
if (ldpreload_env != nullptr) {
INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
}
}
//动态加载exe elf,由于exe实际上已经被内核加载了,这里仅仅是读取elf的信息和mmap文件到用户空间,而没有加载exe的依赖和进行相关的重定位
const ExecutableInfo exe_info = exe_to_load