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 <cstdlib>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <link.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
@ -55,12 +56,6 @@ extern "C" MOZ_EXPORT const void* __gnu_Unwind_Find_exidx(void* pc, int* pcount)
|
||||||
__attribute__((weak));
|
__attribute__((weak));
|
||||||
#endif
|
#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
|
/* Pointer to the PT_DYNAMIC section of the executable or library
|
||||||
* containing this code. */
|
* containing this code. */
|
||||||
extern "C" Elf::Dyn _DYNAMIC[];
|
extern "C" Elf::Dyn _DYNAMIC[];
|
||||||
|
|
@ -246,33 +241,18 @@ int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data) {
|
||||||
DlIteratePhdrHelper helper;
|
DlIteratePhdrHelper helper;
|
||||||
AutoLock lock(&ElfLoader::Singleton.handlesMutex);
|
AutoLock lock(&ElfLoader::Singleton.handlesMutex);
|
||||||
|
|
||||||
if (dl_iterate_phdr) {
|
for (ElfLoader::LibHandleList::reverse_iterator it =
|
||||||
for (ElfLoader::LibHandleList::reverse_iterator it =
|
ElfLoader::Singleton.handles.rbegin();
|
||||||
ElfLoader::Singleton.handles.rbegin();
|
it < ElfLoader::Singleton.handles.rend(); ++it) {
|
||||||
it < ElfLoader::Singleton.handles.rend(); ++it) {
|
BaseElf* elf = (*it)->AsBaseElf();
|
||||||
BaseElf* elf = (*it)->AsBaseElf();
|
if (!elf) {
|
||||||
if (!elf) {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int ret = helper.fill_and_call(callback, (*it)->GetBase(),
|
|
||||||
(*it)->GetPath(), data);
|
|
||||||
if (ret) return ret;
|
|
||||||
}
|
}
|
||||||
return dl_iterate_phdr(callback, data);
|
int ret = helper.fill_and_call(callback, (*it)->GetBase(), (*it)->GetPath(),
|
||||||
}
|
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;
|
if (ret) return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return dl_iterate_phdr(callback, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ARM_EABI__
|
#ifdef __ARM_EABI__
|
||||||
|
|
@ -304,11 +284,6 @@ const char* LeafName(const char* path) {
|
||||||
*/
|
*/
|
||||||
template <class Lambda>
|
template <class Lambda>
|
||||||
static bool RunWithSystemLinkerLock(Lambda&& aLambda) {
|
static bool RunWithSystemLinkerLock(Lambda&& aLambda) {
|
||||||
if (!dl_iterate_phdr) {
|
|
||||||
// No dl_iterate_phdr support.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(ANDROID)
|
#if defined(ANDROID)
|
||||||
if (GetAndroidSDKVersion() < 23) {
|
if (GetAndroidSDKVersion() < 23) {
|
||||||
// dl_iterate_phdr is _not_ protected by a lock on Android < 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) {
|
if (dladdr(_DYNAMIC, &info) != 0) {
|
||||||
self_elf = LoadedElf::Create(info.dli_fname, info.dli_fbase);
|
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() {
|
ElfLoader::~ElfLoader() {
|
||||||
|
|
@ -554,10 +516,6 @@ ElfLoader::~ElfLoader() {
|
||||||
|
|
||||||
/* Release self_elf and libc */
|
/* Release self_elf and libc */
|
||||||
self_elf = nullptr;
|
self_elf = nullptr;
|
||||||
#if defined(ANDROID)
|
|
||||||
libc = nullptr;
|
|
||||||
libm = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AutoLock lock(&handlesMutex);
|
AutoLock lock(&handlesMutex);
|
||||||
/* Build up a list of all library handles with direct (external) references.
|
/* 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
|
/* Finally, scan forward to find the last environment variable pointer and
|
||||||
* thus the first auxiliary vector. */
|
* thus the first auxiliary vector. */
|
||||||
while (*scan++)
|
while (*scan++);
|
||||||
;
|
|
||||||
|
|
||||||
/* Some platforms have more NULLs here, so skip them if we encounter them */
|
/* Some platforms have more NULLs here, so skip them if we encounter them */
|
||||||
while (!*scan) scan++;
|
while (!*scan) scan++;
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,6 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
int __wrap_dladdr(const void* addr, Dl_info* info);
|
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*);
|
typedef int (*dl_phdr_cb)(struct dl_phdr_info*, size_t, void*);
|
||||||
int __wrap_dl_iterate_phdr(dl_phdr_cb callback, void* data);
|
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. */
|
* is used to resolve wrapped functions. */
|
||||||
RefPtr<LibHandle> self_elf;
|
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 */
|
/* Bookkeeping */
|
||||||
typedef std::vector<LibHandle*> LibHandleList;
|
typedef std::vector<LibHandle*> LibHandleList;
|
||||||
LibHandleList handles;
|
LibHandleList handles;
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,9 @@
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
/**
|
#include <elf.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 <endian.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
|
* Generic ELF macros for the target system
|
||||||
*/
|
*/
|
||||||
|
|
@ -128,58 +116,6 @@
|
||||||
# error Unknown ELF machine type
|
# error Unknown ELF machine type
|
||||||
#endif
|
#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 {
|
namespace Elf {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -220,26 +156,29 @@ class Strtab : public UnsizedArray<const char> {
|
||||||
/**
|
/**
|
||||||
* Helper class around Elf relocation.
|
* Helper class around Elf relocation.
|
||||||
*/
|
*/
|
||||||
struct Rel : public Elf_(Rel) {
|
struct Rel
|
||||||
/**
|
: public Elf_(Rel){/**
|
||||||
* Returns the addend for the relocation, which is the value stored
|
* Returns the addend for the relocation, which is the
|
||||||
* at r_offset.
|
* value stored at r_offset.
|
||||||
*/
|
*/
|
||||||
Addr GetAddend(void* base) const {
|
Addr GetAddend(void* base)
|
||||||
return *(reinterpret_cast<const Addr*>(reinterpret_cast<const char*>(base) +
|
const {return *(reinterpret_cast<const Addr*>(
|
||||||
r_offset));
|
reinterpret_cast<const char*>(base) + r_offset));
|
||||||
}
|
} // namespace Elf
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class around Elf relocation with addend.
|
* Helper class around Elf relocation with addend.
|
||||||
*/
|
*/
|
||||||
struct Rela : public Elf_(Rela) {
|
struct Rela
|
||||||
/**
|
: public Elf_(Rela){/**
|
||||||
* Returns the addend for the relocation.
|
* Returns the addend for the relocation.
|
||||||
*/
|
*/
|
||||||
Addr GetAddend(void* base) const { return r_addend; }
|
Addr GetAddend(void* base) const {return r_addend;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
} /* namespace Elf */
|
} /* namespace Elf */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue