Browse Source

Another mips patch from Steven J. Hill:

    Uh, this patch fixes a few bugs that I overlooked. Shoot, even BusyBox
    wouldn't work until these are applied. Erik, plop this into CVS please.
    Thanks.
Eric Andersen 22 years ago
parent
commit
4a6cfe3180

+ 13 - 24
ldso/ldso/dl-elf.c

@@ -315,11 +315,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	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);
@@ -529,22 +524,21 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+
 #if defined(__mips__)
-	/*
-	 * The program header file size for the dynamic section is
-	 * calculated differently for MIPS. We look for a null tag
-	 * value instead.
-	 */
-	while(dpnt->d_tag)
-		if (dpnt->d_tag == DT_MIPS_GOTSYM)
-			mips_gotsym = (unsigned long) dpnt->d_un.d_val;
-		if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
-			mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
-		if (dpnt->d_tag == DT_MIPS_SYMTABNO)
-			mips_symtabno = (unsigned long) dpnt->d_un.d_val;
-#else
-	for (i = 0; i < dynamic_size; i++) 
+	{
+	    int i = 1;
+	    Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+	    while(dpnt->d_tag) {
+		dpnt++;
+		i++;
+	    }
+	    dynamic_size = i * sizeof(Elf32_Dyn);
+	}
 #endif
+
+	for (i = 0; i < dynamic_size; i++) 
 	{
 		if (dpnt->d_tag > DT_JMPREL) {
 			dpnt++;
@@ -601,11 +595,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	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);
 	};
 

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

@@ -125,6 +125,21 @@ struct elf_resolve *_dl_add_elf_hash_table(char *libname,
 	tpnt->loadaddr = loadaddr;
 	for (i = 0; i < 24; i++)
 		tpnt->dynamic_info[i] = dynamic_info[i];
+#ifdef __mips__
+	{
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+		while(dpnt->d_tag) {
+			if (dpnt->d_tag == DT_MIPS_GOTSYM)
+				tpnt->mips_gotsym = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+				tpnt->mips_local_gotno = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+				tpnt->mips_symtabno = dpnt->d_un.d_val;
+			dpnt++;
+		}
+	}
+#endif
 	return tpnt;
 }
 
@@ -235,7 +250,8 @@ char *_dl_find_hash(char *name, struct dyn_elf *rpnt1,
 					(ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
 					 ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
 					 ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-					symtab[si].st_value != 0) {
+					symtab[si].st_value != 0 &&
+					symtab[si].st_shndx != 0) {
 
 					/* Here we make sure that we find a module where the symbol is
 					 * actually defined.

+ 17 - 1
ldso/ldso/hash.c

@@ -125,6 +125,21 @@ struct elf_resolve *_dl_add_elf_hash_table(char *libname,
 	tpnt->loadaddr = loadaddr;
 	for (i = 0; i < 24; i++)
 		tpnt->dynamic_info[i] = dynamic_info[i];
+#ifdef __mips__
+	{
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+		while(dpnt->d_tag) {
+			if (dpnt->d_tag == DT_MIPS_GOTSYM)
+				tpnt->mips_gotsym = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+				tpnt->mips_local_gotno = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+				tpnt->mips_symtabno = dpnt->d_un.d_val;
+			dpnt++;
+		}
+	}
+#endif
 	return tpnt;
 }
 
@@ -235,7 +250,8 @@ char *_dl_find_hash(char *name, struct dyn_elf *rpnt1,
 					(ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
 					 ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
 					 ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-					symtab[si].st_value != 0) {
+					symtab[si].st_value != 0 &&
+					symtab[si].st_shndx != 0) {
 
 					/* Here we make sure that we find a module where the symbol is
 					 * actually defined.

+ 46 - 25
ldso/ldso/ldso.c

@@ -368,12 +368,6 @@ DL_BOOT(unsigned long args)
 	/* OK, that was easy.  Next scan the DYNAMIC section of the image.
 	   We are only doing ourself right now - we will have to do the rest later */
 	while (dpnt->d_tag) {
-		if (dpnt->d_tag < 24) {
-			tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-			if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT) {
-				tpnt->dynamic_info[DT_TEXTREL] = 1;
-			}
-		}
 #if defined(__mips__)
 		if (dpnt->d_tag == DT_MIPS_GOTSYM)
 			tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
@@ -382,6 +376,12 @@ DL_BOOT(unsigned long args)
 		if (dpnt->d_tag == DT_MIPS_SYMTABNO)
 			tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
 #endif
+		if (dpnt->d_tag < 24) {
+			tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+			if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT) {
+				tpnt->dynamic_info[DT_TEXTREL] = 1;
+			}
+		}
 		dpnt++;
 	}
 
@@ -473,9 +473,10 @@ DL_BOOT(unsigned long args)
 #endif
 
 
-	/* For MIPS, we have to do special stuff to the GOT before we do
-	   any relocations. */
 #if defined(__mips__)
+	/*
+	 * For MIPS we have to do stuff to the GOT before we do relocations.
+	 */
 	PERFORM_BOOTSTRAP_GOT(got);
 #endif
 
@@ -612,11 +613,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 	struct elf_resolve *tpnt1;
 	unsigned long brk_addr, *lpnt;
 	int (*_dl_atexit) (void *);
-#ifdef __mips__
-	unsigned long mips_gotsym = 0;
-	unsigned long mips_local_gotno = 0;
-	unsigned long mips_symtabno = 0;
-#endif
 
 
 	/* Now we have done the mandatory linking of some things.  We are now
@@ -649,7 +645,20 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
 			if (ppnt->p_type == PT_DYNAMIC) {
 				tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
+#if defined(__mips__)
+				{
+					int i = 1;
+					Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+
+					while(dpnt->d_tag) {
+						dpnt++;
+						i++;
+					}
+					tpnt->dynamic_size = i * sizeof(Elf32_Dyn);
+				}
+#else
 				tpnt->dynamic_size = ppnt->p_filesz;
+#endif
 			}
 		}
 	}
@@ -674,31 +683,38 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 				continue;
 #endif
 			/* OK, we have what we need - slip this one into the list. */
-#ifdef __mips__
-			mips_gotsym = app_tpnt->mips_gotsym;
-			mips_local_gotno = app_tpnt->mips_local_gotno;
-			mips_symtabno = app_tpnt->mips_symtabno;
-#endif
+#if defined(__mips__)
+			{
+				int i = 1;
+				Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+
+				while(dpnt->d_tag) {
+					dpnt++;
+					i++;
+				}
+				app_tpnt = _dl_add_elf_hash_table("", 0, 
+					app_tpnt->dynamic_info, ppnt->p_vaddr,
+					(i * sizeof(Elf32_Dyn)));
+			}
+#else
 			app_tpnt = _dl_add_elf_hash_table("", 0, 
 					app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+#endif
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->ppnt = (elf_phdr *) auxvt[AT_PHDR].a_un.a_ptr;
 			_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
-#ifdef __mips__
-			_dl_loaded_modules->mips_gotsym = mips_gotsym; 
-			_dl_loaded_modules->mips_local_gotno = mips_local_gotno;
-			_dl_loaded_modules->mips_symtabno = mips_symtabno;
-#endif
 			_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(*rpnt));
 			rpnt->dyn = _dl_loaded_modules;
 			app_tpnt->usage_count++;
 			app_tpnt->symbol_scope = _dl_symbol_tables;
 			lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+#ifndef __mips__
 #ifdef ALLOW_ZERO_PLTGOT
 			if (lpnt)
 #endif
 				INIT_GOT(lpnt, _dl_loaded_modules);
+#endif
 		}
 
 		/* OK, fill this in - we did not have this before */
@@ -1063,8 +1079,8 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 	   up each symbol individually. */
 
 
-	_dl_brkp =
-		(unsigned long *) _dl_find_hash("___brk_addr", NULL, NULL, 0);
+	_dl_brkp = (unsigned long *) _dl_find_hash("___brk_addr", NULL, NULL, 0);
+	
 	if (_dl_brkp) {
 		*_dl_brkp = brk_addr;
 	}
@@ -1075,6 +1091,11 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 		*_dl_envp = (unsigned long) envp;
 	}
 
+#ifdef __mips__
+	lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+	INIT_GOT(lpnt, _dl_loaded_modules);
+#endif
+
 #ifdef DO_MPROTECT_HACKS
 	{
 		int i;

+ 4 - 4
ldso/ldso/mips/dl-sysdep.h

@@ -20,7 +20,7 @@
 
 
 /*
- * Initialization sequence for the application GOT.
+ * Initialization sequence for the application or library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)										\
 do {																	\
@@ -56,12 +56,12 @@ do {																	\
 					(unsigned long) MODULE->loadaddr;					\
 			else {														\
 				*GOT_BASE = (unsigned long) _dl_find_hash(strtab +		\
-					sym->st_name, MODULE->symbol_scope, NULL, 0);		\
+					sym->st_name, MODULE->symbol_scope, NULL, 1);		\
 			}															\
 		}																\
 		else if (sym->st_shndx == SHN_COMMON) {							\
 			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
 		}																\
 		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
 			*GOT_BASE != sym->st_value)									\
@@ -72,7 +72,7 @@ do {																	\
 		}																\
 		else {															\
 			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
 		}																\
 																		\
 		++GOT_BASE;														\

+ 4 - 4
ldso/ldso/mips/ld_sysdep.h

@@ -20,7 +20,7 @@
 
 
 /*
- * Initialization sequence for the application GOT.
+ * Initialization sequence for the application or library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)										\
 do {																	\
@@ -56,12 +56,12 @@ do {																	\
 					(unsigned long) MODULE->loadaddr;					\
 			else {														\
 				*GOT_BASE = (unsigned long) _dl_find_hash(strtab +		\
-					sym->st_name, MODULE->symbol_scope, NULL, 0);		\
+					sym->st_name, MODULE->symbol_scope, NULL, 1);		\
 			}															\
 		}																\
 		else if (sym->st_shndx == SHN_COMMON) {							\
 			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
 		}																\
 		else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&				\
 			*GOT_BASE != sym->st_value)									\
@@ -72,7 +72,7 @@ do {																	\
 		}																\
 		else {															\
 			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 0);			\
+				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
 		}																\
 																		\
 		++GOT_BASE;														\

+ 9 - 5
ldso/ldso/mips/resolve.S

@@ -23,18 +23,22 @@ _dl_linux_resolve:
 	addu	$25, 8		# t9 ($25) now points at .cpload instruction
 	.cpload	$25		# Compute GP
 	.set reorder
-	subu	$29, 32
-	.cprestore 28
+	subu	$29, 40
+	.cprestore 32
+	sw	$15, 36($29)
 	sw	$4, 16($29)
 	sw	$5, 20($29)
-	sw	$15, 24($29)
+	sw	$6, 24($29)
+	sw	$7, 28($29)
 	move	$4, $24
 	move	$5, $3
 	jal     _dl_linux_resolver
-	lw	$31, 24($29)
+	lw	$31, 36($29)
 	lw	$4, 16($29)
 	lw	$5, 20($29)
-	addu	$29, 32
+	lw	$6, 24($29)
+	lw	$7, 28($29)
+	addu	$29, 40
 	move	$25, $2
 	jr	$25
 .size _dl_linux_resolve,.-_dl_linux_resolve

+ 13 - 24
ldso/ldso/readelflib1.c

@@ -315,11 +315,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	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);
@@ -529,22 +524,21 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+
 #if defined(__mips__)
-	/*
-	 * The program header file size for the dynamic section is
-	 * calculated differently for MIPS. We look for a null tag
-	 * value instead.
-	 */
-	while(dpnt->d_tag)
-		if (dpnt->d_tag == DT_MIPS_GOTSYM)
-			mips_gotsym = (unsigned long) dpnt->d_un.d_val;
-		if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
-			mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
-		if (dpnt->d_tag == DT_MIPS_SYMTABNO)
-			mips_symtabno = (unsigned long) dpnt->d_un.d_val;
-#else
-	for (i = 0; i < dynamic_size; i++) 
+	{
+	    int i = 1;
+	    Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+	    while(dpnt->d_tag) {
+		dpnt++;
+		i++;
+	    }
+	    dynamic_size = i * sizeof(Elf32_Dyn);
+	}
 #endif
+
+	for (i = 0; i < dynamic_size; i++) 
 	{
 		if (dpnt->d_tag > DT_JMPREL) {
 			dpnt++;
@@ -601,11 +595,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	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);
 	};