forked from mirrors/gecko-dev
Bug 1898382 - Remove Android < 5.0 specific code from the linker. r=gsvelto
Also remove workarounds for older NDKs. Differential Revision: https://phabricator.services.mozilla.com/D211299
This commit is contained in:
parent
67a6fa45ec
commit
3adb098477
3 changed files with 31 additions and 153 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <dlfcn.h>
|
||||
#include <link.h>
|
||||
#include <optional>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -55,12 +56,6 @@ extern "C" MOZ_EXPORT const void* __gnu_Unwind_Find_exidx(void* pc, int* pcount)
|
|||
__attribute__((weak));
|
||||
#endif
|
||||
|
||||
/* Ideally we'd #include <link.h>, but that's a world of pain
|
||||
* Moreover, not all versions of android support it, so we need a weak
|
||||
* reference. */
|
||||
extern "C" MOZ_EXPORT int dl_iterate_phdr(dl_phdr_cb callback, void* data)
|
||||
__attribute__((weak));
|
||||
|
||||
/* Pointer to the PT_DYNAMIC section of the executable or library
|
||||
* containing this code. */
|
||||
extern "C" Elf::Dyn _DYNAMIC[];
|
||||
|
|
@ -246,7 +241,6 @@ int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data) {
|
|||
DlIteratePhdrHelper helper;
|
||||
AutoLock lock(&ElfLoader::Singleton.handlesMutex);
|
||||
|
||||
if (dl_iterate_phdr) {
|
||||
for (ElfLoader::LibHandleList::reverse_iterator it =
|
||||
ElfLoader::Singleton.handles.rbegin();
|
||||
it < ElfLoader::Singleton.handles.rend(); ++it) {
|
||||
|
|
@ -254,25 +248,11 @@ int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data) {
|
|||
if (!elf) {
|
||||
continue;
|
||||
}
|
||||
int ret = helper.fill_and_call(callback, (*it)->GetBase(),
|
||||
(*it)->GetPath(), data);
|
||||
int ret = helper.fill_and_call(callback, (*it)->GetBase(), (*it)->GetPath(),
|
||||
data);
|
||||
if (ret) return ret;
|
||||
}
|
||||
return dl_iterate_phdr(callback, data);
|
||||
}
|
||||
|
||||
/* For versions of Android that don't support dl_iterate_phdr (< 5.0),
|
||||
* we go through the debugger helper data, which is known to be racy, but
|
||||
* there's not much we can do about this :( . */
|
||||
if (!ElfLoader::Singleton.dbg) return -1;
|
||||
|
||||
for (ElfLoader::DebuggerHelper::iterator it =
|
||||
ElfLoader::Singleton.dbg.begin();
|
||||
it < ElfLoader::Singleton.dbg.end(); ++it) {
|
||||
int ret = helper.fill_and_call(callback, it->l_addr, it->l_name, data);
|
||||
if (ret) return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
|
|
@ -304,11 +284,6 @@ const char* LeafName(const char* path) {
|
|||
*/
|
||||
template <class Lambda>
|
||||
static bool RunWithSystemLinkerLock(Lambda&& aLambda) {
|
||||
if (!dl_iterate_phdr) {
|
||||
// No dl_iterate_phdr support.
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ANDROID)
|
||||
if (GetAndroidSDKVersion() < 23) {
|
||||
// dl_iterate_phdr is _not_ protected by a lock on Android < 23.
|
||||
|
|
@ -530,19 +505,6 @@ void ElfLoader::Init() {
|
|||
if (dladdr(_DYNAMIC, &info) != 0) {
|
||||
self_elf = LoadedElf::Create(info.dli_fname, info.dli_fbase);
|
||||
}
|
||||
#if defined(ANDROID)
|
||||
// On Android < 5.0, resolving weak symbols via dlsym doesn't work.
|
||||
// The weak symbols Gecko uses are in either libc or libm, so we
|
||||
// wrap those such that this linker does symbol resolution for them.
|
||||
if (GetAndroidSDKVersion() < 21) {
|
||||
if (dladdr(FunctionPtr(syscall), &info) != 0) {
|
||||
libc = LoadedElf::Create(info.dli_fname, info.dli_fbase);
|
||||
}
|
||||
if (dladdr(FunctionPtr<int (*)(double)>(isnan), &info) != 0) {
|
||||
libm = LoadedElf::Create(info.dli_fname, info.dli_fbase);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ElfLoader::~ElfLoader() {
|
||||
|
|
@ -554,10 +516,6 @@ ElfLoader::~ElfLoader() {
|
|||
|
||||
/* Release self_elf and libc */
|
||||
self_elf = nullptr;
|
||||
#if defined(ANDROID)
|
||||
libc = nullptr;
|
||||
libm = nullptr;
|
||||
#endif
|
||||
|
||||
AutoLock lock(&handlesMutex);
|
||||
/* Build up a list of all library handles with direct (external) references.
|
||||
|
|
@ -701,8 +659,7 @@ ElfLoader::DebuggerHelper::DebuggerHelper()
|
|||
|
||||
/* Finally, scan forward to find the last environment variable pointer and
|
||||
* thus the first auxiliary vector. */
|
||||
while (*scan++)
|
||||
;
|
||||
while (*scan++);
|
||||
|
||||
/* Some platforms have more NULLs here, so skip them if we encounter them */
|
||||
while (!*scan) scan++;
|
||||
|
|
|
|||
|
|
@ -34,13 +34,6 @@ typedef struct {
|
|||
#endif
|
||||
int __wrap_dladdr(const void* addr, Dl_info* info);
|
||||
|
||||
struct dl_phdr_info {
|
||||
Elf::Addr dlpi_addr;
|
||||
const char* dlpi_name;
|
||||
const Elf::Phdr* dlpi_phdr;
|
||||
Elf::Half dlpi_phnum;
|
||||
};
|
||||
|
||||
typedef int (*dl_phdr_cb)(struct dl_phdr_info*, size_t, void*);
|
||||
int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data);
|
||||
|
||||
|
|
@ -408,17 +401,6 @@ class ElfLoader : public SEGVHandler {
|
|||
* is used to resolve wrapped functions. */
|
||||
RefPtr<LibHandle> self_elf;
|
||||
|
||||
#if defined(ANDROID)
|
||||
/* System loader handle for the libc. This is used to resolve weak symbols
|
||||
* that some libcs contain that the Android linker won't dlsym(). Normally,
|
||||
* we wouldn't treat non-Android differently, but glibc uses versioned
|
||||
* symbols which this linker doesn't support. */
|
||||
RefPtr<LibHandle> libc;
|
||||
|
||||
/* And for libm. */
|
||||
RefPtr<LibHandle> libm;
|
||||
#endif
|
||||
|
||||
/* Bookkeeping */
|
||||
typedef std::vector<LibHandle*> LibHandleList;
|
||||
LibHandleList handles;
|
||||
|
|
|
|||
|
|
@ -7,21 +7,9 @@
|
|||
|
||||
#include "Utils.h"
|
||||
|
||||
/**
|
||||
* Android system headers have two different elf.h file. The one under linux/
|
||||
* is the most complete on older Android API versions without unified headers.
|
||||
*/
|
||||
#if defined(ANDROID) && __ANDROID_API__ < 21 && !defined(__ANDROID_API_L__)
|
||||
# include <linux/elf.h>
|
||||
#else
|
||||
# include <elf.h>
|
||||
#endif
|
||||
#include <elf.h>
|
||||
#include <endian.h>
|
||||
|
||||
#if defined(__ARM_EABI__) && !defined(PT_ARM_EXIDX)
|
||||
# define PT_ARM_EXIDX 0x70000001
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generic ELF macros for the target system
|
||||
*/
|
||||
|
|
@ -128,58 +116,6 @@
|
|||
# error Unknown ELF machine type
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Android system headers don't have all definitions
|
||||
*/
|
||||
#ifndef STN_UNDEF
|
||||
# define STN_UNDEF 0
|
||||
#endif
|
||||
#ifndef DT_INIT_ARRAY
|
||||
# define DT_INIT_ARRAY 25
|
||||
#endif
|
||||
#ifndef DT_FINI_ARRAY
|
||||
# define DT_FINI_ARRAY 26
|
||||
#endif
|
||||
#ifndef DT_INIT_ARRAYSZ
|
||||
# define DT_INIT_ARRAYSZ 27
|
||||
#endif
|
||||
#ifndef DT_FINI_ARRAYSZ
|
||||
# define DT_FINI_ARRAYSZ 28
|
||||
#endif
|
||||
#ifndef DT_RELACOUNT
|
||||
# define DT_RELACOUNT 0x6ffffff9
|
||||
#endif
|
||||
#ifndef DT_RELCOUNT
|
||||
# define DT_RELCOUNT 0x6ffffffa
|
||||
#endif
|
||||
#ifndef DT_VERSYM
|
||||
# define DT_VERSYM 0x6ffffff0
|
||||
#endif
|
||||
#ifndef DT_VERDEF
|
||||
# define DT_VERDEF 0x6ffffffc
|
||||
#endif
|
||||
#ifndef DT_VERDEFNUM
|
||||
# define DT_VERDEFNUM 0x6ffffffd
|
||||
#endif
|
||||
#ifndef DT_VERNEED
|
||||
# define DT_VERNEED 0x6ffffffe
|
||||
#endif
|
||||
#ifndef DT_VERNEEDNUM
|
||||
# define DT_VERNEEDNUM 0x6fffffff
|
||||
#endif
|
||||
#ifndef DT_FLAGS_1
|
||||
# define DT_FLAGS_1 0x6ffffffb
|
||||
#endif
|
||||
#ifndef DT_FLAGS
|
||||
# define DT_FLAGS 30
|
||||
#endif
|
||||
#ifndef DF_SYMBOLIC
|
||||
# define DF_SYMBOLIC 0x00000002
|
||||
#endif
|
||||
#ifndef DF_TEXTREL
|
||||
# define DF_TEXTREL 0x00000004
|
||||
#endif
|
||||
|
||||
namespace Elf {
|
||||
|
||||
/**
|
||||
|
|
@ -220,26 +156,29 @@ class Strtab : public UnsizedArray<const char> {
|
|||
/**
|
||||
* Helper class around Elf relocation.
|
||||
*/
|
||||
struct Rel : public Elf_(Rel) {
|
||||
/**
|
||||
* Returns the addend for the relocation, which is the value stored
|
||||
* at r_offset.
|
||||
struct Rel
|
||||
: public Elf_(Rel){/**
|
||||
* Returns the addend for the relocation, which is the
|
||||
* value stored at r_offset.
|
||||
*/
|
||||
Addr GetAddend(void* base) const {
|
||||
return *(reinterpret_cast<const Addr*>(reinterpret_cast<const char*>(base) +
|
||||
r_offset));
|
||||
}
|
||||
};
|
||||
Addr GetAddend(void* base)
|
||||
const {return *(reinterpret_cast<const Addr*>(
|
||||
reinterpret_cast<const char*>(base) + r_offset));
|
||||
} // namespace Elf
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Helper class around Elf relocation with addend.
|
||||
*/
|
||||
struct Rela : public Elf_(Rela) {
|
||||
/**
|
||||
struct Rela
|
||||
: public Elf_(Rela){/**
|
||||
* Returns the addend for the relocation.
|
||||
*/
|
||||
Addr GetAddend(void* base) const { return r_addend; }
|
||||
};
|
||||
Addr GetAddend(void* base) const {return r_addend;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
} /* namespace Elf */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue