summaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@google.com>2012-06-19 00:08:39 +0200
committerDavid 'Digit' Turner <digit@google.com>2012-06-26 10:39:55 +0200
commit63f99f4a4e05353de2e8ba3d7bd4d882d716167a (patch)
treea7a3af579dc0f14191c014543d889237e69916f8 /linker
parent8941cfa17a60133f3896b84f6517aa849bafb050 (diff)
downloadbionic-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.c57
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]);