summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorCarmelo Amoroso <carmelo.amoroso@st.com>2009-01-14 15:20:25 +0000
committerCarmelo Amoroso <carmelo.amoroso@st.com>2009-01-14 15:20:25 +0000
commitd23c49221a13a57ba041ec6091ab510a912b8105 (patch)
tree6d54087854c4133485496c50cafb14f538bb9ba2 /ldso
parentcd3a494e99fa4bcad1c2a621b71361005528bead (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')
-rw-r--r--ldso/ldso/avr32/dl-sysdep.h3
-rw-r--r--ldso/ldso/bfin/dl-sysdep.h3
-rw-r--r--ldso/ldso/cris/dl-sysdep.h3
-rw-r--r--ldso/ldso/dl-startup.c73
-rw-r--r--ldso/ldso/frv/dl-sysdep.h3
-rw-r--r--ldso/ldso/m68k/dl-sysdep.h3
-rw-r--r--ldso/ldso/mips/dl-sysdep.h2
-rw-r--r--ldso/ldso/sh64/dl-sysdep.h4
-rw-r--r--ldso/ldso/sparc/dl-sysdep.h3
-rw-r--r--ldso/ldso/xtensa/dl-sysdep.h3
10 files changed, 69 insertions, 31 deletions
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);