From d23c49221a13a57ba041ec6091ab510a912b8105 Mon Sep 17 00:00:00 2001 From: Carmelo Amoroso Date: Wed, 14 Jan 2009 15:20:25 +0000 Subject: ldso: performs bootstrap relocations only if required by the arch. It is controlled by ARCH_NEEDS_BOOTSTRAP_RELOCS macro. Signed-off-by: Jirka Acked-by: Carmelo Amoroso --- ldso/ldso/avr32/dl-sysdep.h | 3 ++ ldso/ldso/bfin/dl-sysdep.h | 3 ++ ldso/ldso/cris/dl-sysdep.h | 3 ++ ldso/ldso/dl-startup.c | 73 +++++++++++++++++++++++++------------------- ldso/ldso/frv/dl-sysdep.h | 3 ++ ldso/ldso/m68k/dl-sysdep.h | 3 ++ ldso/ldso/mips/dl-sysdep.h | 2 ++ ldso/ldso/sh64/dl-sysdep.h | 4 +++ ldso/ldso/sparc/dl-sysdep.h | 3 ++ ldso/ldso/xtensa/dl-sysdep.h | 3 ++ 10 files changed, 69 insertions(+), 31 deletions(-) (limited to 'ldso') diff --git a/ldso/ldso/avr32/dl-sysdep.h b/ldso/ldso/avr32/dl-sysdep.h index 85c120dd8..618769b6d 100644 --- a/ldso/ldso/avr32/dl-sysdep.h +++ b/ldso/ldso/avr32/dl-sysdep.h @@ -44,6 +44,9 @@ /* Used for error messages */ #define ELF_TARGET "AVR32" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got); #define elf_machine_type_class(type) \ diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h index a3563a0de..3c88da4a0 100644 --- a/ldso/ldso/bfin/dl-sysdep.h +++ b/ldso/ldso/bfin/dl-sysdep.h @@ -56,6 +56,9 @@ USA. */ /* Used for error messages */ #define ELF_TARGET "BFIN" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; struct funcdesc_value diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h index 575145df2..ffb763a5c 100644 --- a/ldso/ldso/cris/dl-sysdep.h +++ b/ldso/ldso/cris/dl-sysdep.h @@ -15,6 +15,9 @@ #undef MAGIC2 #define ELF_TARGET "CRIS" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry); 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 diff --git a/ldso/ldso/frv/dl-sysdep.h b/ldso/ldso/frv/dl-sysdep.h index 8e36ce592..e9c847a69 100644 --- a/ldso/ldso/frv/dl-sysdep.h +++ b/ldso/ldso/frv/dl-sysdep.h @@ -40,6 +40,9 @@ /* Used for error messages */ #define ELF_TARGET "FR-V" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; struct funcdesc_value diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h index 6d206bcbf..8e26e200e 100644 --- a/ldso/ldso/m68k/dl-sysdep.h +++ b/ldso/ldso/m68k/dl-sysdep.h @@ -22,6 +22,9 @@ do { \ /* Used for error messages */ #define ELF_TARGET "m68k" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h index 8f303fba1..cf6b28bf1 100644 --- a/ldso/ldso/mips/dl-sysdep.h +++ b/ldso/ldso/mips/dl-sysdep.h @@ -149,6 +149,8 @@ do { \ /* Used for error messages */ #define ELF_TARGET "MIPS" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS unsigned long __dl_runtime_resolve(unsigned long sym_index, unsigned long old_gpreg); diff --git a/ldso/ldso/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h index bb78964ba..fc67b127c 100644 --- a/ldso/ldso/sh64/dl-sysdep.h +++ b/ldso/ldso/sh64/dl-sysdep.h @@ -19,9 +19,13 @@ /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_SH #undef MAGIC2 + /* Used for error messages */ #define ELF_TARGET "sh64" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h index 17359e9b6..79365178d 100644 --- a/ldso/ldso/sparc/dl-sysdep.h +++ b/ldso/ldso/sparc/dl-sysdep.h @@ -40,6 +40,9 @@ /* Used for error messages */ #define ELF_TARGET "sparc" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h index 57b3e1d09..daae42810 100644 --- a/ldso/ldso/xtensa/dl-sysdep.h +++ b/ldso/ldso/xtensa/dl-sysdep.h @@ -73,6 +73,9 @@ typedef struct xtensa_got_location_struct { /* Used for error messages. */ #define ELF_TARGET "Xtensa" +/* Need bootstrap relocations */ +#define ARCH_NEEDS_BOOTSTRAP_RELOCS + struct elf_resolve; extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); -- cgit v1.2.3