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:
Mike Hommey 2024-05-23 06:48:36 +00:00
parent 67a6fa45ec
commit 3adb098477
3 changed files with 31 additions and 153 deletions

View file

@ -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,27 +248,13 @@ 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__
const void* __wrap___gnu_Unwind_Find_exidx(void* pc, int* pcount) {
RefPtr<LibHandle> handle = ElfLoader::Singleton.GetHandleByPtr(pc);
@ -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++;

View file

@ -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;

View file

@ -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 <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 */