linker: simplify code for dynamic and ARM exidx sections.
This moves the code that determines where the .dynamic and .ARM.exidx sections are to a single place in soinfo_link_image(). Change-Id: I98adcb440577bed86442349f03f3c629c945efec
This commit is contained in:
parent
8941cfa17a
commit
63f99f4a4e
@ -126,10 +126,6 @@ struct _link_stats linker_stats;
|
||||
unsigned bitmask[4096];
|
||||
#endif
|
||||
|
||||
#ifndef PT_ARM_EXIDX
|
||||
#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
|
||||
#endif
|
||||
|
||||
#define HOODLUM(name, ret, ...) \
|
||||
ret name __VA_ARGS__ \
|
||||
{ \
|
||||
@ -924,10 +920,6 @@ soinfo_load_segments(soinfo* si, int fd, const Elf32_Phdr* phdr_table, int phdr_
|
||||
mprotect(pbase, len,
|
||||
PFLAGS_TO_PROT(phdr->p_flags) | PROT_WRITE);
|
||||
}
|
||||
} else if (phdr->p_type == PT_DYNAMIC) {
|
||||
DEBUG_DUMP_PHDR(phdr, "PT_DYNAMIC", pid);
|
||||
/* this segment contains the dynamic linking information */
|
||||
si->dynamic = (unsigned *)(base + phdr->p_vaddr);
|
||||
} else if (phdr->p_type == PT_GNU_RELRO) {
|
||||
if (((base + phdr->p_vaddr) >= si->base + si->size)
|
||||
|| ((base + phdr->p_vaddr + phdr->p_memsz) > si->base + si->size)
|
||||
@ -939,16 +931,6 @@ soinfo_load_segments(soinfo* si, int fd, const Elf32_Phdr* phdr_table, int phdr_
|
||||
}
|
||||
si->gnu_relro_start = (Elf32_Addr) (base + phdr->p_vaddr);
|
||||
si->gnu_relro_len = (unsigned) phdr->p_memsz;
|
||||
} else {
|
||||
#ifdef ANDROID_ARM_LINKER
|
||||
if (phdr->p_type == PT_ARM_EXIDX) {
|
||||
DEBUG_DUMP_PHDR(phdr, "PT_ARM_EXIDX", pid);
|
||||
/* exidx entries (used for stack unwinding) are 8 bytes each.
|
||||
*/
|
||||
si->ARM_exidx = (unsigned *)(base + phdr->p_vaddr);
|
||||
si->ARM_exidx_count = phdr->p_memsz / 8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@ -1659,6 +1641,20 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
|
||||
DEBUG("%5d si->base = 0x%08x si->flags = 0x%08x\n", pid,
|
||||
si->base, si->flags);
|
||||
|
||||
/* Extract dynamic section */
|
||||
si->dynamic = phdr_table_get_dynamic_section(phdr, phnum, base);
|
||||
if (si->dynamic == NULL) {
|
||||
DL_ERR("%5d missing PT_DYNAMIC?!", pid);
|
||||
goto fail;
|
||||
} else {
|
||||
DEBUG("%5d dynamic = %p\n", pid, si->dynamic);
|
||||
}
|
||||
|
||||
#ifdef ANDROID_ARM_LINKER
|
||||
(void) phdr_table_get_arm_exidx(phdr, phnum, base,
|
||||
&si->ARM_exidx, &si->ARM_exidx_count);
|
||||
#endif
|
||||
|
||||
if (si->flags & (FLAG_EXE | FLAG_LINKER)) {
|
||||
/* Locate the needed program segments (DYNAMIC/ARM_EXIDX) for
|
||||
* linkage info if this is the executable or the linker itself.
|
||||
@ -1670,14 +1666,6 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
|
||||
*/
|
||||
si->size = 0;
|
||||
for(; phnum > 0; --phnum, ++phdr) {
|
||||
#ifdef ANDROID_ARM_LINKER
|
||||
if(phdr->p_type == PT_ARM_EXIDX) {
|
||||
/* exidx entries (used for stack unwinding) are 8 bytes each.
|
||||
*/
|
||||
si->ARM_exidx = (unsigned *)(base + phdr->p_vaddr);
|
||||
si->ARM_exidx_count = phdr->p_memsz / 8;
|
||||
}
|
||||
#endif
|
||||
if (phdr->p_type == PT_LOAD) {
|
||||
/* For the executable, we use the si->size field only in
|
||||
dl_unwind_find_exidx(), so the meaning of si->size
|
||||
@ -1715,16 +1703,6 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
|
||||
phdr->p_memsz,
|
||||
PFLAGS_TO_PROT(phdr->p_flags) | PROT_WRITE);
|
||||
}
|
||||
} else if (phdr->p_type == PT_DYNAMIC) {
|
||||
if (si->dynamic != (unsigned *)-1) {
|
||||
DL_ERR("%5d multiple PT_DYNAMIC segments found in '%s'. "
|
||||
"Segment at 0x%08x, previously one found at 0x%08x",
|
||||
pid, si->name, base + phdr->p_vaddr,
|
||||
(unsigned)si->dynamic);
|
||||
goto fail;
|
||||
}
|
||||
DEBUG_DUMP_PHDR(phdr, "PT_DYNAMIC", pid);
|
||||
si->dynamic = (unsigned *) (base + phdr->p_vaddr);
|
||||
} else if (phdr->p_type == PT_GNU_RELRO) {
|
||||
if ((base + phdr->p_vaddr >= si->base + si->size)
|
||||
|| ((base + phdr->p_vaddr + phdr->p_memsz) > si->base + si->size)
|
||||
@ -1740,13 +1718,6 @@ static int soinfo_link_image(soinfo *si, unsigned wr_offset)
|
||||
}
|
||||
}
|
||||
|
||||
if (si->dynamic == (unsigned *)-1) {
|
||||
DL_ERR("%5d missing PT_DYNAMIC?!", pid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DEBUG("%5d dynamic = %p\n", pid, si->dynamic);
|
||||
|
||||
/* extract useful information from dynamic section */
|
||||
for(d = si->dynamic; *d; d++){
|
||||
DEBUG("%5d d = %p, d[0] = 0x%08x d[1] = 0x%08x\n", pid, d, d[0], d[1]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user