Revert "Make the linker relocatable."
This reverts commit 994e9a5ed1c4e9f23a8bed79caea684eaa270027.
Broke x86 build.
diff --git a/linker/linker.c b/linker/linker.c
index cf66211..504fb93 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -313,6 +313,15 @@
freelist = si;
}
+#ifndef LINKER_TEXT_BASE
+#error "linker's makefile must define LINKER_TEXT_BASE"
+#endif
+#ifndef LINKER_AREA_SIZE
+#error "linker's makefile must define LINKER_AREA_SIZE"
+#endif
+#define LINKER_BASE ((LINKER_TEXT_BASE) & 0xfff00000)
+#define LINKER_TOP (LINKER_BASE + (LINKER_AREA_SIZE))
+
const char *addr_to_name(unsigned addr)
{
soinfo *si;
@@ -323,6 +332,10 @@
}
}
+ if((addr >= LINKER_BASE) && (addr < LINKER_TOP)){
+ return "linker";
+ }
+
return "";
}
@@ -341,10 +354,12 @@
soinfo *si;
unsigned addr = (unsigned)pc;
- for (si = solist; si != 0; si = si->next){
- if ((addr >= si->base) && (addr < (si->base + si->size))) {
- *pcount = si->ARM_exidx_count;
- return (_Unwind_Ptr)(si->base + (unsigned long)si->ARM_exidx);
+ if ((addr < LINKER_BASE) || (addr >= LINKER_TOP)) {
+ for (si = solist; si != 0; si = si->next){
+ if ((addr >= si->base) && (addr < (si->base + si->size))) {
+ *pcount = si->ARM_exidx_count;
+ return (_Unwind_Ptr)(si->base + (unsigned long)si->ARM_exidx);
+ }
}
}
*pcount = 0;
@@ -405,33 +420,6 @@
return NULL;
}
-/*
- * Essentially the same method as _elf_lookup() above, but only
- * searches for LOCAL symbols
- */
-static Elf32_Sym *_elf_lookup_local(soinfo *si, unsigned hash, const char *name)
-{
- Elf32_Sym *symtab = si->symtab;
- const char *strtab = si->strtab;
- unsigned n = hash % si->nbucket;;
-
- TRACE_TYPE(LOOKUP, "%5d LOCAL SEARCH %s in %s@0x%08x %08x %d\n", pid,
- name, si->name, si->base, hash, hash % si->nbucket);
- for(n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n]){
- Elf32_Sym *s = symtab + n;
- if (strcmp(strtab + s->st_name, name)) continue;
- if (ELF32_ST_BIND(s->st_info) != STB_LOCAL) continue;
- /* no section == undefined */
- if(s->st_shndx == 0) continue;
-
- TRACE_TYPE(LOOKUP, "%5d FOUND LOCAL %s in %s (%08x) %d\n", pid,
- name, si->name, s->st_value, s->st_size);
- return s;
- }
-
- return NULL;
-}
-
static unsigned elfhash(const char *_name)
{
const unsigned char *name = (const unsigned char *) _name;
@@ -455,17 +443,7 @@
soinfo *lsi = si;
int i;
- /* If we are trying to find a symbol for the linker itself, look
- * for LOCAL symbols first. Avoid using LOCAL symbols for other
- * shared libraries until we have a better understanding of what
- * might break by doing so. */
- if (si->flags & FLAG_LINKER) {
- s = _elf_lookup_local(si, elf_hash, name);
- if(s != NULL)
- goto done;
- }
-
- /* Look for symbols in the local scope (the object who is
+ /* Look for symbols in the local scope first (the object who is
* searching). This happens with C++ templates on i386 for some
* reason.
*
@@ -474,7 +452,6 @@
* dynamic linking. Some systems return the first definition found
* and some the first non-weak definition. This is system dependent.
* Here we return the first definition found for simplicity. */
-
s = _elf_lookup(si, elf_hash, name);
if(s != NULL)
goto done;
@@ -2107,12 +2084,7 @@
static void * __tls_area[ANDROID_TLS_SLOTS];
-/*
- * This code is called after the linker has linked itself and
- * fixed it's own GOT. It is safe to make references to externs
- * and other non-local data at this point.
- */
-static unsigned __linker_init_post_relocation(unsigned **elfdata)
+unsigned __linker_init(unsigned **elfdata)
{
static soinfo linker_soinfo;
@@ -2289,80 +2261,3 @@
si->entry);
return si->entry;
}
-
-/*
- * Find the value of AT_BASE passed to us by the kernel. This is the load
- * location of the linker.
- */
-static unsigned find_linker_base(unsigned **elfdata) {
- int argc = (int) *elfdata;
- char **argv = (char**) (elfdata + 1);
- unsigned *vecs = (unsigned*) (argv + argc + 1);
- while (vecs[0] != 0) {
- vecs++;
- }
-
- /* The end of the environment block is marked by two NULL pointers */
- vecs++;
-
- while(vecs[0]) {
- if (vecs[0] == AT_BASE) {
- return vecs[1];
- }
- vecs += 2;
- }
-
- return 0; // should never happen
-}
-
-/*
- * This is the entry point for the linker, called from begin.S. This
- * method is responsible for fixing the linker's own relocations, and
- * then calling __linker_init_post_relocation().
- *
- * Because this method is called before the linker has fixed it's own
- * relocations, any attempt to reference an extern variable, extern
- * function, or other GOT reference will generate a segfault.
- */
-unsigned __linker_init(unsigned **elfdata) {
- unsigned linker_addr = find_linker_base(elfdata);
- Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) linker_addr;
- Elf32_Phdr *phdr =
- (Elf32_Phdr *)((unsigned char *) linker_addr + elf_hdr->e_phoff);
-
- soinfo linker_so;
- memset(&linker_so, 0, sizeof(soinfo));
-
- linker_so.base = linker_addr;
- linker_so.dynamic = (unsigned *) -1;
- linker_so.phdr = phdr;
- linker_so.phnum = elf_hdr->e_phnum;
- linker_so.flags |= FLAG_LINKER;
-
- /*
- * Find the DYNAMIC section of the linker itself, so we can
- * fix our own relocations.
- */
- int i;
- for (i = 0; i < linker_so.phnum; i++) {
- if (phdr[i].p_type == PT_DYNAMIC) {
- linker_so.dynamic = (unsigned *)(linker_so.base + phdr[i].p_vaddr);
- break;
- }
- }
-
- if ((linker_so.dynamic != (unsigned char*) -1)
- && link_image(&linker_so, 0)) {
- // It would be nice to print an error message, but if the linker
- // can't link itself, there's no guarantee that we'll be able to
- // call write() (because it involves a GOT reference).
- //
- // This situation should never occur unless the linker itself
- // is corrupt.
- exit(-1);
- }
-
- // We have successfully fixed our own relocations. It's safe to run
- // the main part of the linker now.
- return __linker_init_post_relocation(elfdata);
-}