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

Erik Andersen andersen at codepoet.org
Thu Aug 26 11:30:49 UTC 2004


    Date: Thursday, August 26, 2004 @ 05:30:48
  Author: andersen
    Path: /var/cvs/uClibc/ldso/ldso

Modified: ldso.c (1.112 -> 1.113) mips/dl-sysdep.h (1.10 -> 1.11)
          mips/elfinterp.c (1.19 -> 1.20)

Relocations of the application's global GOT entries were not being run, and
only the global GOT entry relocations for the loaded shared libs were being
handled.  This made applications segfault when using un-fixedup symbols.  After
many hours debugging to track down the problem, this patch makes the mips port
happy again.
 -Erik


Index: uClibc/ldso/ldso/ldso.c
diff -u uClibc/ldso/ldso/ldso.c:1.112 uClibc/ldso/ldso/ldso.c:1.113
--- uClibc/ldso/ldso/ldso.c:1.112	Wed Aug 25 09:18:56 2004
+++ uClibc/ldso/ldso/ldso.c	Thu Aug 26 05:30:47 2004
@@ -275,6 +275,11 @@
 				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;
Index: uClibc/ldso/ldso/mips/dl-sysdep.h
diff -u uClibc/ldso/ldso/mips/dl-sysdep.h:1.10 uClibc/ldso/ldso/mips/dl-sysdep.h:1.11
--- uClibc/ldso/ldso/mips/dl-sysdep.h:1.10	Sat Jun 19 15:33:04 2004
+++ uClibc/ldso/ldso/mips/dl-sysdep.h	Thu Aug 26 05:30:48 2004
@@ -42,6 +42,8 @@
 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)
 
Index: uClibc/ldso/ldso/mips/elfinterp.c
diff -u uClibc/ldso/ldso/mips/elfinterp.c:1.19 uClibc/ldso/ldso/mips/elfinterp.c:1.20
--- uClibc/ldso/ldso/mips/elfinterp.c:1.19	Wed Aug 25 17:10:43 2004
+++ uClibc/ldso/ldso/mips/elfinterp.c	Thu Aug 26 05:30:48 2004
@@ -178,6 +178,7 @@
 	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 @@
 #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 @@
 	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
 }



More information about the uClibc-cvs mailing list