Merge "Remove 32-bit assumptions from the ELF code."
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
extern void* __executable_start;
|
||||
|
||||
int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data), void* data) {
|
||||
Elf32_Ehdr* ehdr = (Elf32_Ehdr*) &__executable_start;
|
||||
Elf_Ehdr* ehdr = (Elf_Ehdr*) &__executable_start;
|
||||
|
||||
// TODO: again, copied from linker.c. Find a better home for this later.
|
||||
if (ehdr->e_ident[EI_MAG0] != ELFMAG0) return -1;
|
||||
@@ -51,7 +51,7 @@ int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data
|
||||
struct dl_phdr_info exe_info;
|
||||
exe_info.dlpi_addr = 0;
|
||||
exe_info.dlpi_name = NULL;
|
||||
exe_info.dlpi_phdr = (Elf32_Phdr*) ((unsigned long) ehdr + ehdr->e_phoff);
|
||||
exe_info.dlpi_phdr = (Elf_Phdr*) ((unsigned long) ehdr + ehdr->e_phoff);
|
||||
exe_info.dlpi_phnum = ehdr->e_phnum;
|
||||
|
||||
#ifdef AT_SYSINFO_EHDR
|
||||
@@ -62,15 +62,15 @@ int dl_iterate_phdr(int (*cb)(struct dl_phdr_info* info, size_t size, void* data
|
||||
}
|
||||
|
||||
// Try the VDSO if that didn't work.
|
||||
Elf32_Ehdr* ehdr_vdso = (Elf32_Ehdr*) getauxval(AT_SYSINFO_EHDR);
|
||||
Elf_Ehdr* ehdr_vdso = (Elf_Ehdr*) getauxval(AT_SYSINFO_EHDR);
|
||||
struct dl_phdr_info vdso_info;
|
||||
vdso_info.dlpi_addr = 0;
|
||||
vdso_info.dlpi_name = NULL;
|
||||
vdso_info.dlpi_phdr = (Elf32_Phdr*) ((char*) ehdr_vdso + ehdr_vdso->e_phoff);
|
||||
vdso_info.dlpi_phdr = (Elf_Phdr*) ((char*) ehdr_vdso + ehdr_vdso->e_phoff);
|
||||
vdso_info.dlpi_phnum = ehdr_vdso->e_phnum;
|
||||
for (size_t i = 0; i < vdso_info.dlpi_phnum; ++i) {
|
||||
if (vdso_info.dlpi_phdr[i].p_type == PT_LOAD) {
|
||||
vdso_info.dlpi_addr = (Elf32_Addr) ehdr_vdso - vdso_info.dlpi_phdr[i].p_vaddr;
|
||||
vdso_info.dlpi_addr = (Elf_Addr) ehdr_vdso - vdso_info.dlpi_phdr[i].p_vaddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -32,10 +32,10 @@
|
||||
#include <private/bionic_auxv.h>
|
||||
#include <elf.h>
|
||||
|
||||
__LIBC_HIDDEN__ Elf32_auxv_t* __libc_auxv = NULL;
|
||||
__LIBC_HIDDEN__ Elf_auxv_t* __libc_auxv = NULL;
|
||||
|
||||
extern "C" unsigned long int getauxval(unsigned long int type) {
|
||||
for (Elf32_auxv_t* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
|
||||
for (Elf_auxv_t* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
|
||||
if (v->a_type == type) {
|
||||
return v->a_un.a_val;
|
||||
}
|
||||
|
@@ -67,16 +67,16 @@ static void call_array(void(**list)()) {
|
||||
}
|
||||
|
||||
static void apply_gnu_relro() {
|
||||
Elf32_Phdr* phdr_start = reinterpret_cast<Elf32_Phdr*>(getauxval(AT_PHDR));
|
||||
Elf_Phdr* phdr_start = reinterpret_cast<Elf_Phdr*>(getauxval(AT_PHDR));
|
||||
unsigned long int phdr_ct = getauxval(AT_PHNUM);
|
||||
|
||||
for (Elf32_Phdr* phdr = phdr_start; phdr < (phdr_start + phdr_ct); phdr++) {
|
||||
for (Elf_Phdr* phdr = phdr_start; phdr < (phdr_start + phdr_ct); phdr++) {
|
||||
if (phdr->p_type != PT_GNU_RELRO) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Elf32_Addr seg_page_start = PAGE_START(phdr->p_vaddr);
|
||||
Elf32_Addr seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz);
|
||||
Elf_Addr seg_page_start = PAGE_START(phdr->p_vaddr);
|
||||
Elf_Addr seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz);
|
||||
|
||||
// Check return value here? What do we do if we fail?
|
||||
mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_end - seg_page_start, PROT_READ);
|
||||
|
@@ -46,5 +46,10 @@ typedef struct {
|
||||
} a_un;
|
||||
} Elf64_auxv_t;
|
||||
|
||||
#endif /* _ELF_H */
|
||||
#ifdef __LP64__
|
||||
# define Elf_auxv_t Elf64_auxv_t
|
||||
#else
|
||||
# define Elf_auxv_t Elf32_auxv_t
|
||||
#endif
|
||||
|
||||
#endif /* _ELF_H */
|
||||
|
@@ -33,8 +33,7 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* bionic is currently only 32-bit. */
|
||||
#define ElfW(type) Elf32_##type
|
||||
#define ElfW(type) Elf_##type
|
||||
|
||||
struct dl_phdr_info {
|
||||
ElfW(Addr) dlpi_addr;
|
||||
|
@@ -30,7 +30,7 @@ struct abort_msg_t;
|
||||
class KernelArgumentBlock {
|
||||
public:
|
||||
KernelArgumentBlock(void* raw_args) {
|
||||
uint32_t* args = reinterpret_cast<uint32_t*>(raw_args);
|
||||
uintptr_t* args = reinterpret_cast<uintptr_t*>(raw_args);
|
||||
argc = static_cast<int>(*args);
|
||||
argv = reinterpret_cast<char**>(args + 1);
|
||||
envp = argv + argc + 1;
|
||||
@@ -43,14 +43,14 @@ class KernelArgumentBlock {
|
||||
}
|
||||
++p; // Skip second NULL;
|
||||
|
||||
auxv = reinterpret_cast<Elf32_auxv_t*>(p);
|
||||
auxv = reinterpret_cast<Elf_auxv_t*>(p);
|
||||
}
|
||||
|
||||
// Similar to ::getauxval but doesn't require the libc global variables to be set up,
|
||||
// so it's safe to call this really early on. This function also lets you distinguish
|
||||
// between the inability to find the given type and its value just happening to be 0.
|
||||
unsigned long getauxval(unsigned long type, bool* found_match = NULL) {
|
||||
for (Elf32_auxv_t* v = auxv; v->a_type != AT_NULL; ++v) {
|
||||
for (Elf_auxv_t* v = auxv; v->a_type != AT_NULL; ++v) {
|
||||
if (v->a_type == type) {
|
||||
if (found_match != NULL) {
|
||||
*found_match = true;
|
||||
@@ -67,7 +67,7 @@ class KernelArgumentBlock {
|
||||
int argc;
|
||||
char** argv;
|
||||
char** envp;
|
||||
Elf32_auxv_t* auxv;
|
||||
Elf_auxv_t* auxv;
|
||||
|
||||
abort_msg_t** abort_message_ptr;
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern Elf32_auxv_t* __libc_auxv;
|
||||
extern Elf_auxv_t* __libc_auxv;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
Reference in New Issue
Block a user