[uClibc][PATCH] MIPS dynamic linker patch (2/2) for 20020425...

Steven J. Hill sjhill at realitydiluted.com
Thu Apr 25 13:51:32 UTC 2002


This patch changes the function prototypes for '_dl_find_hash' and
'_dl_load_shared_library'. In '_dl_find_hash' the 'instr_addr' 
argument has been removed since it is not used by anyone. In the
'_dl_load_shared_library' function, an argument has been added that
passes the 'struct dyn_elf *rpnt' for each loaded object down to
lower functions. This is needed for MIPS, but has the side effect 
of reducing code size as the code was duplicated three places in
'ldso.c' and is not only duplicated two places instead in 'hash.c'.
Please apply.

-Steve

diff -urN uclibc/ldso/ldso/arm/elfinterp.c uclibc-patched/ldso/ldso/arm/elfinterp.c
--- uclibc/ldso/ldso/arm/elfinterp.c	Thu Mar 21 11:39:07 2002
+++ uclibc-patched/ldso/ldso/arm/elfinterp.c	Tue Apr 16 13:10:24 2002
@@ -89,7 +89,7 @@
 
 	/* Get the address of the GOT entry */
 	new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-		tpnt->symbol_scope, (unsigned long) got_addr, tpnt, 0);
+		tpnt->symbol_scope, tpnt, 0);
 	if (!new_addr) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 			_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -221,7 +221,7 @@
 				continue;
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-					tpnt->symbol_scope, (unsigned long) reloc_addr, 
+					tpnt->symbol_scope,
 					(reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), 0);
 
 			/*
@@ -350,7 +350,7 @@
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 				symtab[symtab_index].st_name, xpnt->next, 
-				(unsigned long) reloc_addr, NULL, 1);
+				NULL, 1);
 			if (!symbol_addr) {
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 					_dl_progname, strtab + symtab[symtab_index].st_name);
diff -urN uclibc/ldso/ldso/arm/resolve.S uclibc-patched/ldso/ldso/arm/resolve.S
--- uclibc/ldso/ldso/arm/resolve.S	Tue Jul  3 13:28:09 2001
+++ uclibc-patched/ldso/ldso/arm/resolve.S	Tue Apr  9 13:39:35 2002
@@ -13,8 +13,6 @@
  * where the jump symbol is _really_ supposed to have jumped to and returns
  * that to us.  Once we have that, we overwrite tpnt with this fixed up
  * address. We then clean up after ourselves, put all the registers back how we
- * found them, then we jump to where the fixed up address, which is where the
- * jump symbol that got us here really wanted to jump to in the first place.
  * found them, then we jump to the fixed up address, which is where the jump
  * symbol that got us here really wanted to jump to in the first place.  
  *  -Erik Andersen
diff -urN uclibc/ldso/ldso/hash.c uclibc-patched/ldso/ldso/hash.c
--- uclibc/ldso/ldso/hash.c	Wed Jan 23 10:04:38 2002
+++ uclibc-patched/ldso/ldso/hash.c	Tue Apr 16 16:42:33 2002
@@ -135,7 +135,7 @@
  */
 
 char *_dl_find_hash(char *name, struct dyn_elf *rpnt1, 
-	unsigned long instr_addr, struct elf_resolve *f_tpnt, int copyrel)
+	struct elf_resolve *f_tpnt, int copyrel)
 {
 	struct elf_resolve *tpnt;
 	int si;
diff -urN uclibc/ldso/ldso/i386/elfinterp.c uclibc-patched/ldso/ldso/i386/elfinterp.c
--- uclibc/ldso/ldso/i386/elfinterp.c	Thu Mar 21 11:39:07 2002
+++ uclibc-patched/ldso/ldso/i386/elfinterp.c	Tue Apr 16 13:09:55 2002
@@ -81,7 +81,7 @@
 
 	/* Get the address of the GOT entry */
 	new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-		tpnt->symbol_scope, (unsigned long) got_addr, tpnt, 0);
+		tpnt->symbol_scope, tpnt, 0);
 	if (!new_addr) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 			_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -188,7 +188,7 @@
 				continue;
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-					tpnt->symbol_scope, (unsigned long) reloc_addr, 
+					tpnt->symbol_scope,
 					(reloc_type == R_386_JMP_SLOT ? tpnt : NULL), 0);
 
 			/*
@@ -294,7 +294,7 @@
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 				symtab[symtab_index].st_name, xpnt->next, 
-				(unsigned long) reloc_addr, NULL, 1);
+				NULL, 1);
 			if (!symbol_addr) {
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 					_dl_progname, strtab + symtab[symtab_index].st_name);
diff -urN uclibc/ldso/ldso/ld_hash.h uclibc-patched/ldso/ldso/ld_hash.h
--- uclibc/ldso/ldso/ld_hash.h	Tue Mar 19 08:41:30 2002
+++ uclibc-patched/ldso/ldso/ld_hash.h	Tue Apr 16 13:03:55 2002
@@ -71,6 +71,13 @@
   unsigned long n_phent;
   Elf32_Phdr * ppnt;
 
+#if defined(__mips__)
+  /* Needed for MIPS relocation */
+  unsigned long mips_gotsym;
+  unsigned long mips_local_gotno;
+  unsigned long mips_symtabno;
+#endif
+
 #ifdef __powerpc__
   /* this is used to store the address of relocation data words, so
    * we don't have to calculate it every time, which requires a divide */
@@ -107,8 +114,7 @@
 	char * loadaddr, unsigned long * dynamic_info, 
 	unsigned long dynamic_addr, unsigned long dynamic_size);
 extern char * _dl_find_hash(char * name, struct dyn_elf * rpnt1, 
-	unsigned long instr_addr, struct elf_resolve * f_tpnt, 
-	int copyrel);
+	struct elf_resolve * f_tpnt, int copyrel);
 extern int _dl_linux_dynamic_link(void);
 
 extern char * _dl_library_path;
diff -urN uclibc/ldso/ldso/ldso.c uclibc-patched/ldso/ldso/ldso.c
--- uclibc/ldso/ldso/ldso.c	Tue Apr  9 10:46:43 2002
+++ uclibc-patched/ldso/ldso/ldso.c	Wed Apr 24 18:45:18 2002
@@ -211,11 +211,6 @@
 	struct r_debug *debug_addr;
 	int indx;
 	int status;
-#if defined(__mips__)
-	unsigned long mips_gotsym = 0;
-	unsigned long mips_local_gotno = 0;
-	unsigned long mips_symtabno = 0;
-#endif
 
 
 	/* WARNING! -- we cannot make _any_ funtion calls until we have
@@ -381,11 +376,11 @@
 		}
 #if defined(__mips__)
 		if (dpnt->d_tag == DT_MIPS_GOTSYM)
-			mips_gotsym = (unsigned long) dpnt->d_un.d_val;
+			tpnt->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;
+			tpnt->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;
+			tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
 #endif
 		dpnt++;
 	}
@@ -399,6 +394,17 @@
 			if (ppnt->p_type == PT_DYNAMIC) {
 				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
 				while (dpnt->d_tag) {
+#if defined(__mips__)
+					if (dpnt->d_tag == DT_MIPS_GOTSYM)
+						app_tpnt->mips_gotsym =
+							(unsigned long) dpnt->d_un.d_val;
+					if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+						app_tpnt->mips_local_gotno =
+							(unsigned long) dpnt->d_un.d_val;
+					if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+						app_tpnt->mips_symtabno =
+							(unsigned long) dpnt->d_un.d_val;
+#endif
 					if (dpnt->d_tag > DT_JMPREL) {
 						dpnt++;
 						continue;
@@ -524,7 +530,6 @@
 				if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
 					continue;
 				symbol_addr = load_addr + symtab[symtab_index].st_value;
-				//SEND_NUMBER_STDERR(symbol_addr,1);
 
 				if (!symbol_addr) {
 					/* This will segfault - you cannot call a function until
@@ -580,7 +585,6 @@
 
 
 
-
 	/* OK we are done here.  Turn out the lights, and lock up. */
 	_dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
 
@@ -608,6 +612,11 @@
 	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
@@ -615,6 +624,13 @@
 	   fixed up by now.  Still no function calls outside of this library ,
 	   since the dynamic resolver is not yet ready. */
 	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+
+	tpnt->chains = hash_addr;
+	tpnt->next = 0;
+	tpnt->libname = 0;
+	tpnt->libtype = program_interpreter;
+	tpnt->loadaddr = (char *) load_addr;
+
 	INIT_GOT(lpnt, tpnt);
 #ifdef DL_DEBUG
 	_dl_dprintf(2, "GOT found at %x\n", tpnt);
@@ -622,10 +638,6 @@
 	/* OK, this was a big step, now we need to scan all of the user images
 	   and load them properly. */
 
-	tpnt->next = 0;
-	tpnt->libname = 0;
-	tpnt->libtype = program_interpreter;
-
 	{
 		elfhdr *epnt;
 		elf_phdr *ppnt;
@@ -642,9 +654,6 @@
 		}
 	}
 
-	tpnt->chains = hash_addr;
-	tpnt->loadaddr = (char *) load_addr;
-
 	brk_addr = 0;
 	rpnt = NULL;
 
@@ -665,11 +674,21 @@
 				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
 			app_tpnt = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
 			_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;
@@ -774,7 +793,7 @@
 			*str2 = '\0';
 			if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
 			{
-				tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
+				tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str);
 				if (!tpnt1) {
 #ifdef DL_TRACE
 					if (_dl_trace_loaded_objects)
@@ -801,14 +820,6 @@
 									(unsigned) tpnt1->loadaddr);
 					}
 #endif
-					rpnt->next = (struct dyn_elf *)
-						_dl_malloc(sizeof(struct dyn_elf));
-					_dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
-					rpnt = rpnt->next;
-					tpnt1->usage_count++;
-					tpnt1->symbol_scope = _dl_symbol_tables;
-					tpnt1->libtype = elf_lib;
-					rpnt->dyn = tpnt1;
 				}
 			}
 			*str2 = c;
@@ -861,7 +872,7 @@
 						c = *cp;
 						*cp = '\0';
 
-						tpnt1 = _dl_load_shared_library(0, NULL, cp2);
+						tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2);
 						if (!tpnt1) {
 #ifdef DL_TRACE
 							if (_dl_trace_loaded_objects)
@@ -885,15 +896,6 @@
 										tpnt1->libname, (unsigned) tpnt1->loadaddr);
 							}
 #endif
-							rpnt->next = (struct dyn_elf *)
-								_dl_malloc(sizeof(struct dyn_elf));
-							_dl_memset(rpnt->next, 0, 
-									sizeof(*(rpnt->next)));
-							rpnt = rpnt->next;
-							tpnt1->usage_count++;
-							tpnt1->symbol_scope = _dl_symbol_tables;
-							tpnt1->libtype = elf_lib;
-							rpnt->dyn = tpnt1;
 						}
 
 						/* find start of next library */
@@ -945,7 +947,8 @@
 					tpnt = NULL;
 					continue;
 				}
-				if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpntstr))) {
+				if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr)))
+				{
 #ifdef DL_TRACE
 					if (_dl_trace_loaded_objects)
 						_dl_dprintf(1, "\t%s => not found\n", lpntstr);
@@ -966,14 +969,6 @@
 						_dl_dprintf(1, "\t%s => %s (0x%x)\n", lpntstr, tpnt1->libname, 
 								(unsigned) tpnt1->loadaddr);
 #endif
-					rpnt->next = (struct dyn_elf *)
-						_dl_malloc(sizeof(struct dyn_elf));
-					_dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
-					rpnt = rpnt->next;
-					tpnt1->usage_count++;
-					tpnt1->symbol_scope = _dl_symbol_tables;
-					tpnt1->libtype = elf_lib;
-					rpnt->dyn = tpnt1;
 				}
 			}
 		}
@@ -1069,12 +1064,12 @@
 
 
 	_dl_brkp =
-		(unsigned long *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
+		(unsigned long *) _dl_find_hash("___brk_addr", NULL, NULL, 0);
 	if (_dl_brkp) {
 		*_dl_brkp = brk_addr;
 	}
 	_dl_envp =
-		(unsigned long *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
+		(unsigned long *) _dl_find_hash("__environ", NULL, NULL, 0);
 
 	if (_dl_envp) {
 		*_dl_envp = (unsigned long) envp;
@@ -1098,7 +1093,7 @@
 
 	}
 #endif
-	_dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
+	_dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, NULL, 0);
 
 	/*
 	 * OK, fix one more thing - set up the debug_addr structure to point
@@ -1209,8 +1204,9 @@
 	void *retval;
 
 #if 0
-//#ifdef DL_DEBUG
+#ifdef DL_DEBUG
 	_dl_dprintf(2, "malloc: request for %d bytes\n", size);
+#endif
 #endif
 
 	if (_dl_malloc_function)
diff -urN uclibc/ldso/ldso/linuxelf.h uclibc-patched/ldso/ldso/linuxelf.h
--- uclibc/ldso/ldso/linuxelf.h	Fri Jan 11 13:57:38 2002
+++ uclibc-patched/ldso/ldso/linuxelf.h	Mon Apr 22 01:00:44 2002
@@ -16,16 +16,16 @@
 extern int _dl_map_cache(void);
 extern int _dl_unmap_cache(void);
 int _dl_copy_fixups(struct dyn_elf * tpnt);
-extern int _dl_parse_relocation_information(struct elf_resolve * tpnt, unsigned long rel_addr,
-       unsigned long rel_size, int type);
-extern void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, unsigned long rel_addr,
-       unsigned long rel_size, int type);
+extern int _dl_parse_copy_information(struct dyn_elf *rpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type);
+extern void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type);
+extern int _dl_parse_relocation_information(struct elf_resolve *tpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type);
 extern struct elf_resolve * _dl_load_shared_library(int secure, 
-				struct elf_resolve *, char * libname);
+	struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname);
 extern struct elf_resolve * _dl_load_elf_shared_library(int secure, 
-				char * libname, int flag);
-extern int _dl_parse_copy_information(struct dyn_elf * rpnt, unsigned long rel_addr,
-       unsigned long rel_size, int type);
+	struct dyn_elf **rpnt, char *libname, int flag);
 extern int _dl_linux_resolve(void);
 #define ELF_CLASS   ELFCLASS32
 
diff -urN uclibc/ldso/ldso/m68k/elfinterp.c uclibc-patched/ldso/ldso/m68k/elfinterp.c
--- uclibc/ldso/ldso/m68k/elfinterp.c	Thu Mar 21 11:39:07 2002
+++ uclibc-patched/ldso/ldso/m68k/elfinterp.c	Tue Apr 16 13:10:51 2002
@@ -90,7 +90,7 @@
 
   /* Get the address of the GOT entry.  */
   new_addr = _dl_find_hash (strtab + symtab[symtab_index].st_name,
-			    tpnt->symbol_scope, (int) got_addr, tpnt, 0);
+			    tpnt->symbol_scope, tpnt, 0);
   if (!new_addr)
     {
       _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
@@ -201,7 +201,7 @@
 	{
 	  symbol_addr = (unsigned int)
 	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
-			   tpnt->symbol_scope, (int) reloc_addr,
+			   tpnt->symbol_scope,
 			   reloc_type == R_68K_JMP_SLOT ? tpnt : NULL, 0);
 
 	  /* We want to allow undefined references to weak symbols -
@@ -327,7 +327,7 @@
 	{
 	  symbol_addr = (unsigned int)
 	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
-			   xpnt->next, (int) reloc_addr, NULL, 1);
+			   xpnt->next, NULL, 1);
 	  if (!symbol_addr)
 	    {
 	      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
diff -urN uclibc/ldso/ldso/powerpc/elfinterp.c uclibc-patched/ldso/ldso/powerpc/elfinterp.c
--- uclibc/ldso/ldso/powerpc/elfinterp.c	Mon Apr 15 07:30:03 2002
+++ uclibc-patched/ldso/ldso/powerpc/elfinterp.c	Thu Apr 18 16:09:33 2002
@@ -161,7 +161,7 @@
 	/* Get the address of the GOT entry */
 	targ_addr = (unsigned long) _dl_find_hash(
 		strtab + symtab[symtab_index].st_name, 
-		tpnt->symbol_scope, insn_addr, tpnt, 0);
+		tpnt->symbol_scope, tpnt, 0);
 	if (!targ_addr) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 			_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -337,7 +337,7 @@
 				continue;
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-					tpnt->symbol_scope, (unsigned long) reloc_addr, 
+					tpnt->symbol_scope,
 					(reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), 0);
 
 			/*
@@ -499,7 +499,7 @@
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 				symtab[symtab_index].st_name, xpnt->next, 
-				(unsigned long) reloc_addr, NULL, 1);
+				NULL, 1);
 			if (!symbol_addr) {
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 					_dl_progname, strtab + symtab[symtab_index].st_name);
diff -urN uclibc/ldso/ldso/readelflib1.c uclibc-patched/ldso/ldso/readelflib1.c
--- uclibc/ldso/ldso/readelflib1.c	Tue Apr  9 10:46:43 2002
+++ uclibc-patched/ldso/ldso/readelflib1.c	Tue Apr 16 16:06:15 2002
@@ -108,14 +108,14 @@
 /* This function's behavior must exactly match that 
  * in uClibc/ldso/util/ldd.c */
 static struct elf_resolve * 
-search_for_named_library(char *name, int secure, const char *path_list)
+search_for_named_library(char *name, int secure, const char *path_list,
+	struct dyn_elf **rpnt)
 {
 	int i, count = 1;
 	char *path, *path_n;
 	char mylibname[2050];
 	struct elf_resolve *tpnt1;
 
-
 	/* We need a writable copy of this string */
 	path = _dl_strdup(path_list);
 	if (!path) {
@@ -140,8 +140,11 @@
 		_dl_strcpy(mylibname, path_n); 
 		_dl_strcat(mylibname, "/"); 
 		_dl_strcat(mylibname, name);
-		if ((tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0)) != NULL)
-		    return tpnt1;
+		if ((tpnt1 = _dl_load_elf_shared_library(secure, rpnt,
+			mylibname, 0)) != NULL)
+		{
+			return tpnt1;
+		}
 		path_n += (_dl_strlen(path_n) + 1);
 	}
 	return NULL;
@@ -156,7 +159,7 @@
 unsigned long _dl_internal_error_number;
 extern char *_dl_ldsopath;
 
-struct elf_resolve *_dl_load_shared_library(int secure, 
+struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
 	struct elf_resolve *tpnt, char *full_libname)
 {
 	char *pnt;
@@ -185,7 +188,7 @@
 	   /usr/i486-sysv4/lib for /usr/lib in library names. */
 
 	if (libname != full_libname) {
-		tpnt1 = _dl_load_elf_shared_library(secure, full_libname, 0);
+		tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname, 0);
 		if (tpnt1)
 			return tpnt1;
 		goto goof;
@@ -204,7 +207,7 @@
 #ifdef DL_DEBUG
 				_dl_dprintf(2, "searching RPATH: '%s'\n", pnt);
 #endif
-				if ((tpnt1 = search_for_named_library(libname, secure, pnt)) != NULL) 
+				if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) 
 				{
 				    return tpnt1;
 				}
@@ -217,7 +220,7 @@
 #ifdef DL_DEBUG
 	    _dl_dprintf(2, "searching _dl_library_path: '%s'\n", _dl_library_path);
 #endif
-	    if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path)) != NULL) 
+	    if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path, rpnt)) != NULL) 
 	    {
 		return tpnt1;
 	    }
@@ -240,7 +243,7 @@
 				 libent[i].flags == LIB_ELF_LIBC5) &&
 				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
 				(tpnt1 = _dl_load_elf_shared_library(secure, 
-				     strs + libent[i].liboffset, 0)))
+				     rpnt, strs + libent[i].liboffset, 0)))
 				return tpnt1;
 		}
 	}
@@ -251,7 +254,7 @@
 #ifdef DL_DEBUG
 	_dl_dprintf(2, "searching in ldso dir: %s\n", _dl_ldsopath);
 #endif
-	if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath)) != NULL) 
+	if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL) 
 	{
 	    return tpnt1;
 	}
@@ -268,7 +271,7 @@
 			UCLIBC_DEVEL_PREFIX "/lib:"
 			UCLIBC_BUILD_DIR "/lib:"
 			"/usr/lib:"
-			"/lib")
+			"/lib", rpnt)
 		    ) != NULL) 
 	{
 	    return tpnt1;
@@ -286,16 +289,15 @@
 	return NULL;
 }
 
+
 /*
  * Read one ELF library into memory, mmap it into the correct locations and
  * add the symbol info to the symbol chain.  Perform any relocations that
  * are required.
  */
 
-//extern _elf_rtbndr(void);
-
-struct elf_resolve *_dl_load_elf_shared_library(int secure, 
-	char *libname, int flag)
+struct elf_resolve *_dl_load_elf_shared_library(int secure,
+	struct dyn_elf **rpnt, char *libname, int flag)
 {
 	elfhdr *epnt;
 	unsigned long dynamic_addr = 0;
@@ -311,14 +313,27 @@
 	unsigned long *lpnt;
 	unsigned long libaddr;
 	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);
-	if (tpnt)
+	if (tpnt) {
+		(*rpnt)->next = (struct dyn_elf *)
+			_dl_malloc(sizeof(struct dyn_elf));
+		_dl_memset((*rpnt)->next, 0, sizeof(*((*rpnt)->next)));
+		*rpnt = (*rpnt)->next;
+		tpnt->usage_count++;
+		tpnt->symbol_scope = _dl_symbol_tables;
+		tpnt->libtype = elf_lib;
+		(*rpnt)->dyn = tpnt;
 		return tpnt;
+	}
 
 	/* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
 	   we don't load the library if it isn't setuid. */
@@ -515,6 +530,14 @@
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
 	for (i = 0; i < dynamic_size; i++) {
+#if defined(__mips__)
+		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;
+#endif
 		if (dpnt->d_tag > DT_JMPREL) {
 			dpnt++;
 			continue;
@@ -548,6 +571,18 @@
 	tpnt->n_phent = epnt->e_phnum;
 
 	/*
+	 * Add this object into the symbol chain
+	 */
+	(*rpnt)->next = (struct dyn_elf *)
+		_dl_malloc(sizeof(struct dyn_elf));
+	_dl_memset((*rpnt)->next, 0, sizeof(*((*rpnt)->next)));
+	*rpnt = (*rpnt)->next;
+	tpnt->usage_count++;
+	tpnt->symbol_scope = _dl_symbol_tables;
+	tpnt->libtype = elf_lib;
+	(*rpnt)->dyn = tpnt;
+
+	/*
 	 * OK, the next thing we need to do is to insert the dynamic linker into
 	 * the proper entry in the GOT so that the PLT symbols can be properly
 	 * resolved. 
@@ -558,6 +593,11 @@
 	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);
 	};
 
diff -urN uclibc/ldso/ldso/sparc/elfinterp.c uclibc-patched/ldso/ldso/sparc/elfinterp.c
--- uclibc/ldso/ldso/sparc/elfinterp.c	Thu Mar 21 11:39:07 2002
+++ uclibc-patched/ldso/ldso/sparc/elfinterp.c	Tue Apr 16 13:11:51 2002
@@ -98,7 +98,7 @@
 
   /* Get the address of the GOT entry */
   new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-  			tpnt->symbol_scope, (int) got_addr, tpnt, 0);
+  			tpnt->symbol_scope, tpnt, 0);
   if(!new_addr) {
     _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
 	       _dl_progname, strtab + symtab[symtab_index].st_name);
@@ -201,7 +201,7 @@
 
       symbol_addr = (unsigned int) 
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
-			      tpnt->symbol_scope, (int) reloc_addr, 
+			      tpnt->symbol_scope,
 		      (reloc_type == R_SPARC_JMP_SLOT ? tpnt : NULL), 0);
 
       if(!symbol_addr &&
@@ -319,7 +319,7 @@
 
       symbol_addr = (unsigned int) 
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
-			      xpnt->next, (int) reloc_addr, NULL, 1);
+			      xpnt->next, NULL, 1);
       if(!symbol_addr) {
 	_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
 		   _dl_progname, strtab + symtab[symtab_index].st_name);
diff -urN uclibc/ldso/libdl/dlib.c uclibc-patched/ldso/libdl/dlib.c
--- uclibc/ldso/libdl/dlib.c	Fri Jan 11 14:11:12 2002
+++ uclibc-patched/ldso/libdl/dlib.c	Wed Apr 17 09:21:34 2002
@@ -108,7 +108,7 @@
 			tfrom = tpnt;
 	}
 
-	if (!(tpnt = _dl_load_shared_library(0, tfrom, libname))) {
+	if (!(tpnt = _dl_load_shared_library(0, &rpnt, tfrom, libname))) {
 #ifdef USE_CACHE
 		_dl_unmap_cache();
 #endif
@@ -145,7 +145,7 @@
 		    {
 		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
 			dpnt->d_un.d_val;
-		      if(!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt)))
+		      if(!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpnt)))
 			goto oops;
 
 		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
@@ -304,7 +304,7 @@
 		}
 	}
 
-	ret = _dl_find_hash(name, handle, 1, NULL, 1);
+	ret = _dl_find_hash(name, handle, NULL, 1);
 
 	/*
 	 * Nothing found.



More information about the uClibc mailing list