diff options
author | David 'Digit' Turner <digit@google.com> | 2012-06-19 00:08:39 +0200 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2012-06-26 10:39:55 +0200 |
commit | 63f99f4a4e05353de2e8ba3d7bd4d882d716167a (patch) | |
tree | a7a3af579dc0f14191c014543d889237e69916f8 /linker | |
parent | 8941cfa17a60133f3896b84f6517aa849bafb050 (diff) | |
download | bionic-63f99f4a4e05353de2e8ba3d7bd4d882d716167a.zip bionic-63f99f4a4e05353de2e8ba3d7bd4d882d716167a.tar.gz bionic-63f99f4a4e05353de2e8ba3d7bd4d882d716167a.tar.bz2 |
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
Diffstat (limited to 'linker')
-rw-r--r-- | linker/linker.c | 57 |
1 files changed, 14 insertions, 43 deletions
diff --git a/linker/linker.c b/linker/linker.c index c725d02..a3bc171 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -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]); |