summaryrefslogtreecommitdiff
path: root/ldso/ldso/mips/elfinterp.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-08-26 18:36:23 +0000
committerEric Andersen <andersen@codepoet.org>2004-08-26 18:36:23 +0000
commit17415ee0becb11c97e86dfa00c2e503649f952e6 (patch)
tree6410fbd0a149c06695a0a4a38b7d82ec76de67bd /ldso/ldso/mips/elfinterp.c
parent9d7a22d351d45808aa88224367cc1dd30e518705 (diff)
Avoid multiple passes to perform mips GOT relocations, and do
the whole lot in a single pass. -Erik
Diffstat (limited to 'ldso/ldso/mips/elfinterp.c')
-rw-r--r--ldso/ldso/mips/elfinterp.c85
1 files changed, 48 insertions, 37 deletions
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index e9c6294ca..d86f60d77 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/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++;
+ }
}
}
+