[uClibc][PATCH] More MIPS dynamic linker patches...

Steven J. Hill sjhill at realitydiluted.com
Thu Apr 18 21:15:24 UTC 2002


Greetings.

This is another patch for more of the MIPS dynamic linker. The
resolver code is being called which means it's almost done!
Currently the stack and registers are getting smashed, so there
is some tweaking to do, but it's really close! Please apply.

-Steve

diff -urN uclibc/Makefile uclibc-patched/Makefile
--- uclibc/Makefile	Mon Apr 15 07:30:02 2002
+++ uclibc-patched/Makefile	Thu Apr 18 14:51:14 2002
@@ -347,6 +347,7 @@
 	    $(MAKE) -C libc/sysdeps/linux/$(TARGET_ARCH) clean;		\
 	fi;
 	- find . \( -name \*.o -o -name \*.a -o -name \*.so -o -name core -o -name .\#\* \) -exec rm -f {} \;
+	- find -type l -exec rm -f {} \;
 
 dist release: distclean
 	cd ..;					\
diff -urN uclibc/ldso/ldso/Makefile uclibc-patched/ldso/ldso/Makefile
--- uclibc/ldso/ldso/Makefile	Thu Mar 21 11:39:07 2002
+++ uclibc-patched/ldso/ldso/Makefile	Tue Apr 16 14:24:52 2002
@@ -34,8 +34,9 @@
 XXFLAGS+= -DDL_TRACE
 
 # Enable this to enable debugging output from ld.so
-#XXFLAGS+= -DDL_DEBUG
-#XXFLAGS+= -DDL_DEBUG_SYMBOLS
+XXFLAGS+= -DDL_DEBUG
+XXFLAGS+= -DDL_DEBUG_SYMBOLS
+#XXFLAGS+= -DSJH
 #Enable this to never actually fixup symbols so you can watch each call...
 #XXFLAGS+= -DDL_NEVER_FIXUP_SYMBOLS
 
@@ -50,9 +51,9 @@
 AOBJS=$(patsubst %.S,%.o, $(ASRC))
 OBJS=$(AOBJS) $(COBJS)
 
-ifneq ($(strip $(DODEBUG)),true)
-LDFLAGS+=-s
-endif
+#ifneq ($(strip $(DODEBUG)),true)
+#LDFLAGS+=-s
+#endif
 
 all: lib
 
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	Tue Apr 16 16:08:13 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
@@ -608,6 +613,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 +625,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 +639,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 +655,6 @@
 		}
 	}
 
-	tpnt->chains = hash_addr;
-	tpnt->loadaddr = (char *) load_addr;
-
 	brk_addr = 0;
 	rpnt = NULL;
 
@@ -665,11 +675,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 +794,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 +821,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 +873,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 +897,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 +948,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 +970,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 +1065,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 +1094,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 +1205,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	Tue Apr 16 15:46:09 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/mips/README uclibc-patched/ldso/ldso/mips/README
--- uclibc/ldso/ldso/mips/README	Tue Apr  2 15:12:37 2002
+++ uclibc-patched/ldso/ldso/mips/README	Thu Apr  4 09:41:13 2002
@@ -7,22 +7,18 @@
 ------------
 Contains code to fix up the stack pointer so that the dynamic
 linker can find argc, argv and Auxillary Vector Table (AVT).
-The codes is taken from the function 'RTLD_START' in the
-file 'sysdeps/mips/dl-machine.h'.
+The code is taken from the function 'RTLD_START' in the file
+'sysdeps/mips/dl-machine.h'.
 
 elfinterp.c
 -----------
-Contains '_dl_init_got' which initializes the GOT for the
-application being dynamically linked and loaded. The code is
-taken from the functions 'elf_machine_runtime_setup' and 
-'elf_machine_got_rel' in the file 'sysdeps/mips/dl-machine.h'.
 
 ld_syscalls.h
 -------------
-Contains all the macro function prototypes for the system calls
-as well as the list of system calls supported. The macros were
-taken from the Linux kernel source 2.4.17 found in the file
-'include/asm-mips/unistd.h'.
+Contains all the macro functions for the system calls as well
+as the list of system calls supported. The functions were taken
+from the Linux kernel source 2.4.17 and can be found in the
+file 'include/asm-mips/unistd.h'.
 
 ld_sysdep.h
 -----------
@@ -31,13 +27,17 @@
 function 'PERFORM_BOOTSTRAP_GOT' is used to relocate the dynamic
 linker's GOT so that function calls can be made. The code is
 taken from the function 'ELF_MACHINE_BEFORE_RTLD_RELOC' in the
-file 'sysdep/mips/dl-machine.h'. The other macro function
+file 'sysdeps/mips/dl-machine.h'. The other macro function
 'PERFORM_BOOTSTRAP_RELOC' is used to do the relocations for
 the dynamic loader. The code is taken from the function
-'elf_machine_rel' in the file 'sysdep/mips/dl-machine.h'.
+'elf_machine_rel' in the file 'sysdeps/mips/dl-machine.h'. The
+final macro function is 'INIT_GOT' which initializes the GOT
+for the application being dynamically linked and loaded. The
+code is taken from the functions 'elf_machine_runtime_setup'
+and 'elf_machine_got_rel' in 'sysdeps/mips/dl-machine.h'.
 
 resolve.S
 ---------
 Contains the low-level assembly code for the dynamic runtime
 resolver. The code is taken from the assembly code function
-'_dl_runtime_resolve' in the file 'sysdesp/mips/dl-machine.h'.
+'_dl_runtime_resolve' in the file 'sysdeps/mips/dl-machine.h'.
diff -urN uclibc/ldso/ldso/mips/elfinterp.c uclibc-patched/ldso/ldso/mips/elfinterp.c
--- uclibc/ldso/ldso/mips/elfinterp.c	Tue Apr  2 15:12:37 2002
+++ uclibc-patched/ldso/ldso/mips/elfinterp.c	Wed Apr 17 16:11:47 2002
@@ -1,3 +1,5 @@
+/* vi: set sw=4 ts=4: */
+
 /* Run an ELF binary on a linux system.
 
    Copyright (C) 1993, Eric Youngdale.
@@ -32,18 +34,102 @@
 
 extern int _dl_linux_resolve(void);
 
-void _dl_init_got(unsigned long *got, struct elf_resolve *tpnt)
+//unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+void _dl_linux_resolver(void)
+{
+	unsigned long foo;
+
+	__asm__("\tmove %0, $7\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tmove %0, $15\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tmove %0, $24\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tmove %0, $25\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tmove %0, $28\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tmove %0, $29\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tmove %0, $31\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tlw %0, 0($25)\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+	__asm__("\tlw %0, 0($29)\t\n":"=r"(foo));
+	SEND_ADDRESS_STDERR(foo,1);
+
+while(1);
+//	return 0;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type)
 {
+	/* Nothing to do */
 	return;
 }
 
-unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
+int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
+	unsigned long rel_size, int type)
 {
+	/* Nothing to do */
 	return 0;
 }
-
+        
 int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
 	unsigned long rel_addr, unsigned long rel_size, int type)
 {
-	return 1;
+	Elf32_Sym *symtab;
+	Elf32_Rel *rpnt;
+	char *strtab;
+	unsigned long *got;
+	unsigned long *reloc_addr;
+	unsigned long symbol_addr;
+	int i, reloc_type, symtab_index;
+
+	/* Now parse the relocation information */
+	rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
+	rel_size = rel_size / sizeof(Elf32_Rel);
+
+	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+	got = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
+
+	for (i = 0; i < rel_size; i++, rpnt++) {
+		reloc_addr = (unsigned long *) (tpnt->loadaddr +
+			(unsigned long) rpnt->r_offset);
+		reloc_type = ELF32_R_TYPE(rpnt->r_info);
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+		symbol_addr = 0;
+
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+
+		switch (reloc_type) {
+		case R_MIPS_REL32:
+			if (symtab_index) {
+				if (symtab_index < tpnt->mips_gotsym)
+					*reloc_addr +=
+						symtab[symtab_index].st_value +
+						(unsigned long) tpnt->loadaddr;
+				else {
+					*reloc_addr += got[symtab_index + tpnt->mips_local_gotno -
+						tpnt->mips_gotsym];
+				}
+			}
+			else {
+				*reloc_addr += (unsigned long) tpnt->loadaddr;
+			}
+			break;
+		case R_MIPS_NONE:
+			break;
+		default:
+			_dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
+			if (symtab_index)
+				_dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+			_dl_exit(1);
+		};
+
+	};
+	return 0;
 }
diff -urN uclibc/ldso/ldso/mips/ld_sysdep.h uclibc-patched/ldso/ldso/mips/ld_sysdep.h
--- uclibc/ldso/ldso/mips/ld_sysdep.h	Tue Apr  9 10:46:45 2002
+++ uclibc-patched/ldso/ldso/mips/ld_sysdep.h	Wed Apr 17 14:06:03 2002
@@ -1,3 +1,5 @@
+/* vi: set sw=4 ts=4: */
+
 /*
  * Various assmbly language/system dependent  hacks that are required
  * so that we can minimize the amount of platform specific code.
@@ -20,46 +22,112 @@
 /*
  * Initialization sequence for the application GOT.
  */
-#define INIT_GOT(GOT_BASE,MODULE)	_dl_init_got(GOT_BASE,MODULE)
+#define INIT_GOT(GOT_BASE,MODULE)										\
+do {																	\
+	Elf32_Sym *sym;														\
+	char *strtab;														\
+	unsigned long i;													\
+																		\
+	/* Check if this is the dynamic linker itself */					\
+	if (MODULE->libtype == program_interpreter)							\
+		continue;														\
+																		\
+	/* Fill in first two GOT entries according to the ABI */			\
+	GOT_BASE[0] = (unsigned long) _dl_linux_resolver;					\
+	GOT_BASE[1] = (unsigned long) MODULE;								\
+																		\
+	/* Add load address displacement to all local GOT entries */		\
+	i = 2;																\
+	while (i < MODULE->mips_local_gotno)								\
+		GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;				\
+																		\
+	/* Handle global GOT entries */										\
+	GOT_BASE += MODULE->mips_local_gotno;								\
+	sym = (Elf32_Sym *) (MODULE->dynamic_info[DT_SYMTAB] +				\
+		(unsigned long) MODULE->loadaddr) + MODULE->mips_gotsym;		\
+	strtab = (char *) (MODULE->dynamic_info[DT_STRTAB] +				\
+		(unsigned long) MODULE->loadaddr);								\
+	i = MODULE->mips_symtabno - MODULE->mips_gotsym;					\
+	while (i--) {														\
+		if (sym->st_shndx == SHN_UNDEF) {								\
+			if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
+				sym->st_value)											\
+				*GOT_BASE = sym->st_value +								\
+					(unsigned long) MODULE->loadaddr;					\
+			else {														\
+				*GOT_BASE = (unsigned long) _dl_find_hash(strtab +		\
+					sym->st_name, MODULE->symbol_scope, NULL, 0);		\
+				if (*GOT_BASE == 0)										\
+					_dl_dprintf(2, "INIT_GOT(SHN_UNDEF) zero: %s\n",	\
+						strtab + sym->st_name);							\
+			}															\
+		}																\
+		else if (sym->st_shndx == SHN_COMMON) {							\
+			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
+				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				if (*GOT_BASE == 0)										\
+					_dl_dprintf(2, "INIT_GOT(SHN_COMMON) zero: %s\n",	\
+						strtab + sym->st_name);							\
+		}																\
+		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
+			*GOT_BASE != sym->st_value)									\
+			*GOT_BASE += (unsigned long) MODULE->loadaddr;				\
+		else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {			\
+			if (sym->st_other == 0)										\
+				*GOT_BASE += (unsigned long) MODULE->loadaddr;			\
+		}																\
+		else {															\
+			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
+				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				if (*GOT_BASE == 0)										\
+					_dl_dprintf(2, "INIT_GOT(END) zero: %s\n",			\
+						strtab + sym->st_name);							\
+		}																\
+																		\
+		++GOT_BASE;														\
+		++sym;															\
+	}																	\
+} while (0)
 
 
 /*
- * Here is a macro to perform the GOT relocation.  This is only
+ * Here is a macro to perform the GOT relocation. This is only
  * used when bootstrapping the dynamic loader.
  */
-#define PERFORM_BOOTSTRAP_GOT(got)					\
-do {									\
-	Elf32_Sym *sym;							\
-	unsigned long i;						\
-									\
-	/* Add load address displacement to all local GOT entries */	\
-	i = 2;								\
-	while (i < mips_local_gotno)					\
-		got[i++] += load_addr;					\
-									\
-	/* Handle global GOT entries */					\
-	got += mips_local_gotno;					\
-	sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +		\
-		 load_addr) + mips_gotsym;				\
-	i = mips_symtabno - mips_gotsym;				\
-									\
-	while (i--) {							\
-		if (sym->st_shndx == SHN_UNDEF ||			\
-			sym->st_shndx == SHN_COMMON)			\
-			*got = load_addr + sym->st_value;		\
-		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&	\
-			*got != sym->st_value)				\
-			*got += load_addr;				\
-		else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {	\
-			if (sym->st_other == 0)				\
-				*got += load_addr;			\
-		}							\
-		else							\
-			*got = load_addr + sym->st_value;		\
-									\
-		got++;							\
-		sym++;							\
-	}								\
+#define PERFORM_BOOTSTRAP_GOT(got)										\
+do {																	\
+	Elf32_Sym *sym;														\
+	unsigned long i;													\
+																		\
+	got[0] = (unsigned long) _dl_linux_resolver;						\
+	/* Add load address displacement to all local GOT entries */		\
+	i = 2;																\
+	while (i < tpnt->mips_local_gotno)									\
+		got[i++] += load_addr;											\
+																		\
+	/* Handle global GOT entries */										\
+	got += tpnt->mips_local_gotno;										\
+	sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +				\
+		 load_addr) + tpnt->mips_gotsym;								\
+	i = tpnt->mips_symtabno - tpnt->mips_gotsym;						\
+																		\
+	while (i--) {														\
+		if (sym->st_shndx == SHN_UNDEF ||								\
+			sym->st_shndx == SHN_COMMON)								\
+			*got = load_addr + sym->st_value;							\
+		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
+			*got != sym->st_value)										\
+			*got += load_addr;											\
+		else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {			\
+			if (sym->st_other == 0)										\
+				*got += load_addr;										\
+		}																\
+		else															\
+			*got = load_addr + sym->st_value;							\
+																		\
+		got++;															\
+		sym++;															\
+	}																	\
 } while (0)
 
 
@@ -67,22 +135,22 @@
  * Here is a macro to perform a relocation.  This is only used when
  * bootstrapping the dynamic loader.
  */
-#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)			\
-	switch(ELF32_R_TYPE((RELP)->r_info)) {				\
-	case R_MIPS_REL32:						\
-		if (symtab_index) {					\
-			if (symtab_index < mips_gotsym)			\
-				*REL += SYMBOL + LOAD;			\
-		}							\
-		else {							\
-			*REL += LOAD;					\
-		}							\
-		break;							\
-	case R_MIPS_NONE:						\
-		break;							\
-	default:							\
-		SEND_STDERR("Aiieeee!");				\
-		_dl_exit(1);						\
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)					\
+	switch(ELF32_R_TYPE((RELP)->r_info)) {								\
+	case R_MIPS_REL32:													\
+		if (symtab_index) {												\
+			if (symtab_index < tpnt->mips_gotsym)						\
+				*REL += SYMBOL;											\
+		}																\
+		else {															\
+			*REL += LOAD;												\
+		}																\
+		break;															\
+	case R_MIPS_NONE:													\
+		break;															\
+	default:															\
+		SEND_STDERR("Aiieeee!");										\
+		_dl_exit(1);													\
 	}
 
 
@@ -104,8 +172,7 @@
 
 
 struct elf_resolve;
-extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt,
-	int reloc_entry);
-void _dl_init_got(unsigned long *got, struct elf_resolve *tpnt);
+//unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+void _dl_linux_resolver(void);
 
 #define do_rem(result, n, base)  result = (n % base)
diff -urN uclibc/ldso/ldso/mips/resolve.S uclibc-patched/ldso/ldso/mips/resolve.S
--- uclibc/ldso/ldso/mips/resolve.S	Tue Mar 19 11:05:51 2002
+++ uclibc-patched/ldso/ldso/mips/resolve.S	Wed Apr 17 15:51:24 2002
@@ -43,6 +43,6 @@
 	lw	$7, 28($29)
 	addu	$29, 40
 	move	$25, $2
-        jr	$25
+	jr	$25
 .size _dl_linux_resolve,.-_dl_linux_resolve
 .end _dl_linux_resolve
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