Pārlūkot izejas kodu

Patch from Steven J. Hill <sjhill@realitydiluted.com>:

    I am very pleased to announce that the MIPS dynamic linker/loader
    for uClibc is now working. It works on big and little endian
    platforms.

A few minor changes were needed to avoid breaking ldd, and since this
makes some non-trivial changes, I have tested on x86, arm, and powerpc
to be sure thoese arches didn't get broken.  Excellent work Steven!
Eric Andersen 22 gadi atpakaļ
vecāks
revīzija
4a5a81ac16

+ 3 - 3
ldso/ldso/arm/elfinterp.c

@@ -89,7 +89,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
 
 
 	/* Get the address of the GOT entry */
 	/* Get the address of the GOT entry */
 	new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
 	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) {
 	if (!new_addr) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 			_dl_progname, strtab + symtab[symtab_index].st_name);
 			_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -221,7 +221,7 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt,
 				continue;
 				continue;
 
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
 			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);
 					(reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), 0);
 
 
 			/*
 			/*
@@ -350,7 +350,7 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
 
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 				symtab[symtab_index].st_name, xpnt->next, 
 				symtab[symtab_index].st_name, xpnt->next, 
-				(unsigned long) reloc_addr, NULL, 1);
+				NULL, 1);
 			if (!symbol_addr) {
 			if (!symbol_addr) {
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 					_dl_progname, strtab + symtab[symtab_index].st_name);
 					_dl_progname, strtab + symtab[symtab_index].st_name);

+ 0 - 2
ldso/ldso/arm/resolve.S

@@ -13,8 +13,6 @@
  * where the jump symbol is _really_ supposed to have jumped to and returns
  * 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
  * 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
  * 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
  * 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.  
  * symbol that got us here really wanted to jump to in the first place.  
  *  -Erik Andersen
  *  -Erik Andersen

+ 66 - 19
ldso/ldso/dl-elf.c

@@ -108,14 +108,14 @@ int _dl_unmap_cache(void)
 /* This function's behavior must exactly match that 
 /* This function's behavior must exactly match that 
  * in uClibc/ldso/util/ldd.c */
  * in uClibc/ldso/util/ldd.c */
 static struct elf_resolve * 
 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;
 	int i, count = 1;
 	char *path, *path_n;
 	char *path, *path_n;
 	char mylibname[2050];
 	char mylibname[2050];
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
 
 
-
 	/* We need a writable copy of this string */
 	/* We need a writable copy of this string */
 	path = _dl_strdup(path_list);
 	path = _dl_strdup(path_list);
 	if (!path) {
 	if (!path) {
@@ -140,8 +140,11 @@ search_for_named_library(char *name, int secure, const char *path_list)
 		_dl_strcpy(mylibname, path_n); 
 		_dl_strcpy(mylibname, path_n); 
 		_dl_strcat(mylibname, "/"); 
 		_dl_strcat(mylibname, "/"); 
 		_dl_strcat(mylibname, name);
 		_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);
 		path_n += (_dl_strlen(path_n) + 1);
 	}
 	}
 	return NULL;
 	return NULL;
@@ -156,7 +159,7 @@ unsigned long _dl_error_number;
 unsigned long _dl_internal_error_number;
 unsigned long _dl_internal_error_number;
 extern char *_dl_ldsopath;
 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)
 	struct elf_resolve *tpnt, char *full_libname)
 {
 {
 	char *pnt;
 	char *pnt;
@@ -185,7 +188,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 	   /usr/i486-sysv4/lib for /usr/lib in library names. */
 	   /usr/i486-sysv4/lib for /usr/lib in library names. */
 
 
 	if (libname != full_libname) {
 	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)
 		if (tpnt1)
 			return tpnt1;
 			return tpnt1;
 		goto goof;
 		goto goof;
@@ -204,7 +207,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 				_dl_dprintf(2, "searching RPATH: '%s'\n", pnt);
 				_dl_dprintf(2, "searching RPATH: '%s'\n", pnt);
 #endif
 #endif
-				if ((tpnt1 = search_for_named_library(libname, secure, pnt)) != NULL) 
+				if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) 
 				{
 				{
 				    return tpnt1;
 				    return tpnt1;
 				}
 				}
@@ -217,7 +220,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 	    _dl_dprintf(2, "searching _dl_library_path: '%s'\n", _dl_library_path);
 	    _dl_dprintf(2, "searching _dl_library_path: '%s'\n", _dl_library_path);
 #endif
 #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;
 		return tpnt1;
 	    }
 	    }
@@ -240,7 +243,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 				 libent[i].flags == LIB_ELF_LIBC5) &&
 				 libent[i].flags == LIB_ELF_LIBC5) &&
 				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
 				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
 				(tpnt1 = _dl_load_elf_shared_library(secure, 
 				(tpnt1 = _dl_load_elf_shared_library(secure, 
-				     strs + libent[i].liboffset, 0)))
+				     rpnt, strs + libent[i].liboffset, 0)))
 				return tpnt1;
 				return tpnt1;
 		}
 		}
 	}
 	}
@@ -251,7 +254,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 	_dl_dprintf(2, "searching in ldso dir: %s\n", _dl_ldsopath);
 	_dl_dprintf(2, "searching in ldso dir: %s\n", _dl_ldsopath);
 #endif
 #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;
 	    return tpnt1;
 	}
 	}
@@ -268,7 +271,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 			UCLIBC_DEVEL_PREFIX "/lib:"
 			UCLIBC_DEVEL_PREFIX "/lib:"
 			UCLIBC_BUILD_DIR "/lib:"
 			UCLIBC_BUILD_DIR "/lib:"
 			"/usr/lib:"
 			"/usr/lib:"
-			"/lib")
+			"/lib", rpnt)
 		    ) != NULL) 
 		    ) != NULL) 
 	{
 	{
 	    return tpnt1;
 	    return tpnt1;
@@ -286,16 +289,15 @@ goof:
 	return NULL;
 	return NULL;
 }
 }
 
 
+
 /*
 /*
  * Read one ELF library into memory, mmap it into the correct locations and
  * 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
  * add the symbol info to the symbol chain.  Perform any relocations that
  * are required.
  * 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;
 	elfhdr *epnt;
 	unsigned long dynamic_addr = 0;
 	unsigned long dynamic_addr = 0;
@@ -311,14 +313,27 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	unsigned long *lpnt;
 	unsigned long *lpnt;
 	unsigned long libaddr;
 	unsigned long libaddr;
 	unsigned long minvma = 0xffffffff, maxvma = 0;
 	unsigned long minvma = 0xffffffff, maxvma = 0;
-
 	int i;
 	int i;
 	int infile;
 	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 */
 	/* If this file is already loaded, skip this step */
 	tpnt = _dl_check_hashed_files(libname);
 	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;
 		return tpnt;
+	}
 
 
 	/* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
 	/* 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. */
 	   we don't load the library if it isn't setuid. */
@@ -514,7 +529,22 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
 	_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++) {
 	for (i = 0; i < dynamic_size; i++) {
+#endif
 		if (dpnt->d_tag > DT_JMPREL) {
 		if (dpnt->d_tag > DT_JMPREL) {
 			dpnt++;
 			dpnt++;
 			continue;
 			continue;
@@ -526,8 +556,8 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	};
 	};
 
 
 	/* If the TEXTREL is set, this means that we need to make the pages
 	/* If the TEXTREL is set, this means that we need to make the pages
-	   writable before we perform relocations.  Do this now. They get set back
-	   again later. */
+	   writable before we perform relocations.  Do this now. They get set
+	   back again later. */
 
 
 	if (dynamic_info[DT_TEXTREL]) {
 	if (dynamic_info[DT_TEXTREL]) {
 		ppnt = (elf_phdr *) & header[epnt->e_phoff];
 		ppnt = (elf_phdr *) & header[epnt->e_phoff];
@@ -547,6 +577,18 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
 	tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
 	tpnt->n_phent = epnt->e_phnum;
 	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
 	 * 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
 	 * the proper entry in the GOT so that the PLT symbols can be properly
@@ -558,6 +600,11 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	if (lpnt) {
 	if (lpnt) {
 		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
 		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
 			((int) libaddr));
 			((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);
 		INIT_GOT(lpnt, tpnt);
 	};
 	};
 
 

+ 1 - 1
ldso/ldso/dl-hash.c

@@ -135,7 +135,7 @@ struct elf_resolve *_dl_add_elf_hash_table(char *libname,
  */
  */
 
 
 char *_dl_find_hash(char *name, struct dyn_elf *rpnt1, 
 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;
 	struct elf_resolve *tpnt;
 	int si;
 	int si;

+ 1 - 1
ldso/ldso/hash.c

@@ -135,7 +135,7 @@ struct elf_resolve *_dl_add_elf_hash_table(char *libname,
  */
  */
 
 
 char *_dl_find_hash(char *name, struct dyn_elf *rpnt1, 
 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;
 	struct elf_resolve *tpnt;
 	int si;
 	int si;

+ 3 - 3
ldso/ldso/i386/elfinterp.c

@@ -81,7 +81,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
 
 
 	/* Get the address of the GOT entry */
 	/* Get the address of the GOT entry */
 	new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
 	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) {
 	if (!new_addr) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 			_dl_progname, strtab + symtab[symtab_index].st_name);
 			_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -188,7 +188,7 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt,
 				continue;
 				continue;
 
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
 			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);
 					(reloc_type == R_386_JMP_SLOT ? tpnt : NULL), 0);
 
 
 			/*
 			/*
@@ -294,7 +294,7 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
 
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 				symtab[symtab_index].st_name, xpnt->next, 
 				symtab[symtab_index].st_name, xpnt->next, 
-				(unsigned long) reloc_addr, NULL, 1);
+				NULL, 1);
 			if (!symbol_addr) {
 			if (!symbol_addr) {
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 					_dl_progname, strtab + symtab[symtab_index].st_name);
 					_dl_progname, strtab + symtab[symtab_index].st_name);

+ 8 - 2
ldso/ldso/ld_hash.h

@@ -71,6 +71,13 @@ struct elf_resolve{
   unsigned long n_phent;
   unsigned long n_phent;
   Elf32_Phdr * ppnt;
   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__
 #ifdef __powerpc__
   /* this is used to store the address of relocation data words, so
   /* 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 */
    * we don't have to calculate it every time, which requires a divide */
@@ -107,8 +114,7 @@ extern struct elf_resolve * _dl_add_elf_hash_table(char * libname,
 	char * loadaddr, unsigned long * dynamic_info, 
 	char * loadaddr, unsigned long * dynamic_info, 
 	unsigned long dynamic_addr, unsigned long dynamic_size);
 	unsigned long dynamic_addr, unsigned long dynamic_size);
 extern char * _dl_find_hash(char * name, struct dyn_elf * rpnt1, 
 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 int _dl_linux_dynamic_link(void);
 
 
 extern char * _dl_library_path;
 extern char * _dl_library_path;

+ 49 - 53
ldso/ldso/ldso.c

@@ -211,11 +211,6 @@ DL_BOOT(unsigned long args)
 	struct r_debug *debug_addr;
 	struct r_debug *debug_addr;
 	int indx;
 	int indx;
 	int status;
 	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
 	/* WARNING! -- we cannot make _any_ funtion calls until we have
@@ -381,11 +376,11 @@ DL_BOOT(unsigned long args)
 		}
 		}
 #if defined(__mips__)
 #if defined(__mips__)
 		if (dpnt->d_tag == DT_MIPS_GOTSYM)
 		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)
 		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)
 		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
 #endif
 		dpnt++;
 		dpnt++;
 	}
 	}
@@ -399,6 +394,17 @@ DL_BOOT(unsigned long args)
 			if (ppnt->p_type == PT_DYNAMIC) {
 			if (ppnt->p_type == PT_DYNAMIC) {
 				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
 				dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
 				while (dpnt->d_tag) {
 				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) {
 					if (dpnt->d_tag > DT_JMPREL) {
 						dpnt++;
 						dpnt++;
 						continue;
 						continue;
@@ -524,7 +530,6 @@ DL_BOOT(unsigned long args)
 				if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
 				if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
 					continue;
 					continue;
 				symbol_addr = load_addr + symtab[symtab_index].st_value;
 				symbol_addr = load_addr + symtab[symtab_index].st_value;
-				//SEND_NUMBER_STDERR(symbol_addr,1);
 
 
 				if (!symbol_addr) {
 				if (!symbol_addr) {
 					/* This will segfault - you cannot call a function until
 					/* This will segfault - you cannot call a function until
@@ -580,7 +585,6 @@ DL_BOOT(unsigned long args)
 
 
 
 
 
 
-
 	/* OK we are done here.  Turn out the lights, and lock up. */
 	/* 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;
 	_dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
 
 
@@ -608,6 +612,11 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
 	unsigned long brk_addr, *lpnt;
 	unsigned long brk_addr, *lpnt;
 	int (*_dl_atexit) (void *);
 	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
 	/* Now we have done the mandatory linking of some things.  We are now
@@ -615,6 +624,13 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 	   fixed up by now.  Still no function calls outside of this library ,
 	   fixed up by now.  Still no function calls outside of this library ,
 	   since the dynamic resolver is not yet ready. */
 	   since the dynamic resolver is not yet ready. */
 	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
 	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);
 	INIT_GOT(lpnt, tpnt);
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 	_dl_dprintf(2, "GOT found at %x\n", tpnt);
 	_dl_dprintf(2, "GOT found at %x\n", tpnt);
@@ -622,10 +638,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 	/* OK, this was a big step, now we need to scan all of the user images
 	/* OK, this was a big step, now we need to scan all of the user images
 	   and load them properly. */
 	   and load them properly. */
 
 
-	tpnt->next = 0;
-	tpnt->libname = 0;
-	tpnt->libtype = program_interpreter;
-
 	{
 	{
 		elfhdr *epnt;
 		elfhdr *epnt;
 		elf_phdr *ppnt;
 		elf_phdr *ppnt;
@@ -642,9 +654,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 		}
 		}
 	}
 	}
 
 
-	tpnt->chains = hash_addr;
-	tpnt->loadaddr = (char *) load_addr;
-
 	brk_addr = 0;
 	brk_addr = 0;
 	rpnt = NULL;
 	rpnt = NULL;
 
 
@@ -665,11 +674,21 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 				continue;
 				continue;
 #endif
 #endif
 			/* OK, we have what we need - slip this one into the list. */
 			/* 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 = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->ppnt = (elf_phdr *) auxvt[AT_PHDR].a_un.a_ptr;
 			_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;
 			_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_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(*rpnt));
 			_dl_memset(rpnt, 0, sizeof(*rpnt));
 			rpnt->dyn = _dl_loaded_modules;
 			rpnt->dyn = _dl_loaded_modules;
@@ -774,7 +793,7 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 			*str2 = '\0';
 			*str2 = '\0';
 			if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
 			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) {
 				if (!tpnt1) {
 #ifdef DL_TRACE
 #ifdef DL_TRACE
 					if (_dl_trace_loaded_objects)
 					if (_dl_trace_loaded_objects)
@@ -793,7 +812,7 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 #endif
 #endif
 #ifdef DL_TRACE
 #ifdef DL_TRACE
 					if (_dl_trace_loaded_objects
 					if (_dl_trace_loaded_objects
-							&& !tpnt1->usage_count) {
+							&& tpnt1->usage_count==1) {
 						/* this is a real hack to make ldd not print 
 						/* this is a real hack to make ldd not print 
 						 * the library itself when run on a library. */
 						 * the library itself when run on a library. */
 						if (_dl_strcmp(_dl_progname, str) != 0)
 						if (_dl_strcmp(_dl_progname, str) != 0)
@@ -801,14 +820,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 									(unsigned) tpnt1->loadaddr);
 									(unsigned) tpnt1->loadaddr);
 					}
 					}
 #endif
 #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;
 			*str2 = c;
@@ -861,7 +872,7 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 						c = *cp;
 						c = *cp;
 						*cp = '\0';
 						*cp = '\0';
 
 
-						tpnt1 = _dl_load_shared_library(0, NULL, cp2);
+						tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2);
 						if (!tpnt1) {
 						if (!tpnt1) {
 #ifdef DL_TRACE
 #ifdef DL_TRACE
 							if (_dl_trace_loaded_objects)
 							if (_dl_trace_loaded_objects)
@@ -880,20 +891,11 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 #endif
 #endif
 #ifdef DL_TRACE
 #ifdef DL_TRACE
 							if (_dl_trace_loaded_objects
 							if (_dl_trace_loaded_objects
-									&& !tpnt1->usage_count) {
+									&& tpnt1->usage_count==1) {
 								_dl_dprintf(1, "\t%s => %s (0x%x)\n", cp2, 
 								_dl_dprintf(1, "\t%s => %s (0x%x)\n", cp2, 
 										tpnt1->libname, (unsigned) tpnt1->loadaddr);
 										tpnt1->libname, (unsigned) tpnt1->loadaddr);
 							}
 							}
 #endif
 #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 */
 						/* find start of next library */
@@ -924,7 +926,7 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 					struct elf_resolve *ttmp;
 					struct elf_resolve *ttmp;
 
 
 #ifdef DL_TRACE
 #ifdef DL_TRACE
-					if (_dl_trace_loaded_objects && !tpnt->usage_count) {
+					if (_dl_trace_loaded_objects && tpnt->usage_count==1) {
 						_dl_dprintf(1, "\t%s => %s (0x%x)\n", 
 						_dl_dprintf(1, "\t%s => %s (0x%x)\n", 
 								lpntstr, tpnt->libname, (unsigned) tpnt->loadaddr);
 								lpntstr, tpnt->libname, (unsigned) tpnt->loadaddr);
 					}
 					}
@@ -945,7 +947,8 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 					tpnt = NULL;
 					tpnt = NULL;
 					continue;
 					continue;
 				}
 				}
-				if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpntstr))) {
+				if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr)))
+				{
 #ifdef DL_TRACE
 #ifdef DL_TRACE
 					if (_dl_trace_loaded_objects)
 					if (_dl_trace_loaded_objects)
 						_dl_dprintf(1, "\t%s => not found\n", lpntstr);
 						_dl_dprintf(1, "\t%s => not found\n", lpntstr);
@@ -962,18 +965,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 					_dl_dprintf(2, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 					_dl_dprintf(2, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 #endif
 #endif
 #ifdef DL_TRACE
 #ifdef DL_TRACE
-					if (_dl_trace_loaded_objects && !tpnt1->usage_count)
+					if (_dl_trace_loaded_objects && tpnt1->usage_count==1)
 						_dl_dprintf(1, "\t%s => %s (0x%x)\n", lpntstr, tpnt1->libname, 
 						_dl_dprintf(1, "\t%s => %s (0x%x)\n", lpntstr, tpnt1->libname, 
 								(unsigned) tpnt1->loadaddr);
 								(unsigned) tpnt1->loadaddr);
 #endif
 #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 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 
 
 
 
 	_dl_brkp =
 	_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) {
 	if (_dl_brkp) {
 		*_dl_brkp = brk_addr;
 		*_dl_brkp = brk_addr;
 	}
 	}
 	_dl_envp =
 	_dl_envp =
-		(unsigned long *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
+		(unsigned long *) _dl_find_hash("__environ", NULL, NULL, 0);
 
 
 	if (_dl_envp) {
 	if (_dl_envp) {
 		*_dl_envp = (unsigned long) envp;
 		*_dl_envp = (unsigned long) envp;
@@ -1098,7 +1093,7 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 
 
 	}
 	}
 #endif
 #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
 	 * OK, fix one more thing - set up the debug_addr structure to point
@@ -1209,8 +1204,9 @@ void *_dl_malloc(int size)
 	void *retval;
 	void *retval;
 
 
 #if 0
 #if 0
-//#ifdef DL_DEBUG
+#ifdef DL_DEBUG
 	_dl_dprintf(2, "malloc: request for %d bytes\n", size);
 	_dl_dprintf(2, "malloc: request for %d bytes\n", size);
+#endif
 #endif
 #endif
 
 
 	if (_dl_malloc_function)
 	if (_dl_malloc_function)

+ 8 - 8
ldso/ldso/linuxelf.h

@@ -16,16 +16,16 @@ extern void * _dl_malloc(int size);
 extern int _dl_map_cache(void);
 extern int _dl_map_cache(void);
 extern int _dl_unmap_cache(void);
 extern int _dl_unmap_cache(void);
 int _dl_copy_fixups(struct dyn_elf * tpnt);
 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, 
 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, 
 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);
 extern int _dl_linux_resolve(void);
 #define ELF_CLASS   ELFCLASS32
 #define ELF_CLASS   ELFCLASS32
 
 

+ 3 - 3
ldso/ldso/m68k/elfinterp.c

@@ -90,7 +90,7 @@ unsigned int _dl_linux_resolver (int dummy1, int dummy2,
 
 
   /* Get the address of the GOT entry.  */
   /* Get the address of the GOT entry.  */
   new_addr = _dl_find_hash (strtab + symtab[symtab_index].st_name,
   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)
   if (!new_addr)
     {
     {
       _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
       _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
@@ -201,7 +201,7 @@ _dl_parse_relocation_information (struct elf_resolve *tpnt,
 	{
 	{
 	  symbol_addr = (unsigned int)
 	  symbol_addr = (unsigned int)
 	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
 	    _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);
 			   reloc_type == R_68K_JMP_SLOT ? tpnt : NULL, 0);
 
 
 	  /* We want to allow undefined references to weak symbols -
 	  /* We want to allow undefined references to weak symbols -
@@ -327,7 +327,7 @@ _dl_parse_copy_information (struct dyn_elf *xpnt, unsigned long rel_addr,
 	{
 	{
 	  symbol_addr = (unsigned int)
 	  symbol_addr = (unsigned int)
 	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
 	    _dl_find_hash (strtab + symtab[symtab_index].st_name,
-			   xpnt->next, (int) reloc_addr, NULL, 1);
+			   xpnt->next, NULL, 1);
 	  if (!symbol_addr)
 	  if (!symbol_addr)
 	    {
 	    {
 	      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
 	      _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",

+ 21 - 14
ldso/ldso/mips/README

@@ -1,28 +1,29 @@
 Almost all of the code present in these source files was taken
 Almost all of the code present in these source files was taken
 from GLIBC. In the descriptions below, all files mentioned are
 from GLIBC. In the descriptions below, all files mentioned are
 with respect to the top level GLIBC source directory accept for
 with respect to the top level GLIBC source directory accept for
-the code taken from the Linux kernel.
+code taken from the Linux kernel.
 
 
 boot1_arch.h
 boot1_arch.h
 ------------
 ------------
 Contains code to fix up the stack pointer so that the dynamic
 Contains code to fix up the stack pointer so that the dynamic
 linker can find argc, argv and Auxillary Vector Table (AVT).
 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
 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'.
+Contains the runtime resolver code taken from the function
+'__dl_runtime_resolve' in 'sysdeps/mips/dl-machine.h'. Also
+contains the function to perform relocations for objects
+other than the linker itself. The code was taken from the
+function 'elf_machine_rel' in 'sysdeps/mips/dl-machine.h'.
 
 
 ld_syscalls.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
 ld_sysdep.h
 -----------
 -----------
@@ -31,13 +32,19 @@ for detecting MIPS target types and some macros. The macro
 function 'PERFORM_BOOTSTRAP_GOT' is used to relocate the dynamic
 function 'PERFORM_BOOTSTRAP_GOT' is used to relocate the dynamic
 linker's GOT so that function calls can be made. The code is
 linker's GOT so that function calls can be made. The code is
 taken from the function 'ELF_MACHINE_BEFORE_RTLD_RELOC' in the
 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
 'PERFORM_BOOTSTRAP_RELOC' is used to do the relocations for
 the dynamic loader. The code is taken from the function
 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
 resolve.S
 ---------
 ---------
 Contains the low-level assembly code for the dynamic runtime
 Contains the low-level assembly code for the dynamic runtime
 resolver. The code is taken from the assembly code function
 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'.
+The code looks a bit different since we only need to pass the
+symbol index and the old GP register.

+ 9 - 3
ldso/ldso/mips/boot1_arch.h

@@ -1,7 +1,6 @@
 /* Any assmbly language/system dependent hacks needed to setup boot1.c so it
 /* Any assmbly language/system dependent hacks needed to setup boot1.c so it
  * will work as expected and cope with whatever platform specific wierdness is
  * will work as expected and cope with whatever platform specific wierdness is
- * needed for this architecture.  See arm/boot1_arch.h for an example of what
- * can be done.
+ * needed for this architecture.
  */
  */
 
 
 asm("
 asm("
@@ -13,7 +12,6 @@ _dl_boot:
 	nop
 	nop
 0:	.cpload $31
 0:	.cpload $31
 	.set reorder
 	.set reorder
-	# Store offset of DYNAMIC section in first entry of GOT
 	la $4, _DYNAMIC
 	la $4, _DYNAMIC
 	sw $4, -0x7ff0($28)
 	sw $4, -0x7ff0($28)
 	move $4, $29
 	move $4, $29
@@ -23,6 +21,14 @@ coff:	subu $8, $31, $8
 	la $25, _dl_boot2
 	la $25, _dl_boot2
 	addu $25, $8
 	addu $25, $8
 	jalr $25
 	jalr $25
+	lw $4, 0($29)
+	la $5, 4($29)
+	sll $6, $4, 2
+	addu $6, $6, $5
+	addu $6, $6, 4
+	la $7, _dl_elf_main
+	lw $25, 0($7)
+	jr $25
 ");
 ");
 
 
 #define _dl_boot _dl_boot2
 #define _dl_boot _dl_boot2

+ 9 - 3
ldso/ldso/mips/dl-startup.h

@@ -1,7 +1,6 @@
 /* Any assmbly language/system dependent hacks needed to setup boot1.c so it
 /* Any assmbly language/system dependent hacks needed to setup boot1.c so it
  * will work as expected and cope with whatever platform specific wierdness is
  * will work as expected and cope with whatever platform specific wierdness is
- * needed for this architecture.  See arm/boot1_arch.h for an example of what
- * can be done.
+ * needed for this architecture.
  */
  */
 
 
 asm("
 asm("
@@ -13,7 +12,6 @@ _dl_boot:
 	nop
 	nop
 0:	.cpload $31
 0:	.cpload $31
 	.set reorder
 	.set reorder
-	# Store offset of DYNAMIC section in first entry of GOT
 	la $4, _DYNAMIC
 	la $4, _DYNAMIC
 	sw $4, -0x7ff0($28)
 	sw $4, -0x7ff0($28)
 	move $4, $29
 	move $4, $29
@@ -23,6 +21,14 @@ coff:	subu $8, $31, $8
 	la $25, _dl_boot2
 	la $25, _dl_boot2
 	addu $25, $8
 	addu $25, $8
 	jalr $25
 	jalr $25
+	lw $4, 0($29)
+	la $5, 4($29)
+	sll $6, $4, 2
+	addu $6, $6, $5
+	addu $6, $6, 4
+	la $7, _dl_elf_main
+	lw $25, 0($7)
+	jr $25
 ");
 ");
 
 
 #define _dl_boot _dl_boot2
 #define _dl_boot _dl_boot2

+ 117 - 58
ldso/ldso/mips/dl-sysdep.h

@@ -1,5 +1,7 @@
+/* vi: set sw=4 ts=4: */
+
 /*
 /*
- * Various assmbly language/system dependent  hacks that are required
+ * Various assmbly language/system dependent hacks that are required
  * so that we can minimize the amount of platform specific code.
  * so that we can minimize the amount of platform specific code.
  */
  */
 
 
@@ -20,46 +22,102 @@
 /*
 /*
  * Initialization sequence for the application GOT.
  * 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_resolve;					\
+	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);		\
+			}															\
+		}																\
+		else if (sym->st_shndx == SHN_COMMON) {							\
+			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
+				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+		}																\
+		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);			\
+		}																\
+																		\
+		++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.
  * 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;													\
+																		\
+	/* 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)
 } while (0)
 
 
 
 
@@ -67,31 +125,33 @@ do {									\
  * Here is a macro to perform a relocation.  This is only used when
  * Here is a macro to perform a relocation.  This is only used when
  * bootstrapping the dynamic loader.
  * 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);													\
 	}
 	}
 
 
 
 
 /*
 /*
  * Transfer control to the user's application, once the dynamic loader
  * Transfer control to the user's application, once the dynamic loader
  * is done.  This routine has to exit the current function, then 
  * is done.  This routine has to exit the current function, then 
- * call the _dl_elf_main function.
+ * call the _dl_elf_main function. For MIPS, we do it in assembly
+ * because the stack doesn't get properly restored otherwise. Got look
+ * at boot1_arch.h
  */
  */
-#define START()   return (void) _dl_elf_main;      
+#define START()
 
 
 
 
 /* Here we define the magic numbers that this dynamic loader should accept */
 /* Here we define the magic numbers that this dynamic loader should accept */
@@ -103,9 +163,8 @@ do {									\
 #define ELF_TARGET "MIPS"
 #define ELF_TARGET "MIPS"
 
 
 
 
-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(unsigned long sym_index,
+	unsigned long old_gpreg);
+
 
 
 #define do_rem(result, n, base)  result = (n % base)
 #define do_rem(result, n, base)  result = (n % base)

+ 100 - 5
ldso/ldso/mips/elfinterp.c

@@ -1,6 +1,7 @@
+/* vi: set sw=4 ts=4: */
+
 /* Run an ELF binary on a linux system.
 /* Run an ELF binary on a linux system.
 
 
-   Copyright (C) 1993, Eric Youngdale.
    Copyright (C) 2002, Steven J. Hill (sjhill@realitydiluted.com)
    Copyright (C) 2002, Steven J. Hill (sjhill@realitydiluted.com)
 
 
    This program is free software; you can redistribute it and/or modify
    This program is free software; you can redistribute it and/or modify
@@ -32,18 +33,112 @@
 
 
 extern int _dl_linux_resolve(void);
 extern int _dl_linux_resolve(void);
 
 
-void _dl_init_got(unsigned long *got, struct elf_resolve *tpnt)
+#define OFFSET_GP_GOT 0x7ff0
+
+unsigned long _dl_linux_resolver(unsigned long sym_index,
+	unsigned long old_gpreg)
 {
 {
+	unsigned long *got = (unsigned long *) (old_gpreg - OFFSET_GP_GOT);
+	struct elf_resolve *tpnt = (struct elf_resolve *) got[1];
+	Elf32_Sym *sym;
+	char *strtab;
+	unsigned long local_gotno;
+	unsigned long gotsym;
+	unsigned long value;
+
+	gotsym = tpnt->mips_gotsym;
+	local_gotno = tpnt->mips_local_gotno;
+
+	sym = ((Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr)) +
+		sym_index;
+
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	value = (unsigned long) _dl_find_hash(strtab + sym->st_name,
+		 tpnt->symbol_scope, tpnt, 1);
+
+	*(got + local_gotno + sym_index - gotsym) = value;
+
+#ifdef DL_DEBUG
+	_dl_dprintf(2, "---RESOLVER---\n");
+	_dl_dprintf(2, "SYMTAB INDEX: %i\n", sym_index);
+	_dl_dprintf(2, "      GOTSYM: %i\n", gotsym);
+	_dl_dprintf(2, " LOCAL GOTNO: %i\n", local_gotno);
+	_dl_dprintf(2, "       VALUE: %x\n", value);
+	_dl_dprintf(2, "      SYMBOL: %s\n\n", strtab + sym->st_name);
+#endif
+
+	return value;
+}
+
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt,
+	unsigned long rel_addr, unsigned long rel_size, int type)
+{
+	/* Nothing to do */
 	return;
 	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;
 	return 0;
 }
 }
-
+        
 int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
 int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
 	unsigned long rel_addr, unsigned long rel_size, int type)
 	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 */
+	rel_size = rel_size / sizeof(Elf32_Rel);
+	rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
+
+	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;
 }
 }

+ 117 - 58
ldso/ldso/mips/ld_sysdep.h

@@ -1,5 +1,7 @@
+/* vi: set sw=4 ts=4: */
+
 /*
 /*
- * Various assmbly language/system dependent  hacks that are required
+ * Various assmbly language/system dependent hacks that are required
  * so that we can minimize the amount of platform specific code.
  * so that we can minimize the amount of platform specific code.
  */
  */
 
 
@@ -20,46 +22,102 @@
 /*
 /*
  * Initialization sequence for the application GOT.
  * 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_resolve;					\
+	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);		\
+			}															\
+		}																\
+		else if (sym->st_shndx == SHN_COMMON) {							\
+			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
+				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+		}																\
+		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);			\
+		}																\
+																		\
+		++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.
  * 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;													\
+																		\
+	/* 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)
 } while (0)
 
 
 
 
@@ -67,31 +125,33 @@ do {									\
  * Here is a macro to perform a relocation.  This is only used when
  * Here is a macro to perform a relocation.  This is only used when
  * bootstrapping the dynamic loader.
  * 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);													\
 	}
 	}
 
 
 
 
 /*
 /*
  * Transfer control to the user's application, once the dynamic loader
  * Transfer control to the user's application, once the dynamic loader
  * is done.  This routine has to exit the current function, then 
  * is done.  This routine has to exit the current function, then 
- * call the _dl_elf_main function.
+ * call the _dl_elf_main function. For MIPS, we do it in assembly
+ * because the stack doesn't get properly restored otherwise. Got look
+ * at boot1_arch.h
  */
  */
-#define START()   return (void) _dl_elf_main;      
+#define START()
 
 
 
 
 /* Here we define the magic numbers that this dynamic loader should accept */
 /* Here we define the magic numbers that this dynamic loader should accept */
@@ -103,9 +163,8 @@ do {									\
 #define ELF_TARGET "MIPS"
 #define ELF_TARGET "MIPS"
 
 
 
 
-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(unsigned long sym_index,
+	unsigned long old_gpreg);
+
 
 
 #define do_rem(result, n, base)  result = (n % base)
 #define do_rem(result, n, base)  result = (n % base)

+ 8 - 15
ldso/ldso/mips/resolve.S

@@ -1,4 +1,4 @@
-/*
+	/*
  * Linux dynamic resolving code for MIPS. Fixes up the GOT entry as
  * Linux dynamic resolving code for MIPS. Fixes up the GOT entry as
  * indicated in register t8 and jumps to the resolved address. Shamelessly
  * indicated in register t8 and jumps to the resolved address. Shamelessly
  * ripped from 'sysdeps/mips/dl-machine.h' in glibc-2.2.5.
  * ripped from 'sysdeps/mips/dl-machine.h' in glibc-2.2.5.
@@ -23,26 +23,19 @@ _dl_linux_resolve:
 	addu	$25, 8		# t9 ($25) now points at .cpload instruction
 	addu	$25, 8		# t9 ($25) now points at .cpload instruction
 	.cpload	$25		# Compute GP
 	.cpload	$25		# Compute GP
 	.set reorder
 	.set reorder
-	move	$2, $31		# Save slot call pc
-	subu	$29, 40		# Save arguments and sp value in stack
-	.cprestore 32
-	sw	$15, 36($29)
+	subu	$29, 32
+	.cprestore 28
 	sw	$4, 16($29)
 	sw	$4, 16($29)
 	sw	$5, 20($29)
 	sw	$5, 20($29)
-	sw	$6, 24($29)
-	sw	$7, 28($29)
+	sw	$15, 24($29)
 	move	$4, $24
 	move	$4, $24
-	move	$5, $15
-	move	$6, $3
-	move	$7, $2
+	move	$5, $3
 	jal     _dl_linux_resolver
 	jal     _dl_linux_resolver
-	lw	$31, 36($29)
+	lw	$31, 24($29)
 	lw	$4, 16($29)
 	lw	$4, 16($29)
 	lw	$5, 20($29)
 	lw	$5, 20($29)
-	lw	$6, 24($29)
-	lw	$7, 28($29)
-	addu	$29, 40
+	addu	$29, 32
 	move	$25, $2
 	move	$25, $2
-        jr	$25
+	jr	$25
 .size _dl_linux_resolve,.-_dl_linux_resolve
 .size _dl_linux_resolve,.-_dl_linux_resolve
 .end _dl_linux_resolve
 .end _dl_linux_resolve

+ 3 - 3
ldso/ldso/powerpc/elfinterp.c

@@ -161,7 +161,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
 	/* Get the address of the GOT entry */
 	/* Get the address of the GOT entry */
 	targ_addr = (unsigned long) _dl_find_hash(
 	targ_addr = (unsigned long) _dl_find_hash(
 		strtab + symtab[symtab_index].st_name, 
 		strtab + symtab[symtab_index].st_name, 
-		tpnt->symbol_scope, insn_addr, tpnt, 0);
+		tpnt->symbol_scope, tpnt, 0);
 	if (!targ_addr) {
 	if (!targ_addr) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 		_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 			_dl_progname, strtab + symtab[symtab_index].st_name);
 			_dl_progname, strtab + symtab[symtab_index].st_name);
@@ -337,7 +337,7 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt,
 				continue;
 				continue;
 
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
 			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);
 					(reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), 0);
 
 
 			/*
 			/*
@@ -499,7 +499,7 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr,
 
 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 			symbol_addr = (unsigned long) _dl_find_hash(strtab + 
 				symtab[symtab_index].st_name, xpnt->next, 
 				symtab[symtab_index].st_name, xpnt->next, 
-				(unsigned long) reloc_addr, NULL, 1);
+				NULL, 1);
 			if (!symbol_addr) {
 			if (!symbol_addr) {
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 
 					_dl_progname, strtab + symtab[symtab_index].st_name);
 					_dl_progname, strtab + symtab[symtab_index].st_name);

+ 66 - 19
ldso/ldso/readelflib1.c

@@ -108,14 +108,14 @@ int _dl_unmap_cache(void)
 /* This function's behavior must exactly match that 
 /* This function's behavior must exactly match that 
  * in uClibc/ldso/util/ldd.c */
  * in uClibc/ldso/util/ldd.c */
 static struct elf_resolve * 
 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;
 	int i, count = 1;
 	char *path, *path_n;
 	char *path, *path_n;
 	char mylibname[2050];
 	char mylibname[2050];
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
 
 
-
 	/* We need a writable copy of this string */
 	/* We need a writable copy of this string */
 	path = _dl_strdup(path_list);
 	path = _dl_strdup(path_list);
 	if (!path) {
 	if (!path) {
@@ -140,8 +140,11 @@ search_for_named_library(char *name, int secure, const char *path_list)
 		_dl_strcpy(mylibname, path_n); 
 		_dl_strcpy(mylibname, path_n); 
 		_dl_strcat(mylibname, "/"); 
 		_dl_strcat(mylibname, "/"); 
 		_dl_strcat(mylibname, name);
 		_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);
 		path_n += (_dl_strlen(path_n) + 1);
 	}
 	}
 	return NULL;
 	return NULL;
@@ -156,7 +159,7 @@ unsigned long _dl_error_number;
 unsigned long _dl_internal_error_number;
 unsigned long _dl_internal_error_number;
 extern char *_dl_ldsopath;
 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)
 	struct elf_resolve *tpnt, char *full_libname)
 {
 {
 	char *pnt;
 	char *pnt;
@@ -185,7 +188,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 	   /usr/i486-sysv4/lib for /usr/lib in library names. */
 	   /usr/i486-sysv4/lib for /usr/lib in library names. */
 
 
 	if (libname != full_libname) {
 	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)
 		if (tpnt1)
 			return tpnt1;
 			return tpnt1;
 		goto goof;
 		goto goof;
@@ -204,7 +207,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 				_dl_dprintf(2, "searching RPATH: '%s'\n", pnt);
 				_dl_dprintf(2, "searching RPATH: '%s'\n", pnt);
 #endif
 #endif
-				if ((tpnt1 = search_for_named_library(libname, secure, pnt)) != NULL) 
+				if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) 
 				{
 				{
 				    return tpnt1;
 				    return tpnt1;
 				}
 				}
@@ -217,7 +220,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 	    _dl_dprintf(2, "searching _dl_library_path: '%s'\n", _dl_library_path);
 	    _dl_dprintf(2, "searching _dl_library_path: '%s'\n", _dl_library_path);
 #endif
 #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;
 		return tpnt1;
 	    }
 	    }
@@ -240,7 +243,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 				 libent[i].flags == LIB_ELF_LIBC5) &&
 				 libent[i].flags == LIB_ELF_LIBC5) &&
 				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
 				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
 				(tpnt1 = _dl_load_elf_shared_library(secure, 
 				(tpnt1 = _dl_load_elf_shared_library(secure, 
-				     strs + libent[i].liboffset, 0)))
+				     rpnt, strs + libent[i].liboffset, 0)))
 				return tpnt1;
 				return tpnt1;
 		}
 		}
 	}
 	}
@@ -251,7 +254,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 #ifdef DL_DEBUG
 #ifdef DL_DEBUG
 	_dl_dprintf(2, "searching in ldso dir: %s\n", _dl_ldsopath);
 	_dl_dprintf(2, "searching in ldso dir: %s\n", _dl_ldsopath);
 #endif
 #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;
 	    return tpnt1;
 	}
 	}
@@ -268,7 +271,7 @@ struct elf_resolve *_dl_load_shared_library(int secure,
 			UCLIBC_DEVEL_PREFIX "/lib:"
 			UCLIBC_DEVEL_PREFIX "/lib:"
 			UCLIBC_BUILD_DIR "/lib:"
 			UCLIBC_BUILD_DIR "/lib:"
 			"/usr/lib:"
 			"/usr/lib:"
-			"/lib")
+			"/lib", rpnt)
 		    ) != NULL) 
 		    ) != NULL) 
 	{
 	{
 	    return tpnt1;
 	    return tpnt1;
@@ -286,16 +289,15 @@ goof:
 	return NULL;
 	return NULL;
 }
 }
 
 
+
 /*
 /*
  * Read one ELF library into memory, mmap it into the correct locations and
  * 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
  * add the symbol info to the symbol chain.  Perform any relocations that
  * are required.
  * 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;
 	elfhdr *epnt;
 	unsigned long dynamic_addr = 0;
 	unsigned long dynamic_addr = 0;
@@ -311,14 +313,27 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	unsigned long *lpnt;
 	unsigned long *lpnt;
 	unsigned long libaddr;
 	unsigned long libaddr;
 	unsigned long minvma = 0xffffffff, maxvma = 0;
 	unsigned long minvma = 0xffffffff, maxvma = 0;
-
 	int i;
 	int i;
 	int infile;
 	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 */
 	/* If this file is already loaded, skip this step */
 	tpnt = _dl_check_hashed_files(libname);
 	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;
 		return tpnt;
+	}
 
 
 	/* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
 	/* 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. */
 	   we don't load the library if it isn't setuid. */
@@ -514,7 +529,22 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
 	_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++) {
 	for (i = 0; i < dynamic_size; i++) {
+#endif
 		if (dpnt->d_tag > DT_JMPREL) {
 		if (dpnt->d_tag > DT_JMPREL) {
 			dpnt++;
 			dpnt++;
 			continue;
 			continue;
@@ -526,8 +556,8 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	};
 	};
 
 
 	/* If the TEXTREL is set, this means that we need to make the pages
 	/* If the TEXTREL is set, this means that we need to make the pages
-	   writable before we perform relocations.  Do this now. They get set back
-	   again later. */
+	   writable before we perform relocations.  Do this now. They get set
+	   back again later. */
 
 
 	if (dynamic_info[DT_TEXTREL]) {
 	if (dynamic_info[DT_TEXTREL]) {
 		ppnt = (elf_phdr *) & header[epnt->e_phoff];
 		ppnt = (elf_phdr *) & header[epnt->e_phoff];
@@ -547,6 +577,18 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
 	tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
 	tpnt->n_phent = epnt->e_phnum;
 	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
 	 * 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
 	 * the proper entry in the GOT so that the PLT symbols can be properly
@@ -558,6 +600,11 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	if (lpnt) {
 	if (lpnt) {
 		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
 		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
 			((int) libaddr));
 			((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);
 		INIT_GOT(lpnt, tpnt);
 	};
 	};
 
 

+ 3 - 3
ldso/ldso/sparc/elfinterp.c

@@ -98,7 +98,7 @@ unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
 
 
   /* Get the address of the GOT entry */
   /* Get the address of the GOT entry */
   new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
   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) {
   if(!new_addr) {
     _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
     _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
 	       _dl_progname, strtab + symtab[symtab_index].st_name);
 	       _dl_progname, strtab + symtab[symtab_index].st_name);
@@ -201,7 +201,7 @@ int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
 
 
       symbol_addr = (unsigned int) 
       symbol_addr = (unsigned int) 
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
 	_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);
 		      (reloc_type == R_SPARC_JMP_SLOT ? tpnt : NULL), 0);
 
 
       if(!symbol_addr &&
       if(!symbol_addr &&
@@ -319,7 +319,7 @@ int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
 
 
       symbol_addr = (unsigned int) 
       symbol_addr = (unsigned int) 
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
-			      xpnt->next, (int) reloc_addr, NULL, 1);
+			      xpnt->next, NULL, 1);
       if(!symbol_addr) {
       if(!symbol_addr) {
 	_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
 	_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
 		   _dl_progname, strtab + symtab[symtab_index].st_name);
 		   _dl_progname, strtab + symtab[symtab_index].st_name);

+ 3 - 3
ldso/libdl/dlib.c

@@ -108,7 +108,7 @@ void *_dlopen(char *libname, int flag)
 			tfrom = tpnt;
 			tfrom = tpnt;
 	}
 	}
 
 
-	if (!(tpnt = _dl_load_shared_library(0, tfrom, libname))) {
+	if (!(tpnt = _dl_load_shared_library(0, &rpnt, tfrom, libname))) {
 #ifdef USE_CACHE
 #ifdef USE_CACHE
 		_dl_unmap_cache();
 		_dl_unmap_cache();
 #endif
 #endif
@@ -145,7 +145,7 @@ void *_dlopen(char *libname, int flag)
 		    {
 		    {
 		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
 		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
 			dpnt->d_un.d_val;
 			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;
 			goto oops;
 
 
 		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
 		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
@@ -304,7 +304,7 @@ void *_dlsym(void *vhandle, char *name)
 		}
 		}
 	}
 	}
 
 
-	ret = _dl_find_hash(name, handle, 1, NULL, 1);
+	ret = _dl_find_hash(name, handle, NULL, 1);
 
 
 	/*
 	/*
 	 * Nothing found.
 	 * Nothing found.

+ 3 - 3
ldso/libdl/libdl.c

@@ -108,7 +108,7 @@ void *_dlopen(char *libname, int flag)
 			tfrom = tpnt;
 			tfrom = tpnt;
 	}
 	}
 
 
-	if (!(tpnt = _dl_load_shared_library(0, tfrom, libname))) {
+	if (!(tpnt = _dl_load_shared_library(0, &rpnt, tfrom, libname))) {
 #ifdef USE_CACHE
 #ifdef USE_CACHE
 		_dl_unmap_cache();
 		_dl_unmap_cache();
 #endif
 #endif
@@ -145,7 +145,7 @@ void *_dlopen(char *libname, int flag)
 		    {
 		    {
 		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
 		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
 			dpnt->d_un.d_val;
 			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;
 			goto oops;
 
 
 		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
 		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
@@ -304,7 +304,7 @@ void *_dlsym(void *vhandle, char *name)
 		}
 		}
 	}
 	}
 
 
-	ret = _dl_find_hash(name, handle, 1, NULL, 1);
+	ret = _dl_find_hash(name, handle, NULL, 1);
 
 
 	/*
 	/*
 	 * Nothing found.
 	 * Nothing found.