diff options
author | Elliott Hughes <enh@google.com> | 2019-05-09 15:56:39 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2019-05-09 22:12:17 -0700 |
commit | 90f96b9f483b8effefd6a6fe8a8f0562f616837e (patch) | |
tree | 79681d6b86ab2c8c211bf5e39f91a1bf73d6bc95 /linker/linker_main.cpp | |
parent | 81063190064ce84aee135a52b16f53cce50b950a (diff) |
linker: support ldd(1)-like behavior via --list.
Given that we have both linker and linker64, I didn't really want to have
to have ldd and ldd64, so this change just adds the --list option to the
linkers and a shell script wrapper "ldd" that calls the appropriate
linker behind the scenes.
Test: adb shell linker --list `which app_process32`
Test: adb shell linker64 --list `which date`
Test: adb shell ldd `which app_process32`
Test: adb shell ldd `which date`
Change-Id: I33494bda1cc3cafee54e091f97c0f2ae52d1f74b
Diffstat (limited to 'linker/linker_main.cpp')
-rw-r--r-- | linker/linker_main.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index f6e4f6774..f5760231a 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -117,6 +117,7 @@ soinfo* solist_get_vdso() { return vdso; } +bool g_is_ldd; int g_ld_debug_verbosity; static std::vector<std::string> g_ld_preload_names; @@ -397,7 +398,7 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load "\"%s\": error: Android 5.0 and later only support " "position-independent executables (-fPIE).\n", g_argv[0]); - exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid). @@ -660,22 +661,29 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) // linker's _start. const char* exe_to_load = nullptr; if (getauxval(AT_ENTRY) == reinterpret_cast<uintptr_t>(&_start)) { - if (args.argc <= 1 || !strcmp(args.argv[1], "--help")) { + 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 program [arguments...]\n" - " %s path.zip!/program [arguments...]\n" + "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", + "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(0); + _exit(EXIT_SUCCESS); + } else { + exe_to_load = args.argv[1]; + __libc_shared_globals()->initial_linker_arg_count = 1; } - exe_to_load = args.argv[1]; - __libc_shared_globals()->initial_linker_arg_count = 1; } // store argc/argv/envp to use them for calling constructors @@ -693,6 +701,8 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) ElfW(Addr) start_address = linker_main(args, exe_to_load); + 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. |