diff options
author | David 'Digit' Turner <digit@google.com> | 2011-11-15 17:17:28 +0100 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2012-05-15 09:58:33 -0700 |
commit | 077891b199ad295017b32bc9cf1c542c1360b3b8 (patch) | |
tree | 83dcb9018f6cfa9c7bea6a088748ade7cba3b975 /linker | |
parent | 6cdefd06c0386776405e4379af036722db5d60c0 (diff) | |
download | bionic-077891b199ad295017b32bc9cf1c542c1360b3b8.zip bionic-077891b199ad295017b32bc9cf1c542c1360b3b8.tar.gz bionic-077891b199ad295017b32bc9cf1c542c1360b3b8.tar.bz2 |
linker: Fix the computation of si->base
The computation of si->base assumed that the first entry in the
program header table is a PT_PHDR. This results in the dynamic
linker crashing with a SIGSEGV/MAPERR when trying to load some
of the NDK unit test programs, which happen to have an EXIDX
header first, followed byu a PHDR one.
This patch fixes the computation by parsing the program header
table, looking explicitely for the PHDR entry. This fixes the
load of the NDK unit test programs, and doesn't affect system
libraries.
Change-Id: Id18ea6037dbe950b5abbbce816c2960321f0b81d
Diffstat (limited to 'linker')
-rw-r--r-- | linker/linker.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/linker/linker.c b/linker/linker.c index a71986d..1e35f87 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -2078,7 +2078,18 @@ sanitize: vecs += 2; } - si->base = (Elf32_Addr) si->phdr - si->phdr->p_vaddr; + /* Compute the value of si->base. We can't rely on the fact that + * the first entry is the PHDR because this will not be true + * for certain executables (e.g. some in the NDK unit test suite) + */ + int nn; + si->base = 0; + for ( nn = 0; nn < si->phnum; nn++ ) { + if (si->phdr[nn].p_type == PT_PHDR) { + si->base = (Elf32_Addr) si->phdr - si->phdr[nn].p_vaddr; + break; + } + } si->dynamic = (unsigned *)-1; si->wrprotect_start = 0xffffffff; si->wrprotect_end = 0; |