Browse Source

Avoid multiple passes to perform mips GOT relocations, and do
the whole lot in a single pass.
-Erik

Eric Andersen 20 years ago
parent
commit
17415ee0be
2 changed files with 53 additions and 47 deletions
  1. 5 10
      ldso/ldso/ldso.c
  2. 48 37
      ldso/ldso/mips/elfinterp.c

+ 5 - 10
ldso/ldso/ldso.c

@@ -275,11 +275,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
 				INIT_GOT(lpnt, _dl_loaded_modules);
 		}
 
-#if defined(__mips__)
-		/* Relocate any global GOT entries for the application */
-		_dl_perform_mips_global_got_relocations(app_tpnt);
-#endif
-
 		/* OK, fill this in - we did not have this before */
 		if (ppnt->p_type == PT_INTERP) {
 			int readsize = 0;
@@ -667,17 +662,17 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
 #endif
 
 
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+	_dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
+#endif
+
 #ifdef __mips__
 	/*
 	 * Relocation of the GOT entries for MIPS have to be done
-	 * after all the libraries have been loaded.
-	 */
+	 * after all the libraries have been loaded.  */
 	_dl_perform_mips_global_got_relocations(_dl_loaded_modules);
 #endif
 
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
-	_dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
-#endif
 	/*
 	 * OK, now all of the kids are tucked into bed in their proper addresses.
 	 * Now we go through and look for REL and RELA records that indicate fixups

+ 48 - 37
ldso/ldso/mips/elfinterp.c

@@ -188,9 +188,6 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
 	unsigned long old_val=0;
 #endif
 
-	/* Relocate any global GOT entries for the object */
-	_dl_perform_mips_global_got_relocations(tpnt);
-
 	/* Now parse the relocation information */
 	rel_size = rel_size / sizeof(Elf32_Rel);
 	rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
@@ -260,47 +257,61 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
 /* Relocate the global GOT entries for the object */
 void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
 {
-	char *strtab;
 	Elf32_Sym *sym;
+	char *strtab;
 	unsigned long i;
 	unsigned long *got_entry;
-	/* Setup the loop variables */
-	got_entry = (unsigned long *) (tpnt->loadaddr +
-				       tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
-	sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
-			     (unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
-	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
-			   (unsigned long) tpnt->loadaddr);
-	i = tpnt->mips_symtabno - tpnt->mips_gotsym;
-
-	while(i--) {
-		if (sym->st_shndx == SHN_UNDEF) {
-			if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value) {
-				*got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
+
+	for (; tpnt ; tpnt = tpnt->next) {
+
+		/* We don't touch the dynamic linker */
+		if (tpnt->libtype == program_interpreter)
+			continue;
+
+		/* Setup the loop variables */
+		got_entry = (unsigned long *) (tpnt->loadaddr +
+			tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
+		sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+			(unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
+		strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
+			(unsigned long) tpnt->loadaddr);
+		i = tpnt->mips_symtabno - tpnt->mips_gotsym;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		_dl_dprintf(2, "_dl_perform_mips_global_got_relocations for '%s'\n", tpnt->libname);
+#endif
+
+		/* Relocate the global GOT entries for the object */
+		while(i--) {
+			if (sym->st_shndx == SHN_UNDEF) {
+				if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value) {
+					*got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
+				}
+				else {
+					*got_entry = (unsigned long) _dl_find_hash(strtab +
+						sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+				}
 			}
-			else {
+			else if (sym->st_shndx == SHN_COMMON) {
 				*got_entry = (unsigned long) _dl_find_hash(strtab +
-									   sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+					sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
 			}
-		}
-		else if (sym->st_shndx == SHN_COMMON) {
-			*got_entry = (unsigned long) _dl_find_hash(strtab +
-								   sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
-		}
-		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
-			 *got_entry != sym->st_value) {
-			*got_entry += (unsigned long) tpnt->loadaddr;
-		}
-		else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
-			if (sym->st_other == 0)
+			else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+				*got_entry != sym->st_value) {
 				*got_entry += (unsigned long) tpnt->loadaddr;
-		}
-		else {
-			*got_entry = (unsigned long) _dl_find_hash(strtab +
-								   sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
-		}
+			}
+			else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
+				if (sym->st_other == 0)
+					*got_entry += (unsigned long) tpnt->loadaddr;
+			}
+			else {
+				*got_entry = (unsigned long) _dl_find_hash(strtab +
+					sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);
+			}
 
-		got_entry++;
-		sym++;
+			got_entry++;
+			sym++;
+		}
 	}
 }
+