From 8180b08fb2f27052f9df2ae4787bb5bf409f13e0 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Tue, 15 Nov 2011 17:17:28 +0100 Subject: [PATCH] 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 --- linker/linker.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/linker/linker.c b/linker/linker.c index 504fb9359..792ece618 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -2192,7 +2192,18 @@ unsigned __linker_init(unsigned **elfdata) 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;