[uClibc-cvs] CVS update of uClibc/ldso/ldso/mips (elfinterp.c)

Erik Andersen andersen at codepoet.org
Wed Aug 25 23:10:43 UTC 2004


    Date: Wednesday, August 25, 2004 @ 17:10:43
  Author: andersen
    Path: /var/cvs/uClibc/ldso/ldso/mips

Modified: elfinterp.c (1.18 -> 1.19)

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


Index: uClibc/ldso/ldso/mips/elfinterp.c
diff -u uClibc/ldso/ldso/mips/elfinterp.c:1.18 uClibc/ldso/ldso/mips/elfinterp.c:1.19
--- uClibc/ldso/ldso/mips/elfinterp.c:1.18	Wed Aug 25 09:18:59 2004
+++ uClibc/ldso/ldso/mips/elfinterp.c	Wed Aug 25 17:10:43 2004
@@ -181,11 +181,53 @@
 	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 @@
 	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 @@
 			sym++;
 		}
 	}
+#endif
 }



More information about the uClibc-cvs mailing list