diff options
-rw-r--r-- | ldso/ldso/ldso.c | 5 | ||||
-rw-r--r-- | ldso/ldso/mips/dl-sysdep.h | 2 | ||||
-rw-r--r-- | ldso/ldso/mips/elfinterp.c | 115 |
3 files changed, 44 insertions, 78 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 568081acd..5afc4a8f7 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -275,6 +275,11 @@ 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; diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h index 9c4a21580..549bcef9e 100644 --- a/ldso/ldso/mips/dl-sysdep.h +++ b/ldso/ldso/mips/dl-sysdep.h @@ -42,6 +42,8 @@ do { \ unsigned long _dl_linux_resolver(unsigned long sym_index, unsigned long old_gpreg); +struct elf_resolve; +void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt); #define do_rem(result, n, base) result = (n % base) diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c index 3e7672757..e9c6294ca 100644 --- a/ldso/ldso/mips/elfinterp.c +++ b/ldso/ldso/mips/elfinterp.c @@ -178,6 +178,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, Elf32_Sym *symtab; Elf32_Rel *rpnt; char *strtab; + unsigned long i; unsigned long *got; unsigned long *reloc_addr=NULL; unsigned long symbol_addr; @@ -186,47 +187,9 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, #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++; - } + /* 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); @@ -294,54 +257,50 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, return 0; } -/* This function should be removed */ +/* Relocate the global GOT entries for the object */ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt) { -#if 0 - Elf32_Sym *sym; char *strtab; + 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; - for (; tpnt ; tpnt = tpnt->next) { - /* 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; + 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); + sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT); } - - got_entry++; - sym++; } + 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++; } -#endif } |