Allow invoking the linker on an executable.

The executable can be inside a zip file using the same syntax used for
shared objects: path.zip!/libentry.so.

The linker currently requires an absolute path. This restriction could be
loosened, but it didn't seem important? If it allowed non-absolute paths,
we'd need to decide how to handle:
 - foo/bar      (relative to CWD?)
 - foo          (search PATH / LD_LIBRARY_PATH, or also relative to CWD?)
 - foo.zip!/bar (normalize_path() requires an absolute path)

The linker adjusts the argc/argv passed to main() and to constructor
functions to hide the initial linker argument, but doesn't adjust the auxv
vector or files like /proc/self/{exe,cmdline,auxv,stat}. Those files will
report that the kernel loaded the linker as an executable.

I think the linker_logger.cpp change guarding against (g_argv == NULL)
isn't actually necessary, but it seemed like a good idea given that I'm
delaying initialization of g_argv until after C++ constructors have run.

Bug: http://b/112050209
Test: bionic unit tests
Change-Id: I846faf98b16fd34218946f6167e8b451897debe5
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 0def359..5f76354 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -133,7 +133,9 @@
     __cxa_atexit(__libc_fini,structors->fini_array,nullptr);
   }
 
-  exit(slingshot(args.argc, args.argv, args.envp));
+  exit(slingshot(args.argc - __libc_shared_globals->initial_linker_arg_count,
+                 args.argv + __libc_shared_globals->initial_linker_arg_count,
+                 args.envp));
 }
 
 extern "C" uint32_t android_get_application_target_sdk_version();
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index eee33c9..8c00551 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -47,6 +47,11 @@
 // Globals shared between the dynamic linker and libc.so.
 struct libc_shared_globals {
   FdTable fd_table;
+
+  // When the linker is invoked on a binary (e.g. `linker64 /system/bin/date`),
+  // record the number of arguments passed to the linker itself rather than to
+  // the program it's loading. Typically 0, sometimes 1.
+  int initial_linker_arg_count;
 };
 
 __LIBC_HIDDEN__ extern libc_shared_globals* __libc_shared_globals;