summaryrefslogtreecommitdiff
path: root/mozglue/linker/ElfLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mozglue/linker/ElfLoader.cpp')
-rw-r--r--mozglue/linker/ElfLoader.cpp164
1 files changed, 1 insertions, 163 deletions
diff --git a/mozglue/linker/ElfLoader.cpp b/mozglue/linker/ElfLoader.cpp
index 76225d1e77..dd3d7daa8b 100644
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -18,23 +18,6 @@
#include "Logging.h"
#include <inttypes.h>
-#if defined(ANDROID)
-#include <sys/syscall.h>
-
-#include <android/api-level.h>
-#if __ANDROID_API__ < 8
-/* Android API < 8 doesn't provide sigaltstack */
-
-extern "C" {
-
-inline int sigaltstack(const stack_t *ss, stack_t *oss) {
- return syscall(__NR_sigaltstack, ss, oss);
-}
-
-} /* extern "C" */
-#endif /* __ANDROID_API__ */
-#endif /* ANDROID */
-
#ifdef __ARM_EABI__
extern "C" MOZ_EXPORT const void *
__gnu_Unwind_Find_exidx(void *pc, int *pcount) __attribute__((weak));
@@ -348,16 +331,6 @@ SystemElf::GetMappable() const
const char *path = GetPath();
if (!path)
return nullptr;
-#ifdef ANDROID
- /* On Android, if we don't have the full path, try in /system/lib */
- const char *name = LeafName(path);
- std::string systemPath;
- if (name == path) {
- systemPath = "/system/lib/";
- systemPath += path;
- path = systemPath.c_str();
- }
-#endif
return MappableFile::Create(path);
}
@@ -550,17 +523,9 @@ void
ElfLoader::Init()
{
Dl_info info;
- /* On Android < 4.1 can't reenter dl* functions. So when the library
- * containing this code is dlopen()ed, it can't call dladdr from a
- * static initializer. */
if (dladdr(_DYNAMIC, &info) != 0) {
self_elf = LoadedElf::Create(info.dli_fname, info.dli_fbase);
}
-#if defined(ANDROID)
- if (dladdr(FunctionPtr(syscall), &info) != 0) {
- libc = LoadedElf::Create(info.dli_fname, info.dli_fbase);
- }
-#endif
}
ElfLoader::~ElfLoader()
@@ -573,9 +538,6 @@ ElfLoader::~ElfLoader()
/* Release self_elf and libc */
self_elf = nullptr;
-#if defined(ANDROID)
- libc = nullptr;
-#endif
/* Build up a list of all library handles with direct (external) references.
* We actually skip system library handles because we want to keep at least
@@ -962,88 +924,6 @@ ElfLoader::DebuggerHelper::Remove(ElfLoader::link_map *map)
dbg->r_brk();
}
-#if defined(ANDROID)
-/* As some system libraries may be calling signal() or sigaction() to
- * set a SIGSEGV handler, effectively breaking MappableSeekableZStream,
- * or worse, restore our SIGSEGV handler with wrong flags (which using
- * signal() will do), we want to hook into the system's sigaction() to
- * replace it with our own wrapper instead, so that our handler is never
- * replaced. We used to only do that with libraries this linker loads,
- * but it turns out at least one system library does call signal() and
- * breaks us (libsc-a3xx.so on the Samsung Galaxy S4).
- * As libc's signal (bsd_signal/sysv_signal, really) calls sigaction
- * under the hood, instead of calling the signal system call directly,
- * we only need to hook sigaction. This is true for both bionic and
- * glibc.
- */
-
-/* libc's sigaction */
-extern "C" int
-sigaction(int signum, const struct sigaction *act,
- struct sigaction *oldact);
-
-/* Simple reimplementation of sigaction. This is roughly equivalent
- * to the assembly that comes in bionic, but not quite equivalent to
- * glibc's implementation, so we only use this on Android. */
-int
-sys_sigaction(int signum, const struct sigaction *act,
- struct sigaction *oldact)
-{
- return syscall(__NR_sigaction, signum, act, oldact);
-}
-
-/* Replace the first instructions of the given function with a jump
- * to the given new function. */
-template <typename T>
-static bool
-Divert(T func, T new_func)
-{
- void *ptr = FunctionPtr(func);
- uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
-
-#if defined(__i386__)
- // A 32-bit jump is a 5 bytes instruction.
- EnsureWritable w(ptr, 5);
- *reinterpret_cast<unsigned char *>(addr) = 0xe9; // jmp
- *reinterpret_cast<intptr_t *>(addr + 1) =
- reinterpret_cast<uintptr_t>(new_func) - addr - 5; // target displacement
- return true;
-#elif defined(__arm__)
- const unsigned char trampoline[] = {
- // .thumb
- 0x46, 0x04, // nop
- 0x78, 0x47, // bx pc
- 0x46, 0x04, // nop
- // .arm
- 0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc, #-4]
- // .word <new_func>
- };
- const unsigned char *start;
- if (addr & 0x01) {
- /* Function is thumb, the actual address of the code is without the
- * least significant bit. */
- addr--;
- /* The arm part of the trampoline needs to be 32-bit aligned */
- if (addr & 0x02)
- start = trampoline;
- else
- start = trampoline + 2;
- } else {
- /* Function is arm, we only need the arm part of the trampoline */
- start = trampoline + 6;
- }
-
- size_t len = sizeof(trampoline) - (start - trampoline);
- EnsureWritable w(reinterpret_cast<void *>(addr), len + sizeof(void *));
- memcpy(reinterpret_cast<void *>(addr), start, len);
- *reinterpret_cast<void **>(addr + len) = FunctionPtr(new_func);
- cacheflush(addr, addr + len + sizeof(void *), 0);
- return true;
-#else
- return false;
-#endif
-}
-#else
#define sys_sigaction sigaction
template <typename T>
static bool
@@ -1051,7 +931,7 @@ Divert(T func, T new_func)
{
return false;
}
-#endif
+
namespace {
@@ -1144,48 +1024,6 @@ SEGVHandler::FinishInitialization()
sigaction_func libc_sigaction;
-#if defined(ANDROID)
- /* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library
- * (libsigchain) for ART. That wrapper kind of does the same trick as we
- * do, so we need extra care in handling it.
- * - Divert the libc's sigaction, assuming the LD_PRELOADed library uses
- * it under the hood (which is more or less true according to the source
- * of that library, since it's doing a lookup in RTLD_NEXT)
- * - With the LD_PRELOADed library in place, all calls to sigaction from
- * from system libraries will go to the LD_PRELOADed library.
- * - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction.
- * - The calls to sigaction from libraries faulty.lib loads are sent to
- * the LD_PRELOADed library.
- * In practice, for signal handling, this means:
- * - The signal handler registered to the kernel is ours.
- * - Our handler redispatches to the LD_PRELOADed library's if there's a
- * segfault we don't handle.
- * - The LD_PRELOADed library redispatches according to whatever system
- * library or faulty.lib-loaded library set with sigaction.
- *
- * When there is no sigaction wrapper in place:
- * - Divert the libc's sigaction.
- * - Calls to sigaction from system library and faulty.lib-loaded libraries
- * all go to the libc's sigaction, which end up in our __wrap_sigaction.
- * - The signal handler registered to the kernel is ours.
- * - Our handler redispatches according to whatever system library or
- * faulty.lib-loaded library set with sigaction.
- */
- void *libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY);
- if (libc) {
- /*
- * Lollipop bionic only has a small trampoline in sigaction, with the real
- * work happening in __sigaction. Divert there instead of sigaction if it exists.
- * Bug 1154803
- */
- libc_sigaction = reinterpret_cast<sigaction_func>(dlsym(libc, "__sigaction"));
-
- if (!libc_sigaction) {
- libc_sigaction =
- reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction"));
- }
- } else
-#endif
{
libc_sigaction = sigaction;
}