From 4eeb1f12a8b63afc0d0ad4d466b16fbffb21cd5a Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 25 Oct 2013 17:38:02 -0700 Subject: [PATCH] Clean up linker architecture macros. We don't need our own architecture macros; the standard ones will do. This patch also fixes some __x86_64__ tests to be USE_RELA tests instead, because they're not actually x86_64-specific. I've cleaned up architecture-specific code slightly so where possible all the code corresponding to a particular architecture is together. This patch also fixes a bug in LP64 DT_PLTGOT handling, which should be an error rather than falling through into DT_DEBUG! There was another #ifdef bug where we'd only report unexpected DT_ entries on MIPS. Change-Id: Id1d04e372611f641c1aa278a18e379f28af9eaf5 --- libthread_db/libthread_db.c | 42 +++---- linker/Android.mk | 5 - linker/debugger.cpp | 2 +- linker/dlfcn.cpp | 14 +-- linker/linker.cpp | 215 ++++++++++++++++-------------------- linker/linker.h | 23 ++-- linker/linker_phdr.cpp | 18 ++- linker/linker_phdr.h | 2 +- 8 files changed, 147 insertions(+), 174 deletions(-) diff --git a/libthread_db/libthread_db.c b/libthread_db/libthread_db.c index bd78ae6ca..d89904515 100644 --- a/libthread_db/libthread_db.c +++ b/libthread_db/libthread_db.c @@ -79,29 +79,8 @@ static td_thrhandle_t gEventMsgHandle; static int _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr) { - void * pc; - -#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 defined(__arm__) + void* pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL); if (pc == bkpt_addr) { // The hook function takes the id of the new thread as it's first param, // so grab it from r0. @@ -109,8 +88,23 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr) gEventMsgHandle.tid = gEventMsgHandle.pid; 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__) - 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) { // The hook function takes the id of the new thread as it's first param, // so grab it from a0 diff --git a/linker/Android.mk b/linker/Android.mk index 82060abaf..f73d8d682 100644 --- a/linker/Android.mk +++ b/linker/Android.mk @@ -33,11 +33,6 @@ LOCAL_CPPFLAGS += \ # We need to access Bionic private headers in the linker. 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)) LOCAL_MODULE := linker64 else diff --git a/linker/debugger.cpp b/linker/debugger.cpp index c9475228b..29afab1f5 100644 --- a/linker/debugger.cpp +++ b/linker/debugger.cpp @@ -235,7 +235,7 @@ void debuggerd_signal_handler(int n, siginfo_t* info, void*) { case SIGABRT: case SIGFPE: case SIGPIPE: -#ifdef SIGSTKFLT +#if defined(SIGSTKFLT) case SIGSTKFLT: #endif (void) tgkill(getpid(), gettid(), n); diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp index d234787be..166efacf6 100644 --- a/linker/dlfcn.cpp +++ b/linker/dlfcn.cpp @@ -143,12 +143,12 @@ int dlclose(void* handle) { return do_dlclose(reinterpret_cast(handle)); } -#if defined(ANDROID_ARM_LINKER) +#if defined(__arm__) // 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888 8888888 // 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012 3456789 #define ANDROID_LIBDL_STRTAB \ "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 // 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890 #define ANDROID_LIBDL_STRTAB \ @@ -195,7 +195,7 @@ static Elf_Sym gLibDlSymtab[] = { ELF_SYM_INITIALIZER(29, &dladdr, 1), ELF_SYM_INITIALIZER(36, &android_update_LD_LIBRARY_PATH, 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), #endif }; @@ -219,7 +219,7 @@ static Elf_Sym gLibDlSymtab[] = { // Note that adding any new symbols here requires // stubbing them out in libdl. 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 }; #else static unsigned gLibDlChains[8] = { 0, 2, 3, 4, 5, 6, 7, 0 }; @@ -257,7 +257,7 @@ soinfo libdl_info = { .bucket = gLibDlBuckets, .chain = gLibDlChains, -#if defined(ANDROID_X86_64_LINKER) +#if defined(USE_RELA) .plt_rela = 0, .plt_rela_count = 0, .rela = 0, @@ -282,10 +282,10 @@ soinfo libdl_info = { .init_func = 0, .fini_func = 0, -#if defined(ANDROID_ARM_LINKER) +#if defined(__arm__) .ARM_exidx = 0, .ARM_exidx_count = 0, -#elif defined(ANDROID_MIPS_LINKER) +#elif defined(__mips__) .mips_symtabno = 0, .mips_local_gotno = 0, .mips_gotsym = 0, diff --git a/linker/linker.cpp b/linker/linker.cpp index 4f05c7a86..5a4f20f6b 100755 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -90,7 +90,7 @@ static soinfo* sonext = &libdl_info; static soinfo* somain; /* main process, always the one after libdl_info */ static const char* const gSoPaths[] = { -#if __LP64__ +#if defined(__LP64__) "/vendor/lib64", "/system/lib64", #else @@ -393,7 +393,7 @@ static void parse_LD_PRELOAD(const char* path) { gLdPreloadsBuffer, sizeof(gLdPreloadsBuffer), LDPRELOAD_MAX); } -#ifdef ANDROID_ARM_LINKER +#if defined(__arm__) /* For a given PC, find the .so that it belongs to. * 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 - * searching). This happens with C++ templates on i386 for some + * searching). This happens with C++ templates on x86 for some * reason. * * Notes on weak symbols: @@ -845,7 +845,7 @@ int do_dlclose(soinfo* si) { 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[]) { Elf_Sym* symtab = si->symtab; const char* strtab = si->strtab; @@ -888,16 +888,17 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* */ switch (type) { +#if defined(__x86_64__) case R_X86_64_JUMP_SLOT: case R_X86_64_GLOB_DAT: case R_X86_64_32: case R_X86_64_RELATIVE: // No need to do anything. break; - case R_X86_64_PC32: sym_addr = reloc; break; +#endif default: 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) { +#if defined(__x86_64__) case R_X86_64_JUMP_SLOT: count_relocation(kRelocAbsolute); MARK(rela->r_offset); @@ -938,7 +940,6 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* static_cast(si->base)); *reinterpret_cast(reloc) = si->base + rela->r_addend; break; - case R_X86_64_32: count_relocation(kRelocRelative); MARK(rela->r_offset); @@ -946,7 +947,6 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* static_cast(sym_addr), sym_name); *reinterpret_cast(reloc) = sym_addr + rela->r_addend; break; - case R_X86_64_64: count_relocation(kRelocRelative); MARK(rela->r_offset); @@ -954,7 +954,6 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* static_cast(sym_addr), sym_name); *reinterpret_cast(reloc) = sym_addr + rela->r_addend; break; - case R_X86_64_PC32: count_relocation(kRelocRelative); MARK(rela->r_offset); @@ -963,6 +962,7 @@ static int soinfo_relocate_a(soinfo* si, Elf_Rela* rela, unsigned count, soinfo* static_cast(sym_addr), static_cast(reloc), sym_name); *reinterpret_cast(reloc) = sym_addr + rela->r_addend - reloc; break; +#endif default: DL_ERR("unknown reloc type %d @ %p (%d)", type, rela, (int) (rela - start)); 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); s = soinfo_do_lookup(si, sym_name, &lsi, needed); if (s == NULL) { - /* We only allow an undefined symbol if this is a weak - reference.. */ + // We only allow an undefined symbol if this is a weak reference... s = &symtab[sym]; if (ELF_ST_BIND(s->st_info) != STB_WEAK) { 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) { -#if defined(ANDROID_ARM_LINKER) +#if defined(__arm__) case R_ARM_JUMP_SLOT: case R_ARM_GLOB_DAT: case R_ARM_ABS32: 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_GLOB_DAT: case R_386_32: case R_386_RELATIVE: /* Don't care. */ -#endif /* ANDROID_*_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. */ + // 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; - -#if defined(ANDROID_X86_LINKER) case R_386_PC32: sym_addr = reloc; break; -#endif /* ANDROID_X86_LINKER */ +#endif -#if defined(ANDROID_ARM_LINKER) +#if defined(__arm__) case R_ARM_COPY: - /* Fall through. Can't really copy if weak symbol is - not found in run-time. */ -#endif /* ANDROID_ARM_LINKER */ + // Fall through. Can't really copy if weak symbol is not found at run-time. +#endif default: - DL_ERR("unknown weak reloc type %d @ %p (%d)", - type, rel, (int) (rel - start)); + DL_ERR("unknown weak reloc type %d @ %p (%d)", type, rel, (int) (rel - start)); return -1; } } else { - /* 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 + // We got a definition. sym_addr = static_cast(s->st_value + lsi->load_bias); } count_relocation(kRelocSymbol); @@ -1067,11 +1057,8 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count, s = NULL; } -/* TODO: This is ugly. Split up the relocations by arch into - * different files. - */ switch (type) { -#if defined(ANDROID_ARM_LINKER) +#if defined(__arm__) case R_ARM_JUMP_SLOT: count_relocation(kRelocAbsolute); 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); *reinterpret_cast(reloc) += sym_addr - rel->r_offset; 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(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(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(reloc) += sym_addr; - } else { - *reinterpret_cast(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(reloc), reinterpret_cast(si->base)); - *reinterpret_cast(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(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(reloc) += (sym_addr - reloc); - break; -#endif /* ANDROID_X86_LINKER */ - -#ifdef ANDROID_ARM_LINKER case R_ARM_COPY: if ((si->flags & FLAG_EXE) == 0) { /* @@ -1201,11 +1126,64 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count, return -1; } 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(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(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(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(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(reloc) += sym_addr; + } else { + *reinterpret_cast(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(reloc), reinterpret_cast(si->base)); + *reinterpret_cast(reloc) += si->base; + break; default: - DL_ERR("unknown reloc type %d @ %p (%d)", - type, rel, (int) (rel - start)); + DL_ERR("unknown reloc type %d @ %p (%d)", type, rel, (int) (rel - start)); return -1; } } @@ -1213,7 +1191,7 @@ static int soinfo_relocate(soinfo* si, Elf_Rel* rel, unsigned count, } #endif -#ifdef ANDROID_MIPS_LINKER +#if defined(__mips__) static bool mips_relocate_got(soinfo* si, soinfo* needed[]) { unsigned* got = si->plt_got; 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, &si->ARM_exidx, &si->ARM_exidx_count); #endif @@ -1481,7 +1459,7 @@ static bool soinfo_link_image(soinfo* si) { case DT_SYMTAB: si->symtab = (Elf_Sym *) (base + d->d_un.d_ptr); break; -#if !defined(ANDROID_X86_64_LINKER) +#if !defined(__LP64__) case DT_PLTREL: if (d->d_un.d_val != DT_REL) { DL_ERR("unsupported DT_RELA in \"%s\"", si->name); @@ -1490,22 +1468,22 @@ static bool soinfo_link_image(soinfo* si) { break; #endif case DT_JMPREL: -#if defined(ANDROID_X86_64_LINKER) +#if defined(USE_RELA) si->plt_rela = (Elf_Rela*) (base + d->d_un.d_ptr); #else si->plt_rel = (Elf_Rel*) (base + d->d_un.d_ptr); #endif break; 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); #else si->plt_rel_count = d->d_un.d_val / sizeof(Elf_Rel); #endif break; +#if !defined(__LP64__) case DT_PLTGOT: -#if !defined(ANDROID_X86_64_LINKER) - /* Save this in case we decide to do lazy binding. We don't yet. */ + // Used by 32-bit MIPS. si->plt_got = (unsigned *)(base + d->d_un.d_ptr); break; #endif @@ -1516,7 +1494,7 @@ static bool soinfo_link_image(soinfo* si) { d->d_un.d_val = reinterpret_cast(&_r_debug); } break; -#if defined(ANDROID_X86_64_LINKER) +#if defined(USE_RELA) case DT_RELA: si->rela = (Elf_Rela*) (base + d->d_un.d_ptr); break; @@ -1589,7 +1567,7 @@ static bool soinfo_link_image(soinfo* si) { } break; #endif -#if defined(ANDROID_MIPS_LINKER) +#if defined(__mips__) case DT_STRSZ: case DT_SYMENT: case DT_RELENT: @@ -1618,11 +1596,12 @@ static bool soinfo_link_image(soinfo* si) { case DT_MIPS_GOTSYM: si->mips_gotsym = d->d_un.d_val; break; +#endif 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(d->d_tag), reinterpret_cast(d->d_un.d_val)); 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) { DEBUG("[ relocating %s plt ]\n", si->name ); 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 -#ifdef ANDROID_MIPS_LINKER +#if defined(__mips__) if (!mips_relocate_got(si, needed)) { return false; } @@ -1761,7 +1740,7 @@ static bool soinfo_link_image(soinfo* si) { * Also, it makes bionic more like glibc. */ static void add_vdso(KernelArgumentBlock& args UNUSED) { -#ifdef AT_SYSINFO_EHDR +#if defined(AT_SYSINFO_EHDR) Elf_Ehdr* ehdr_vdso = reinterpret_cast(args.getauxval(AT_SYSINFO_EHDR)); soinfo* si = soinfo_alloc("[vdso]"); @@ -1852,7 +1831,7 @@ static Elf_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf_Add */ { static soinfo linker_soinfo; -#ifdef __LP64__ +#if defined(__LP64__) strlcpy(linker_soinfo.name, "/system/bin/linker64", sizeof(linker_soinfo.name)); #else strlcpy(linker_soinfo.name, "/system/bin/linker", sizeof(linker_soinfo.name)); diff --git a/linker/linker.h b/linker/linker.h index c5202c90a..4ba354d8f 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -97,6 +97,11 @@ struct r_debug { 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 { public: char name[SOINFO_NAME_LEN]; @@ -128,15 +133,19 @@ struct soinfo { unsigned* bucket; unsigned* chain; -#if defined(ANDROID_X86_64_LINKER) - Elf_Rela *plt_rela; +#if !defined(__LP64__) + // 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; - Elf_Rela *rela; + Elf_Rela* rela; size_t rela_count; #else - unsigned* plt_got; - Elf_Rel* plt_rel; size_t plt_rel_count; @@ -155,11 +164,11 @@ struct soinfo { linker_function_t init_func; linker_function_t fini_func; -#if defined(ANDROID_ARM_LINKER) +#if defined(__arm__) // ARM EABI section used for stack unwinding. unsigned* ARM_exidx; size_t ARM_exidx_count; -#elif defined(ANDROID_MIPS_LINKER) +#elif defined(__mips__) unsigned mips_symtabno; unsigned mips_local_gotno; unsigned mips_gotsym; diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp index 5f2b2c1f6..4884364a5 100644 --- a/linker/linker_phdr.cpp +++ b/linker/linker_phdr.cpp @@ -202,13 +202,13 @@ bool ElfReader::VerifyElfHeader() { } if (header_.e_machine != -#ifdef ANDROID_ARM_LINKER +#if defined(__arm__) EM_ARM -#elif defined(ANDROID_MIPS_LINKER) - EM_MIPS -#elif defined(ANDROID_X86_LINKER) +#elif defined(__i386__) EM_386 -#elif defined(ANDROID_X86_64_LINKER) +#elif defined(__mips__) + EM_MIPS +#elif defined(__x86_64__) EM_X86_64 #endif ) { @@ -321,10 +321,6 @@ bool ElfReader::ReserveAddressSpace() { 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() { for (size_t i = 0; i < phdr_num_; ++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); } -#ifdef ANDROID_ARM_LINKER +#if defined(__arm__) # ifndef PT_ARM_EXIDX # 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; return -1; } -#endif /* ANDROID_ARM_LINKER */ +#endif /* Return the address and size of the ELF file's .dynamic section in memory, * or NULL if missing. diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h index f774b5dad..db15ac969 100644 --- a/linker/linker_phdr.h +++ b/linker/linker_phdr.h @@ -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); -#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, Elf_Addr** arm_exidx, unsigned* arm_exidix_count); #endif