Explorar el Código

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>

Carmelo Amoroso hace 16 años
padre
commit
d23c49221a

+ 3 - 0
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)				\

+ 3 - 0
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

+ 3 - 0
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);
 

+ 42 - 31
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

+ 3 - 0
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

+ 3 - 0
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);
 

+ 2 - 0
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);

+ 4 - 0
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);
 

+ 3 - 0
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);
 

+ 3 - 0
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);