[uClibc][PATCH] Fixes for MIPS dynamic linker...

Steven J. Hill sjhill at realitydiluted.com
Tue May 7 20:42:09 UTC 2002


Greetings again.

Uh, this patch fixes a few bugs that I overlooked. Shoot, even BusyBox
wouldn't work until these are applied. Erik, plop this into CVS please.
Thanks.

-Steve

diff -urN uclibc/ldso/ldso/hash.c uclibc-patched/ldso/ldso/hash.c
--- uclibc/ldso/ldso/hash.c	Thu May  2 07:44:52 2002
+++ uclibc-patched/ldso/ldso/hash.c	Tue May  7 07:31:55 2002
@@ -125,6 +125,21 @@
 	tpnt->loadaddr = loadaddr;
 	for (i = 0; i < 24; i++)
 		tpnt->dynamic_info[i] = dynamic_info[i];
+#ifdef __mips__
+	{
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+		while(dpnt->d_tag) {
+			if (dpnt->d_tag == DT_MIPS_GOTSYM)
+				tpnt->mips_gotsym = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+				tpnt->mips_local_gotno = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+				tpnt->mips_symtabno = dpnt->d_un.d_val;
+			dpnt++;
+		}
+	}
+#endif
 	return tpnt;
 }
 
@@ -235,7 +250,8 @@
 					(ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
 					 ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
 					 ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-					symtab[si].st_value != 0) {
+					symtab[si].st_value != 0 &&
+					symtab[si].st_shndx != 0) {
 
 					/* Here we make sure that we find a module where the symbol is
 					 * actually defined.
diff -urN uclibc/ldso/ldso/ldso.c uclibc-patched/ldso/ldso/ldso.c
--- uclibc/ldso/ldso/ldso.c	Thu May  2 07:44:52 2002
+++ uclibc-patched/ldso/ldso/ldso.c	Tue May  7 15:32:35 2002
@@ -368,12 +368,6 @@
 	/* OK, that was easy.  Next scan the DYNAMIC section of the image.
 	   We are only doing ourself right now - we will have to do the rest later */
 	while (dpnt->d_tag) {
-		if (dpnt->d_tag < 24) {
-			tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-			if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT) {
-				tpnt->dynamic_info[DT_TEXTREL] = 1;
-			}
-		}
 #if defined(__mips__)
 		if (dpnt->d_tag == DT_MIPS_GOTSYM)
 			tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
@@ -382,6 +376,12 @@
 		if (dpnt->d_tag == DT_MIPS_SYMTABNO)
 			tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
 #endif
+		if (dpnt->d_tag < 24) {
+			tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT) {
+				tpnt->dynamic_info[DT_TEXTREL] = 1;
+			}
+		}
 		dpnt++;
 	}
 
@@ -473,9 +473,10 @@
 #endif
 
 
-	/* For MIPS, we have to do special stuff to the GOT before we do
-	   any relocations. */
 #if defined(__mips__)
+	/*
+	 * For MIPS we have to do stuff to the GOT before we do relocations.
+	 */
 	PERFORM_BOOTSTRAP_GOT(got);
 #endif
 
@@ -612,11 +613,6 @@
 	struct elf_resolve *tpnt1;
 	unsigned long brk_addr, *lpnt;
 	int (*_dl_atexit) (void *);
-#ifdef __mips__
-	unsigned long mips_gotsym = 0;
-	unsigned long mips_local_gotno = 0;
-	unsigned long mips_symtabno = 0;
-#endif
 
 
 	/* Now we have done the mandatory linking of some things.  We are now
@@ -649,7 +645,20 @@
 		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
 			if (ppnt->p_type == PT_DYNAMIC) {
 				tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
+#if defined(__mips__)
+				{
+					int i = 1;
+					Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+
+					while(dpnt->d_tag) {
+						dpnt++;
+						i++;
+					}
+					tpnt->dynamic_size = i * sizeof(Elf32_Dyn);
+				}
+#else
 				tpnt->dynamic_size = ppnt->p_filesz;
+#endif
 			}
 		}
 	}
@@ -674,31 +683,38 @@
 				continue;
 #endif
 			/* OK, we have what we need - slip this one into the list. */
-#ifdef __mips__
-			mips_gotsym = app_tpnt->mips_gotsym;
-			mips_local_gotno = app_tpnt->mips_local_gotno;
-			mips_symtabno = app_tpnt->mips_symtabno;
-#endif
+#if defined(__mips__)
+			{
+				int i = 1;
+				Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+
+				while(dpnt->d_tag) {
+					dpnt++;
+					i++;
+				}
+				app_tpnt = _dl_add_elf_hash_table("", 0, 
+					app_tpnt->dynamic_info, ppnt->p_vaddr,
+					(i * sizeof(Elf32_Dyn)));
+			}
+#else
 			app_tpnt = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+#endif
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->ppnt = (elf_phdr *) auxvt[AT_PHDR].a_un.a_ptr;
 			_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
-#ifdef __mips__
-			_dl_loaded_modules->mips_gotsym = mips_gotsym; 
-			_dl_loaded_modules->mips_local_gotno = mips_local_gotno;
-			_dl_loaded_modules->mips_symtabno = mips_symtabno;
-#endif
 			_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(*rpnt));
 			rpnt->dyn = _dl_loaded_modules;
 			app_tpnt->usage_count++;
 			app_tpnt->symbol_scope = _dl_symbol_tables;
 			lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+#ifndef __mips__
 #ifdef ALLOW_ZERO_PLTGOT
 			if (lpnt)
 #endif
 				INIT_GOT(lpnt, _dl_loaded_modules);
+#endif
 		}
 
 		/* OK, fill this in - we did not have this before */
@@ -1065,6 +1081,7 @@
 
 	_dl_brkp =
 		(unsigned long *) _dl_find_hash("___brk_addr", NULL, NULL, 0);
+	
 	if (_dl_brkp) {
 		*_dl_brkp = brk_addr;
 	}
@@ -1074,6 +1091,11 @@
 	if (_dl_envp) {
 		*_dl_envp = (unsigned long) envp;
 	}
+
+#ifdef __mips__
+	lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+	INIT_GOT(lpnt, _dl_loaded_modules);
+#endif
 
 #ifdef DO_MPROTECT_HACKS
 	{
diff -urN uclibc/ldso/ldso/mips/ld_sysdep.h uclibc-patched/ldso/ldso/mips/ld_sysdep.h
--- uclibc/ldso/ldso/mips/ld_sysdep.h	Thu May  2 07:44:52 2002
+++ uclibc-patched/ldso/ldso/mips/ld_sysdep.h	Tue May  7 14:52:36 2002
@@ -20,7 +20,7 @@
 
 
 /*
- * Initialization sequence for the application GOT.
+ * Initialization sequence for the application or library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)										\
 do {																	\
@@ -56,12 +56,12 @@
 					(unsigned long) MODULE->loadaddr;					\
 			else {														\
 				*GOT_BASE = (unsigned long) _dl_find_hash(strtab +		\
-					sym->st_name, MODULE->symbol_scope, NULL, 0);		\
+					sym->st_name, MODULE->symbol_scope, NULL, 1);		\
 			}															\
 		}																\
 		else if (sym->st_shndx == SHN_COMMON) {							\
 			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
 		}																\
 		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
 			*GOT_BASE != sym->st_value)									\
@@ -72,7 +72,7 @@
 		}																\
 		else {															\
 			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
 		}																\
 																		\
 		++GOT_BASE;														\
diff -urN uclibc/ldso/ldso/mips/resolve.S uclibc-patched/ldso/ldso/mips/resolve.S
--- uclibc/ldso/ldso/mips/resolve.S	Thu May  2 07:44:52 2002
+++ uclibc-patched/ldso/ldso/mips/resolve.S	Tue May  7 14:52:05 2002
@@ -23,18 +23,22 @@
 	addu	$25, 8		# t9 ($25) now points at .cpload instruction
 	.cpload	$25		# Compute GP
 	.set reorder
-	subu	$29, 32
-	.cprestore 28
+	subu	$29, 40
+	.cprestore 32
+	sw	$15, 36($29)
 	sw	$4, 16($29)
 	sw	$5, 20($29)
-	sw	$15, 24($29)
+	sw	$6, 24($29)
+	sw	$7, 28($29)
 	move	$4, $24
 	move	$5, $3
 	jal     _dl_linux_resolver
-	lw	$31, 24($29)
+	lw	$31, 36($29)
 	lw	$4, 16($29)
 	lw	$5, 20($29)
-	addu	$29, 32
+	lw	$6, 24($29)
+	lw	$7, 28($29)
+	addu	$29, 40
 	move	$25, $2
 	jr	$25
 .size _dl_linux_resolve,.-_dl_linux_resolve
diff -urN uclibc/ldso/ldso/readelflib1.c uclibc-patched/ldso/ldso/readelflib1.c
--- uclibc/ldso/ldso/readelflib1.c	Thu May  2 07:44:52 2002
+++ uclibc-patched/ldso/ldso/readelflib1.c	Mon May  6 12:31:58 2002
@@ -315,11 +315,6 @@
 	unsigned long minvma = 0xffffffff, maxvma = 0;
 	int i;
 	int infile;
-#if defined(__mips__)
-	unsigned long mips_gotsym = 0;
-	unsigned long mips_local_gotno = 0;
-	unsigned long mips_symtabno = 0;
-#endif
 
 	/* If this file is already loaded, skip this step */
 	tpnt = _dl_check_hashed_files(libname);
@@ -527,24 +522,21 @@
 
 	dpnt = (Elf32_Dyn *) dynamic_addr;
 
+#if defined(__mips__)
+	{
+		int i = 1;
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+		while(dpnt->d_tag) {
+			dpnt++;
+			i++;
+		}
+		dynamic_size = i * sizeof(Elf32_Dyn);
+	}
+#endif
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-#if defined(__mips__)
-	/*
-	 * The program header file size for the dynamic section is
-	 * calculated differently for MIPS. We look for a null tag
-	 * value instead.
-	 */
-	while(dpnt->d_tag) {
-		if (dpnt->d_tag == DT_MIPS_GOTSYM)
-			mips_gotsym = (unsigned long) dpnt->d_un.d_val;
-		if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
-			mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
-		if (dpnt->d_tag == DT_MIPS_SYMTABNO)
-			mips_symtabno = (unsigned long) dpnt->d_un.d_val;
-#else
 	for (i = 0; i < dynamic_size; i++) {
-#endif
 		if (dpnt->d_tag > DT_JMPREL) {
 			dpnt++;
 			continue;
@@ -600,11 +592,6 @@
 	if (lpnt) {
 		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
 			((int) libaddr));
-#if defined(__mips__)
-		tpnt->mips_gotsym = mips_gotsym;
-		tpnt->mips_local_gotno = mips_local_gotno;
-		tpnt->mips_symtabno = mips_symtabno;
-#endif
 		INIT_GOT(lpnt, tpnt);
 	};
 



More information about the uClibc mailing list