Fix 'adb shell /system/bin/linker' crash
Bug: https://code.google.com/p/android/issues/detail?id=63174
Change-Id: I072290ea11109c07f277ad3dec7f44fcb7bf6aa6
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 4c76594..59b9938 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2221,6 +2221,8 @@
return 0;
}
+extern "C" void _start();
+
/*
* This is the entry point for the linker, called from begin.S. This
* method is responsible for fixing the linker's own relocations, and
@@ -2238,12 +2240,23 @@
KernelArgumentBlock args(raw_args);
ElfW(Addr) linker_addr = args.getauxval(AT_BASE);
+ ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
soinfo linker_so;
memset(&linker_so, 0, sizeof(soinfo));
+ // If the linker is not acting as PT_INTERP entry_point is equal to
+ // _start. Which means that the linker is running as an executable and
+ // already linked by PT_INTERP.
+ //
+ // This happens when user tries to run 'adb shell /system/bin/linker'
+ // see also https://code.google.com/p/android/issues/detail?id=63174
+ if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
+ __libc_fatal("This is %s, the helper program for shared library executables.\n", args.argv[0]);
+ }
+
strcpy(linker_so.name, "[dynamic linker]");
linker_so.base = linker_addr;
linker_so.size = phdr_table_get_load_size(phdr, elf_hdr->e_phnum);
@@ -2265,7 +2278,7 @@
_exit(EXIT_FAILURE);
}
- // lets properly initialize global variables
+ // Initialize the linker's own global variables
linker_so.CallConstructors();
// We have successfully fixed our own relocations. It's safe to run