OSDN Git Service

Joakim Tjernlund writes:
authorEric Andersen <andersen@codepoet.org>
Wed, 25 Aug 2004 23:10:43 +0000 (23:10 -0000)
committerEric Andersen <andersen@codepoet.org>
Wed, 25 Aug 2004 23:10:43 +0000 (23:10 -0000)
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

ldso/ldso/mips/elfinterp.c

index 21bda6f..3e76727 100644 (file)
@@ -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
 }