am d4e9f076
: Merge "Clean up linker architecture macros."
* commit 'd4e9f076d621dcf6450acba178e65d63c076ae6e': Clean up linker architecture macros.
This commit is contained in:
commit
c98827e70a
@ -79,29 +79,8 @@ static td_thrhandle_t gEventMsgHandle;
|
|||||||
static int
|
static int
|
||||||
_event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
|
_event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
|
||||||
{
|
{
|
||||||
void * pc;
|
#if defined(__arm__)
|
||||||
|
void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
|
||||||
#ifdef __i386__
|
|
||||||
/* Get the eip from offset 12*4 = 48 as defined in the struct
|
|
||||||
* user_regs_struct in user_32.h
|
|
||||||
*/
|
|
||||||
pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
|
|
||||||
/* FIXME - pc is a non-decremented breakpoint address, hence the
|
|
||||||
* addition of 1 on test. This seems to work for the thread hook
|
|
||||||
* function in libc.so but should be properly fixed.
|
|
||||||
*/
|
|
||||||
if (pc == ((int)bkpt_addr + 1)) {
|
|
||||||
/* The hook function takes the id of the new thread as it's first
|
|
||||||
* param, so grab it from ecx at offset 4 in struct user_regs_struct
|
|
||||||
* (using fastcall convention for x86)
|
|
||||||
*/
|
|
||||||
gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
|
|
||||||
gEventMsgHandle.tid = gEventMsgHandle.pid;
|
|
||||||
return 0x42;
|
|
||||||
}
|
|
||||||
#elif defined(__arm__)
|
|
||||||
pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL);
|
|
||||||
|
|
||||||
if (pc == bkpt_addr) {
|
if (pc == bkpt_addr) {
|
||||||
// The hook function takes the id of the new thread as it's first param,
|
// The hook function takes the id of the new thread as it's first param,
|
||||||
// so grab it from r0.
|
// so grab it from r0.
|
||||||
@ -109,8 +88,23 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr)
|
|||||||
gEventMsgHandle.tid = gEventMsgHandle.pid;
|
gEventMsgHandle.tid = gEventMsgHandle.pid;
|
||||||
return 0x42;
|
return 0x42;
|
||||||
}
|
}
|
||||||
|
#elif defined(__i386__)
|
||||||
|
// Get the eip from offset 12*4 = 48 as defined in the struct
|
||||||
|
// user_regs_struct in user_32.h
|
||||||
|
void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL);
|
||||||
|
// FIXME - pc is a non-decremented breakpoint address, hence the
|
||||||
|
// addition of 1 on test. This seems to work for the thread hook
|
||||||
|
// function in libc.so but should be properly fixed.
|
||||||
|
if (pc == ((int)bkpt_addr + 1)) {
|
||||||
|
// The hook function takes the id of the new thread as it's first
|
||||||
|
// param, so grab it from ecx at offset 4 in struct user_regs_struct
|
||||||
|
// (using fastcall convention for x86)
|
||||||
|
gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL);
|
||||||
|
gEventMsgHandle.tid = gEventMsgHandle.pid;
|
||||||
|
return 0x42;
|
||||||
|
}
|
||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL);
|
void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL);
|
||||||
if (pc == bkpt_addr) {
|
if (pc == bkpt_addr) {
|
||||||
// The hook function takes the id of the new thread as it's first param,
|
// The hook function takes the id of the new thread as it's first param,
|
||||||
// so grab it from a0
|
// so grab it from a0
|
||||||
|
@ -33,11 +33,6 @@ LOCAL_CPPFLAGS += \
|
|||||||
# We need to access Bionic private headers in the linker.
|
# We need to access Bionic private headers in the linker.
|
||||||
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
|
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
|
||||||
|
|
||||||
# Make the target architecture available at compile time.
|
|
||||||
# TODO: do we really need this? why not just use __aarch64__, __arm__, __i386__, __mips__, __x86_64__?
|
|
||||||
uppercase_target_arch := $(shell tr '[:lower:]' '[:upper:]' <<< $(TARGET_ARCH))
|
|
||||||
LOCAL_CFLAGS += -DANDROID_$(uppercase_target_arch)_LINKER
|
|
||||||
|
|
||||||
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
|
ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),x86_64))
|
||||||
LOCAL_MODULE := linker64
|
LOCAL_MODULE := linker64
|
||||||
else
|
else
|
||||||
|
@ -235,7 +235,7 @@ void debuggerd_signal_handler(int n, siginfo_t* info, void*) {
|
|||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
case SIGPIPE:
|
case SIGPIPE:
|
||||||
#ifdef SIGSTKFLT
|
#if defined(SIGSTKFLT)
|
||||||
case SIGSTKFLT:
|
case SIGSTKFLT:
|
||||||
#endif
|
#endif
|
||||||
(void) tgkill(getpid(), gettid(), n);
|
(void) tgkill(getpid(), gettid(), n);
|
||||||
|
@ -143,12 +143,12 @@ int dlclose(void* handle) {
|
|||||||
return do_dlclose(reinterpret_cast<soinfo*>(handle));
|
return do_dlclose(reinterpret_cast<soinfo*>(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888 8888888
|
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888 8888888
|
||||||
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012 3456789
|
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012 3456789
|
||||||
#define ANDROID_LIBDL_STRTAB \
|
#define ANDROID_LIBDL_STRTAB \
|
||||||
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0dl_iterate_phdr\0dl_unwind_find_exidx\0"
|
"dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0dl_iterate_phdr\0dl_unwind_find_exidx\0"
|
||||||
#elif defined(ANDROID_MIPS_LINKER) || defined(ANDROID_X86_LINKER) || defined(ANDROID_X86_64_LINKER)
|
#elif defined(__i386__) || defined(__mips__) || defined(__x86_64__)
|
||||||
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667
|
// 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667
|
||||||
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890
|
// 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890
|
||||||
#define ANDROID_LIBDL_STRTAB \
|
#define ANDROID_LIBDL_STRTAB \
|
||||||
@ -195,7 +195,7 @@ static Elf_Sym gLibDlSymtab[] = {
|
|||||||
ELF_SYM_INITIALIZER(29, &dladdr, 1),
|
ELF_SYM_INITIALIZER(29, &dladdr, 1),
|
||||||
ELF_SYM_INITIALIZER(36, &android_update_LD_LIBRARY_PATH, 1),
|
ELF_SYM_INITIALIZER(36, &android_update_LD_LIBRARY_PATH, 1),
|
||||||
ELF_SYM_INITIALIZER(67, &dl_iterate_phdr, 1),
|
ELF_SYM_INITIALIZER(67, &dl_iterate_phdr, 1),
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
ELF_SYM_INITIALIZER(83, &dl_unwind_find_exidx, 1),
|
ELF_SYM_INITIALIZER(83, &dl_unwind_find_exidx, 1),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -219,7 +219,7 @@ static Elf_Sym gLibDlSymtab[] = {
|
|||||||
// Note that adding any new symbols here requires
|
// Note that adding any new symbols here requires
|
||||||
// stubbing them out in libdl.
|
// stubbing them out in libdl.
|
||||||
static unsigned gLibDlBuckets[1] = { 1 };
|
static unsigned gLibDlBuckets[1] = { 1 };
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
static unsigned gLibDlChains[9] = { 0, 2, 3, 4, 5, 6, 7, 8, 0 };
|
static unsigned gLibDlChains[9] = { 0, 2, 3, 4, 5, 6, 7, 8, 0 };
|
||||||
#else
|
#else
|
||||||
static unsigned gLibDlChains[8] = { 0, 2, 3, 4, 5, 6, 7, 0 };
|
static unsigned gLibDlChains[8] = { 0, 2, 3, 4, 5, 6, 7, 0 };
|
||||||
@ -257,7 +257,7 @@ soinfo libdl_info = {
|
|||||||
.bucket = gLibDlBuckets,
|
.bucket = gLibDlBuckets,
|
||||||
.chain = gLibDlChains,
|
.chain = gLibDlChains,
|
||||||
|
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if defined(USE_RELA)
|
||||||
.plt_rela = 0,
|
.plt_rela = 0,
|
||||||
.plt_rela_count = 0,
|
.plt_rela_count = 0,
|
||||||
.rela = 0,
|
.rela = 0,
|
||||||
@ -282,10 +282,10 @@ soinfo libdl_info = {
|
|||||||
.init_func = 0,
|
.init_func = 0,
|
||||||
.fini_func = 0,
|
.fini_func = 0,
|
||||||
|
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
.ARM_exidx = 0,
|
.ARM_exidx = 0,
|
||||||
.ARM_exidx_count = 0,
|
.ARM_exidx_count = 0,
|
||||||
#elif defined(ANDROID_MIPS_LINKER)
|
#elif defined(__mips__)
|
||||||
.mips_symtabno = 0,
|
.mips_symtabno = 0,
|
||||||
.mips_local_gotno = 0,
|
.mips_local_gotno = 0,
|
||||||
.mips_gotsym = 0,
|
.mips_gotsym = 0,
|
||||||
|
@ -90,7 +90,7 @@ static soinfo* sonext = &libdl_info;
|
|||||||
static soinfo* somain; /* main process, always the one after libdl_info */
|
static soinfo* somain; /* main process, always the one after libdl_info */
|
||||||
|
|
||||||
static const char* const gSoPaths[] = {
|
static const char* const gSoPaths[] = {
|
||||||
#if __LP64__
|
#if defined(__LP64__)
|
||||||
"/vendor/lib64",
|
"/vendor/lib64",
|
||||||
"/system/lib64",
|
"/system/lib64",
|
||||||
#else
|
#else
|
||||||
@ -393,7 +393,7 @@ static void parse_LD_PRELOAD(const char* path) {
|
|||||||
gLdPreloadsBuffer, sizeof(gLdPreloadsBuffer), LDPRELOAD_MAX);
|
gLdPreloadsBuffer, sizeof(gLdPreloadsBuffer), LDPRELOAD_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID_ARM_LINKER
|
#if defined(__arm__)
|
||||||
|
|
||||||
/* For a given PC, find the .so that it belongs to.
|
/* For a given PC, find the .so that it belongs to.
|
||||||
* Returns the base address of the .ARM.exidx section
|
* Returns the base address of the .ARM.exidx section
|
||||||
@ -521,7 +521,7 @@ static Elf_Sym* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, soi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Look for symbols in the local scope (the object who is
|
/* Look for symbols in the local scope (the object who is
|
||||||
* searching). This happens with C++ templates on i386 for some
|
* searching). This happens with C++ templates on x86 for some
|
||||||
* reason.
|
* reason.
|
||||||
*
|
*
|
||||||
* Notes on weak symbols:
|
* Notes on weak symbols:
|
||||||
@ -845,7 +845,7 @@ int do_dlclose(soinfo* si) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if defined(USE_RELA)
|
||||||
static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* needed[]) {
|
static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* needed[]) {
|
||||||
Elf_Sym* symtab = si->symtab;
|
Elf_Sym* symtab = si->symtab;
|
||||||
const char* strtab = si->strtab;
|
const char* strtab = si->strtab;
|
||||||
@ -888,16 +888,17 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo*
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
case R_X86_64_JUMP_SLOT:
|
case R_X86_64_JUMP_SLOT:
|
||||||
case R_X86_64_GLOB_DAT:
|
case R_X86_64_GLOB_DAT:
|
||||||
case R_X86_64_32:
|
case R_X86_64_32:
|
||||||
case R_X86_64_RELATIVE:
|
case R_X86_64_RELATIVE:
|
||||||
// No need to do anything.
|
// No need to do anything.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
sym_addr = reloc;
|
sym_addr = reloc;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DL_ERR("unknown weak reloc type %d @ %p (%d)", type, rela, (int) (rela - start));
|
DL_ERR("unknown weak reloc type %d @ %p (%d)", type, rela, (int) (rela - start));
|
||||||
@ -913,6 +914,7 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo*
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#if defined(__x86_64__)
|
||||||
case R_X86_64_JUMP_SLOT:
|
case R_X86_64_JUMP_SLOT:
|
||||||
count_relocation(kRelocAbsolute);
|
count_relocation(kRelocAbsolute);
|
||||||
MARK(rela->r_offset);
|
MARK(rela->r_offset);
|
||||||
@ -938,7 +940,6 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo*
|
|||||||
static_cast<size_t>(si->base));
|
static_cast<size_t>(si->base));
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) = si->base + rela->r_addend;
|
*reinterpret_cast<Elf_Addr*>(reloc) = si->base + rela->r_addend;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_X86_64_32:
|
case R_X86_64_32:
|
||||||
count_relocation(kRelocRelative);
|
count_relocation(kRelocRelative);
|
||||||
MARK(rela->r_offset);
|
MARK(rela->r_offset);
|
||||||
@ -946,7 +947,6 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo*
|
|||||||
static_cast<size_t>(sym_addr), sym_name);
|
static_cast<size_t>(sym_addr), sym_name);
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr + rela->r_addend;
|
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr + rela->r_addend;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_X86_64_64:
|
case R_X86_64_64:
|
||||||
count_relocation(kRelocRelative);
|
count_relocation(kRelocRelative);
|
||||||
MARK(rela->r_offset);
|
MARK(rela->r_offset);
|
||||||
@ -954,7 +954,6 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo*
|
|||||||
static_cast<size_t>(sym_addr), sym_name);
|
static_cast<size_t>(sym_addr), sym_name);
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr + rela->r_addend;
|
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr + rela->r_addend;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
count_relocation(kRelocRelative);
|
count_relocation(kRelocRelative);
|
||||||
MARK(rela->r_offset);
|
MARK(rela->r_offset);
|
||||||
@ -963,6 +962,7 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo*
|
|||||||
static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
|
static_cast<size_t>(sym_addr), static_cast<size_t>(reloc), sym_name);
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr + rela->r_addend - reloc;
|
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr + rela->r_addend - reloc;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
DL_ERR("unknown reloc type %d @ %p (%d)", type, rela, (int) (rela - start));
|
DL_ERR("unknown reloc type %d @ %p (%d)", type, rela, (int) (rela - start));
|
||||||
return -1;
|
return -1;
|
||||||
@ -996,8 +996,7 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count,
|
|||||||
sym_name = (char *)(strtab + symtab[sym].st_name);
|
sym_name = (char *)(strtab + symtab[sym].st_name);
|
||||||
s = soinfo_do_lookup(si, sym_name, &lsi, needed);
|
s = soinfo_do_lookup(si, sym_name, &lsi, needed);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
/* We only allow an undefined symbol if this is a weak
|
// We only allow an undefined symbol if this is a weak reference...
|
||||||
reference.. */
|
|
||||||
s = &symtab[sym];
|
s = &symtab[sym];
|
||||||
if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
|
if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
|
||||||
DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, si->name);
|
DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, si->name);
|
||||||
@ -1018,48 +1017,39 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
case R_ARM_JUMP_SLOT:
|
case R_ARM_JUMP_SLOT:
|
||||||
case R_ARM_GLOB_DAT:
|
case R_ARM_GLOB_DAT:
|
||||||
case R_ARM_ABS32:
|
case R_ARM_ABS32:
|
||||||
case R_ARM_RELATIVE: /* Don't care. */
|
case R_ARM_RELATIVE: /* Don't care. */
|
||||||
#elif defined(ANDROID_X86_LINKER)
|
// sym_addr was initialized to be zero above or relocation
|
||||||
|
// code below does not care about value of sym_addr.
|
||||||
|
// No need to do anything.
|
||||||
|
break;
|
||||||
|
#elif defined(__i386__)
|
||||||
case R_386_JMP_SLOT:
|
case R_386_JMP_SLOT:
|
||||||
case R_386_GLOB_DAT:
|
case R_386_GLOB_DAT:
|
||||||
case R_386_32:
|
case R_386_32:
|
||||||
case R_386_RELATIVE: /* Don't care. */
|
case R_386_RELATIVE: /* Don't care. */
|
||||||
#endif /* ANDROID_*_LINKER */
|
// sym_addr was initialized to be zero above or relocation
|
||||||
/* sym_addr was initialized to be zero above or relocation
|
// code below does not care about value of sym_addr.
|
||||||
code below does not care about value of sym_addr.
|
// No need to do anything.
|
||||||
No need to do anything. */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(ANDROID_X86_LINKER)
|
|
||||||
case R_386_PC32:
|
case R_386_PC32:
|
||||||
sym_addr = reloc;
|
sym_addr = reloc;
|
||||||
break;
|
break;
|
||||||
#endif /* ANDROID_X86_LINKER */
|
#endif
|
||||||
|
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
case R_ARM_COPY:
|
case R_ARM_COPY:
|
||||||
/* Fall through. Can't really copy if weak symbol is
|
// Fall through. Can't really copy if weak symbol is not found at run-time.
|
||||||
not found in run-time. */
|
#endif
|
||||||
#endif /* ANDROID_ARM_LINKER */
|
|
||||||
default:
|
default:
|
||||||
DL_ERR("unknown weak reloc type %d @ %p (%d)",
|
DL_ERR("unknown weak reloc type %d @ %p (%d)", type, rel, (int) (rel - start));
|
||||||
type, rel, (int) (rel - start));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* We got a definition. */
|
// We got a definition.
|
||||||
#if 0
|
|
||||||
if ((base == 0) && (si->base != 0)) {
|
|
||||||
/* linking from libraries to main image is bad */
|
|
||||||
DL_ERR("cannot locate \"%s\"...",
|
|
||||||
strtab + symtab[sym].st_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
sym_addr = static_cast<Elf_Addr>(s->st_value + lsi->load_bias);
|
sym_addr = static_cast<Elf_Addr>(s->st_value + lsi->load_bias);
|
||||||
}
|
}
|
||||||
count_relocation(kRelocSymbol);
|
count_relocation(kRelocSymbol);
|
||||||
@ -1067,11 +1057,8 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count,
|
|||||||
s = NULL;
|
s = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: This is ugly. Split up the relocations by arch into
|
|
||||||
* different files.
|
|
||||||
*/
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
case R_ARM_JUMP_SLOT:
|
case R_ARM_JUMP_SLOT:
|
||||||
count_relocation(kRelocAbsolute);
|
count_relocation(kRelocAbsolute);
|
||||||
MARK(rel->r_offset);
|
MARK(rel->r_offset);
|
||||||
@ -1097,68 +1084,6 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count,
|
|||||||
reloc, sym_addr, rel->r_offset, sym_name);
|
reloc, sym_addr, rel->r_offset, sym_name);
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) += sym_addr - rel->r_offset;
|
*reinterpret_cast<Elf_Addr*>(reloc) += sym_addr - rel->r_offset;
|
||||||
break;
|
break;
|
||||||
#elif defined(ANDROID_X86_LINKER)
|
|
||||||
case R_386_JMP_SLOT:
|
|
||||||
count_relocation(kRelocAbsolute);
|
|
||||||
MARK(rel->r_offset);
|
|
||||||
TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name);
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr;
|
|
||||||
break;
|
|
||||||
case R_386_GLOB_DAT:
|
|
||||||
count_relocation(kRelocAbsolute);
|
|
||||||
MARK(rel->r_offset);
|
|
||||||
TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name);
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr;
|
|
||||||
break;
|
|
||||||
#elif defined(ANDROID_MIPS_LINKER)
|
|
||||||
case R_MIPS_REL32:
|
|
||||||
count_relocation(kRelocAbsolute);
|
|
||||||
MARK(rel->r_offset);
|
|
||||||
TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x %s",
|
|
||||||
reloc, sym_addr, (sym_name) ? sym_name : "*SECTIONHDR*");
|
|
||||||
if (s) {
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) += sym_addr;
|
|
||||||
} else {
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) += si->base;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif /* ANDROID_*_LINKER */
|
|
||||||
|
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
|
||||||
case R_ARM_RELATIVE:
|
|
||||||
#elif defined(ANDROID_X86_LINKER)
|
|
||||||
case R_386_RELATIVE:
|
|
||||||
#endif /* ANDROID_*_LINKER */
|
|
||||||
count_relocation(kRelocRelative);
|
|
||||||
MARK(rel->r_offset);
|
|
||||||
if (sym) {
|
|
||||||
DL_ERR("odd RELATIVE form...");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
TRACE_TYPE(RELO, "RELO RELATIVE %p <- +%p",
|
|
||||||
reinterpret_cast<void*>(reloc), reinterpret_cast<void*>(si->base));
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) += si->base;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(ANDROID_X86_LINKER)
|
|
||||||
case R_386_32:
|
|
||||||
count_relocation(kRelocRelative);
|
|
||||||
MARK(rel->r_offset);
|
|
||||||
|
|
||||||
TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name);
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) += sym_addr;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_386_PC32:
|
|
||||||
count_relocation(kRelocRelative);
|
|
||||||
MARK(rel->r_offset);
|
|
||||||
TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s",
|
|
||||||
reloc, (sym_addr - reloc), sym_addr, reloc, sym_name);
|
|
||||||
*reinterpret_cast<Elf_Addr*>(reloc) += (sym_addr - reloc);
|
|
||||||
break;
|
|
||||||
#endif /* ANDROID_X86_LINKER */
|
|
||||||
|
|
||||||
#ifdef ANDROID_ARM_LINKER
|
|
||||||
case R_ARM_COPY:
|
case R_ARM_COPY:
|
||||||
if ((si->flags & FLAG_EXE) == 0) {
|
if ((si->flags & FLAG_EXE) == 0) {
|
||||||
/*
|
/*
|
||||||
@ -1201,11 +1126,64 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* ANDROID_ARM_LINKER */
|
#elif defined(__i386__)
|
||||||
|
case R_386_JMP_SLOT:
|
||||||
|
count_relocation(kRelocAbsolute);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name);
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr;
|
||||||
|
break;
|
||||||
|
case R_386_GLOB_DAT:
|
||||||
|
count_relocation(kRelocAbsolute);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name);
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) = sym_addr;
|
||||||
|
break;
|
||||||
|
case R_386_32:
|
||||||
|
count_relocation(kRelocRelative);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "RELO R_386_32 %08x <- +%08x %s", reloc, sym_addr, sym_name);
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) += sym_addr;
|
||||||
|
break;
|
||||||
|
case R_386_PC32:
|
||||||
|
count_relocation(kRelocRelative);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "RELO R_386_PC32 %08x <- +%08x (%08x - %08x) %s",
|
||||||
|
reloc, (sym_addr - reloc), sym_addr, reloc, sym_name);
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) += (sym_addr - reloc);
|
||||||
|
break;
|
||||||
|
#elif defined(__mips__)
|
||||||
|
case R_MIPS_REL32:
|
||||||
|
count_relocation(kRelocAbsolute);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "RELO REL32 %08x <- %08x %s",
|
||||||
|
reloc, sym_addr, (sym_name) ? sym_name : "*SECTIONHDR*");
|
||||||
|
if (s) {
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) += sym_addr;
|
||||||
|
} else {
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) += si->base;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
case R_ARM_RELATIVE:
|
||||||
|
#elif defined(__i386__)
|
||||||
|
case R_386_RELATIVE:
|
||||||
|
#endif
|
||||||
|
count_relocation(kRelocRelative);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
if (sym) {
|
||||||
|
DL_ERR("odd RELATIVE form...");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
TRACE_TYPE(RELO, "RELO RELATIVE %p <- +%p",
|
||||||
|
reinterpret_cast<void*>(reloc), reinterpret_cast<void*>(si->base));
|
||||||
|
*reinterpret_cast<Elf_Addr*>(reloc) += si->base;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DL_ERR("unknown reloc type %d @ %p (%d)",
|
DL_ERR("unknown reloc type %d @ %p (%d)", type, rel, (int) (rel - start));
|
||||||
type, rel, (int) (rel - start));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1213,7 +1191,7 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ANDROID_MIPS_LINKER
|
#if defined(__mips__)
|
||||||
static bool mips_relocate_got(soinfo* si, soinfo* needed[]) {
|
static bool mips_relocate_got(soinfo* si, soinfo* needed[]) {
|
||||||
unsigned* got = si->plt_got;
|
unsigned* got = si->plt_got;
|
||||||
if (got == NULL) {
|
if (got == NULL) {
|
||||||
@ -1458,7 +1436,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID_ARM_LINKER
|
#if defined(__arm__)
|
||||||
(void) phdr_table_get_arm_exidx(phdr, phnum, base,
|
(void) phdr_table_get_arm_exidx(phdr, phnum, base,
|
||||||
&si->ARM_exidx, &si->ARM_exidx_count);
|
&si->ARM_exidx, &si->ARM_exidx_count);
|
||||||
#endif
|
#endif
|
||||||
@ -1481,7 +1459,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
case DT_SYMTAB:
|
case DT_SYMTAB:
|
||||||
si->symtab = (Elf_Sym *) (base + d->d_un.d_ptr);
|
si->symtab = (Elf_Sym *) (base + d->d_un.d_ptr);
|
||||||
break;
|
break;
|
||||||
#if !defined(ANDROID_X86_64_LINKER)
|
#if !defined(__LP64__)
|
||||||
case DT_PLTREL:
|
case DT_PLTREL:
|
||||||
if (d->d_un.d_val != DT_REL) {
|
if (d->d_un.d_val != DT_REL) {
|
||||||
DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
|
DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
|
||||||
@ -1490,22 +1468,22 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case DT_JMPREL:
|
case DT_JMPREL:
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if defined(USE_RELA)
|
||||||
si->plt_rela = (Elf_Rela*) (base + d->d_un.d_ptr);
|
si->plt_rela = (Elf_Rela*) (base + d->d_un.d_ptr);
|
||||||
#else
|
#else
|
||||||
si->plt_rel = (Elf_Rel*) (base + d->d_un.d_ptr);
|
si->plt_rel = (Elf_Rel*) (base + d->d_un.d_ptr);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case DT_PLTRELSZ:
|
case DT_PLTRELSZ:
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if defined(USE_RELA)
|
||||||
si->plt_rela_count = d->d_un.d_val / sizeof(Elf_Rela);
|
si->plt_rela_count = d->d_un.d_val / sizeof(Elf_Rela);
|
||||||
#else
|
#else
|
||||||
si->plt_rel_count = d->d_un.d_val / sizeof(Elf_Rel);
|
si->plt_rel_count = d->d_un.d_val / sizeof(Elf_Rel);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
#if !defined(__LP64__)
|
||||||
case DT_PLTGOT:
|
case DT_PLTGOT:
|
||||||
#if !defined(ANDROID_X86_64_LINKER)
|
// Used by 32-bit MIPS.
|
||||||
/* Save this in case we decide to do lazy binding. We don't yet. */
|
|
||||||
si->plt_got = (unsigned *)(base + d->d_un.d_ptr);
|
si->plt_got = (unsigned *)(base + d->d_un.d_ptr);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -1516,7 +1494,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
d->d_un.d_val = reinterpret_cast<uintptr_t>(&_r_debug);
|
d->d_un.d_val = reinterpret_cast<uintptr_t>(&_r_debug);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if defined(USE_RELA)
|
||||||
case DT_RELA:
|
case DT_RELA:
|
||||||
si->rela = (Elf_Rela*) (base + d->d_un.d_ptr);
|
si->rela = (Elf_Rela*) (base + d->d_un.d_ptr);
|
||||||
break;
|
break;
|
||||||
@ -1589,7 +1567,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined(ANDROID_MIPS_LINKER)
|
#if defined(__mips__)
|
||||||
case DT_STRSZ:
|
case DT_STRSZ:
|
||||||
case DT_SYMENT:
|
case DT_SYMENT:
|
||||||
case DT_RELENT:
|
case DT_RELENT:
|
||||||
@ -1618,11 +1596,12 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
case DT_MIPS_GOTSYM:
|
case DT_MIPS_GOTSYM:
|
||||||
si->mips_gotsym = d->d_un.d_val;
|
si->mips_gotsym = d->d_un.d_val;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG("Unused DT entry: type 0x%08x arg 0x%08x", d->d_tag, d->d_un.d_val);
|
DEBUG("Unused DT entry: type %p arg %p",
|
||||||
|
reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val));
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1697,7 +1676,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if defined(USE_RELA)
|
||||||
if (si->plt_rela != NULL) {
|
if (si->plt_rela != NULL) {
|
||||||
DEBUG("[ relocating %s plt ]\n", si->name );
|
DEBUG("[ relocating %s plt ]\n", si->name );
|
||||||
if (soinfo_relocate_a(si, si->plt_rela, si->plt_rela_count, needed)) {
|
if (soinfo_relocate_a(si, si->plt_rela, si->plt_rela_count, needed)) {
|
||||||
@ -1725,7 +1704,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ANDROID_MIPS_LINKER
|
#if defined(__mips__)
|
||||||
if (!mips_relocate_got(si, needed)) {
|
if (!mips_relocate_got(si, needed)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1761,7 +1740,7 @@ static bool soinfo_link_image(soinfo* si) {
|
|||||||
* Also, it makes bionic more like glibc.
|
* Also, it makes bionic more like glibc.
|
||||||
*/
|
*/
|
||||||
static void add_vdso(KernelArgumentBlock& args UNUSED) {
|
static void add_vdso(KernelArgumentBlock& args UNUSED) {
|
||||||
#ifdef AT_SYSINFO_EHDR
|
#if defined(AT_SYSINFO_EHDR)
|
||||||
Elf_Ehdr* ehdr_vdso = reinterpret_cast<Elf_Ehdr*>(args.getauxval(AT_SYSINFO_EHDR));
|
Elf_Ehdr* ehdr_vdso = reinterpret_cast<Elf_Ehdr*>(args.getauxval(AT_SYSINFO_EHDR));
|
||||||
|
|
||||||
soinfo* si = soinfo_alloc("[vdso]");
|
soinfo* si = soinfo_alloc("[vdso]");
|
||||||
@ -1852,7 +1831,7 @@ static Elf_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf_Add
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static soinfo linker_soinfo;
|
static soinfo linker_soinfo;
|
||||||
#ifdef __LP64__
|
#if defined(__LP64__)
|
||||||
strlcpy(linker_soinfo.name, "/system/bin/linker64", sizeof(linker_soinfo.name));
|
strlcpy(linker_soinfo.name, "/system/bin/linker64", sizeof(linker_soinfo.name));
|
||||||
#else
|
#else
|
||||||
strlcpy(linker_soinfo.name, "/system/bin/linker", sizeof(linker_soinfo.name));
|
strlcpy(linker_soinfo.name, "/system/bin/linker", sizeof(linker_soinfo.name));
|
||||||
|
@ -97,6 +97,11 @@ struct r_debug {
|
|||||||
|
|
||||||
typedef void (*linker_function_t)();
|
typedef void (*linker_function_t)();
|
||||||
|
|
||||||
|
// Android uses REL for 32-bit but only uses RELA for 64-bit.
|
||||||
|
#if defined(__LP64__)
|
||||||
|
#define USE_RELA 1
|
||||||
|
#endif
|
||||||
|
|
||||||
struct soinfo {
|
struct soinfo {
|
||||||
public:
|
public:
|
||||||
char name[SOINFO_NAME_LEN];
|
char name[SOINFO_NAME_LEN];
|
||||||
@ -128,15 +133,19 @@ struct soinfo {
|
|||||||
unsigned* bucket;
|
unsigned* bucket;
|
||||||
unsigned* chain;
|
unsigned* chain;
|
||||||
|
|
||||||
#if defined(ANDROID_X86_64_LINKER)
|
#if !defined(__LP64__)
|
||||||
Elf_Rela *plt_rela;
|
// This is only used by 32-bit MIPS, but needs to be here for
|
||||||
|
// all 32-bit architectures to preserve binary compatibility.
|
||||||
|
unsigned* plt_got;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_RELA)
|
||||||
|
Elf_Rela* plt_rela;
|
||||||
size_t plt_rela_count;
|
size_t plt_rela_count;
|
||||||
|
|
||||||
Elf_Rela *rela;
|
Elf_Rela* rela;
|
||||||
size_t rela_count;
|
size_t rela_count;
|
||||||
#else
|
#else
|
||||||
unsigned* plt_got;
|
|
||||||
|
|
||||||
Elf_Rel* plt_rel;
|
Elf_Rel* plt_rel;
|
||||||
size_t plt_rel_count;
|
size_t plt_rel_count;
|
||||||
|
|
||||||
@ -155,11 +164,11 @@ struct soinfo {
|
|||||||
linker_function_t init_func;
|
linker_function_t init_func;
|
||||||
linker_function_t fini_func;
|
linker_function_t fini_func;
|
||||||
|
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(__arm__)
|
||||||
// ARM EABI section used for stack unwinding.
|
// ARM EABI section used for stack unwinding.
|
||||||
unsigned* ARM_exidx;
|
unsigned* ARM_exidx;
|
||||||
size_t ARM_exidx_count;
|
size_t ARM_exidx_count;
|
||||||
#elif defined(ANDROID_MIPS_LINKER)
|
#elif defined(__mips__)
|
||||||
unsigned mips_symtabno;
|
unsigned mips_symtabno;
|
||||||
unsigned mips_local_gotno;
|
unsigned mips_local_gotno;
|
||||||
unsigned mips_gotsym;
|
unsigned mips_gotsym;
|
||||||
|
@ -202,13 +202,13 @@ bool ElfReader::VerifyElfHeader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (header_.e_machine !=
|
if (header_.e_machine !=
|
||||||
#ifdef ANDROID_ARM_LINKER
|
#if defined(__arm__)
|
||||||
EM_ARM
|
EM_ARM
|
||||||
#elif defined(ANDROID_MIPS_LINKER)
|
#elif defined(__i386__)
|
||||||
EM_MIPS
|
|
||||||
#elif defined(ANDROID_X86_LINKER)
|
|
||||||
EM_386
|
EM_386
|
||||||
#elif defined(ANDROID_X86_64_LINKER)
|
#elif defined(__mips__)
|
||||||
|
EM_MIPS
|
||||||
|
#elif defined(__x86_64__)
|
||||||
EM_X86_64
|
EM_X86_64
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
@ -321,10 +321,6 @@ bool ElfReader::ReserveAddressSpace() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map all loadable segments in process' address space.
|
|
||||||
// This assumes you already called phdr_table_reserve_memory to
|
|
||||||
// reserve the address space range for the library.
|
|
||||||
// TODO: assert assumption.
|
|
||||||
bool ElfReader::LoadSegments() {
|
bool ElfReader::LoadSegments() {
|
||||||
for (size_t i = 0; i < phdr_num_; ++i) {
|
for (size_t i = 0; i < phdr_num_; ++i) {
|
||||||
const Elf_Phdr* phdr = &phdr_table_[i];
|
const Elf_Phdr* phdr = &phdr_table_[i];
|
||||||
@ -513,7 +509,7 @@ int phdr_table_protect_gnu_relro(const Elf_Phdr* phdr_table, size_t phdr_count,
|
|||||||
return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ);
|
return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID_ARM_LINKER
|
#if defined(__arm__)
|
||||||
|
|
||||||
# ifndef PT_ARM_EXIDX
|
# ifndef PT_ARM_EXIDX
|
||||||
# define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
|
# define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
|
||||||
@ -550,7 +546,7 @@ int phdr_table_get_arm_exidx(const Elf_Phdr* phdr_table, size_t phdr_count,
|
|||||||
*arm_exidx_count = 0;
|
*arm_exidx_count = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* ANDROID_ARM_LINKER */
|
#endif
|
||||||
|
|
||||||
/* Return the address and size of the ELF file's .dynamic section in memory,
|
/* Return the address and size of the ELF file's .dynamic section in memory,
|
||||||
* or NULL if missing.
|
* or NULL if missing.
|
||||||
|
@ -90,7 +90,7 @@ int phdr_table_unprotect_segments(const Elf_Phdr* phdr_table, size_t phdr_count,
|
|||||||
int phdr_table_protect_gnu_relro(const Elf_Phdr* phdr_table, size_t phdr_count, Elf_Addr load_bias);
|
int phdr_table_protect_gnu_relro(const Elf_Phdr* phdr_table, size_t phdr_count, Elf_Addr load_bias);
|
||||||
|
|
||||||
|
|
||||||
#ifdef ANDROID_ARM_LINKER
|
#if defined(__arm__)
|
||||||
int phdr_table_get_arm_exidx(const Elf_Phdr* phdr_table, size_t phdr_count, Elf_Addr load_bias,
|
int phdr_table_get_arm_exidx(const Elf_Phdr* phdr_table, size_t phdr_count, Elf_Addr load_bias,
|
||||||
Elf_Addr** arm_exidx, unsigned* arm_exidix_count);
|
Elf_Addr** arm_exidx, unsigned* arm_exidix_count);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user