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
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index f6e4f67..f576023 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -117,6 +117,7 @@
   return vdso;
 }
 
+bool g_is_ldd;
 int g_ld_debug_verbosity;
 
 static std::vector<std::string> g_ld_preload_names;
@@ -397,7 +398,7 @@
                          "\"%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'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 @@
 
   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.