diff options
author | Carmelo Amoroso <carmelo.amoroso@st.com> | 2009-01-14 15:20:25 +0000 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2009-01-14 15:20:25 +0000 |
commit | d23c49221a13a57ba041ec6091ab510a912b8105 (patch) | |
tree | 6d54087854c4133485496c50cafb14f538bb9ba2 /ldso/ldso/dl-startup.c | |
parent | cd3a494e99fa4bcad1c2a621b71361005528bead (diff) |
ldso: performs bootstrap relocations only if required by the arch.
It is controlled by ARCH_NEEDS_BOOTSTRAP_RELOCS macro.
Signed-off-by: Jirka <olsajiri@gmail.com>
Acked-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Diffstat (limited to 'ldso/ldso/dl-startup.c')
-rw-r--r-- | ldso/ldso/dl-startup.c | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 6b69c7498..70942bc7a 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -230,12 +230,6 @@ DL_START(unsigned long args) # define INDX_MAX 2 #endif for (indx = 0; indx < INDX_MAX; indx++) { - unsigned int i; - unsigned long *reloc_addr; - unsigned long symbol_addr; - int symtab_index; - ElfW(Sym) *sym; - ELF_RELOC *rpnt; unsigned long rel_addr, rel_size; ElfW(Word) relative_count = tpnt->dynamic_info[DT_RELCONT_IDX]; @@ -247,41 +241,58 @@ DL_START(unsigned long args) if (!rel_addr) continue; - /* Now parse the relocation information */ - /* Since ldso is linked with -Bsymbolic, all relocs will be RELATIVE(for those archs that have - RELATIVE relocs) which means that the for(..) loop below has nothing to do and can be deleted. - Possibly one should add a HAVE_RELATIVE_RELOCS directive and #ifdef away some code. */ if (!indx && relative_count) { rel_size -= relative_count * sizeof(ELF_RELOC); elf_machine_relative(load_addr, rel_addr, relative_count); rel_addr += relative_count * sizeof(ELF_RELOC); } - rpnt = (ELF_RELOC *) rel_addr; - for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { - reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset); - symtab_index = ELF_R_SYM(rpnt->r_info); - symbol_addr = 0; - sym = NULL; - if (symtab_index) { - char *strtab; - ElfW(Sym) *symtab; - - symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB]; - strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; - sym = &symtab[symtab_index]; - symbol_addr = (unsigned long) DL_RELOC_ADDR(load_addr, sym->st_value); + /* + * Since ldso is linked with -Bsymbolic, all relocs should be RELATIVE. All archs + * that need bootstrap relocations need to define ARCH_NEEDS_BOOTSTRAP_RELOCS. + */ +#ifdef ARCH_NEEDS_BOOTSTRAP_RELOCS + { + ELF_RELOC *rpnt; + unsigned int i; + ElfW(Sym) *sym; + unsigned long symbol_addr; + int symtab_index; + unsigned long *reloc_addr; + + /* Now parse the relocation information */ + rpnt = (ELF_RELOC *) rel_addr; + for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { + reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset); + symtab_index = ELF_R_SYM(rpnt->r_info); + symbol_addr = 0; + sym = NULL; + if (symtab_index) { + char *strtab; + ElfW(Sym) *symtab; + + symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB]; + strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; + sym = &symtab[symtab_index]; + symbol_addr = (unsigned long) DL_RELOC_ADDR(load_addr, sym->st_value); #if !defined(EARLY_STDERR_SPECIAL) - SEND_STDERR_DEBUG("relocating symbol: "); - SEND_STDERR_DEBUG(strtab + sym->st_name); - SEND_STDERR_DEBUG("\n"); + SEND_STDERR_DEBUG("relocating symbol: "); + SEND_STDERR_DEBUG(strtab + sym->st_name); + SEND_STDERR_DEBUG("\n"); #endif - } else { - SEND_STDERR_DEBUG("relocating unknown symbol\n"); + } else { + SEND_STDERR_DEBUG("relocating unknown symbol\n"); + } + /* Use this machine-specific macro to perform the actual relocation. */ + PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym); } - /* Use this machine-specific macro to perform the actual relocation. */ - PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym); } +#else /* ARCH_NEEDS_BOOTSTRAP_RELOCS */ + if (rel_size) { + SEND_EARLY_STDERR("Cannot continue, found non relative relocs during the bootstrap.\n"); + _dl_exit(14); + } +#endif } } #endif |