summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-08-25 23:10:43 +0000
committerEric Andersen <andersen@codepoet.org>2004-08-25 23:10:43 +0000
commit772a5004213a8c1e955b8754e1ab16845bfdcd8f (patch)
treea1f485aa09b09effa754ee6b31f50073c962a368
parentf2916400b6b3f4ad4a80f9c865a132d6b7fb4d9a (diff)
Joakim Tjernlund writes:
Hi Manuel & Erik I think I know why MIPS is broken. _dl_perform_mips_global_got_relocations() is broken. It will due to my latest changes reloctate ldso. This function needs to die and its job should be done inside _dl_parse_relocation_information(). It is mostly a copy and paste job, Also PERFORM_BOOTSTRAP_GOT and PERFORM_BOOTSTRAP_RELOCATION should be fixed, they use symbols which aren't passed as arguments. Jocke
-rw-r--r--ldso/ldso/mips/elfinterp.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index 21bda6f96..3e7672757 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/ldso/ldso/mips/elfinterp.c
@@ -181,11 +181,53 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
unsigned long *got;
unsigned long *reloc_addr=NULL;
unsigned long symbol_addr;
- int i, reloc_type, symtab_index;
+ int reloc_type, symtab_index;
struct elf_resolve *tpnt = xpnt->dyn;
#if defined (__SUPPORT_LD_DEBUG__)
unsigned long old_val=0;
#endif
+ Elf32_Sym *sym;
+ 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;
+
+ /* 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 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)
+ *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++;
+ }
+
/* Now parse the relocation information */
rel_size = rel_size / sizeof(Elf32_Rel);
rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
@@ -252,8 +294,10 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
return 0;
}
+/* This function should be removed */
void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
{
+#if 0
Elf32_Sym *sym;
char *strtab;
unsigned long i;
@@ -299,4 +343,5 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
sym++;
}
}
+#endif
}