diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-08-25 23:10:43 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-08-25 23:10:43 +0000 |
commit | 772a5004213a8c1e955b8754e1ab16845bfdcd8f (patch) | |
tree | a1f485aa09b09effa754ee6b31f50073c962a368 /ldso | |
parent | f2916400b6b3f4ad4a80f9c865a132d6b7fb4d9a (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
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/mips/elfinterp.c | 47 |
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 } |