Browse Source

Fixed MIPS dynamic linker by removing link order dependency bug.

"Steven J. Hill" 22 years ago
parent
commit
1e811cd2c0

+ 1 - 1
extra/Configs/Config.mips

@@ -187,7 +187,7 @@ DEVEL_PREFIX = /usr/$(TARGET_ARCH)-linux-uclibc
 # the 'make install' target, and is not compiled into anything.  This
 # defaults to $DEVEL_PREFIX/usr, but makers of .rpms and .debs will
 # want to set this to "/usr" instead.
-SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)/usr
+SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)
 
 # If you want 'make install' to install everything under a temporary
 # directory, then define PREFIX during the install step,

+ 1 - 1
extra/Configs/Config.mipsel

@@ -187,7 +187,7 @@ DEVEL_PREFIX = /usr/$(TARGET_ARCH)-linux-uclibc
 # the 'make install' target, and is not compiled into anything.  This
 # defaults to $DEVEL_PREFIX/usr, but makers of .rpms and .debs will
 # want to set this to "/usr" instead.
-SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)/usr
+SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)
 
 # If you want 'make install' to install everything under a temporary
 # directory, then define PREFIX during the install step,

+ 7 - 7
ldso/ldso/dl-elf.c

@@ -527,14 +527,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 #if defined(__mips__)
 	{
-	    int i = 1;
-	    Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+		int i = 1;
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
 
-	    while(dpnt->d_tag) {
-		dpnt++;
-		i++;
-	    }
-	    dynamic_size = i * sizeof(Elf32_Dyn);
+		while(dpnt->d_tag) {
+			dpnt++;
+			i++;
+		}
+		dynamic_size = i;
 	}
 #endif
 

+ 8 - 7
ldso/ldso/ldso.c

@@ -709,12 +709,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 			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 */
@@ -1046,6 +1044,14 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
 	}
 #endif
 
+#ifdef __mips__
+	/*
+	 * Relocation of the GOT entries for MIPS have to be done
+	 * after all the libraries have been loaded.
+	 */
+	_dl_perform_mips_global_got_relocations(_dl_loaded_modules);
+#endif
+
 #ifdef DL_DEBUG
 	_dl_dprintf(2, "Beginning relocation fixups\n");
 #endif
@@ -1091,11 +1097,6 @@ 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 - 1
ldso/ldso/mips/boot1_arch.h

@@ -16,8 +16,11 @@ _dl_boot:
 	sw $4, -0x7ff0($28)
 	move $4, $29
 	la $8, coff
-	bltzal $8, coff
+	.set noreorder
+	bltzal $0, coff
+	nop
 coff:	subu $8, $31, $8
+	.set reorder
 	la $25, _dl_boot2
 	addu $25, $8
 	jalr $25

+ 4 - 1
ldso/ldso/mips/dl-startup.h

@@ -16,8 +16,11 @@ _dl_boot:
 	sw $4, -0x7ff0($28)
 	move $4, $29
 	la $8, coff
-	bltzal $8, coff
+	.set noreorder
+	bltzal $0, coff
+	nop
 coff:	subu $8, $31, $8
+	.set reorder
 	la $25, _dl_boot2
 	addu $25, $8
 	jalr $25

+ 1 - 40
ldso/ldso/mips/dl-sysdep.h

@@ -20,12 +20,10 @@
 
 
 /*
- * Initialization sequence for the application or library GOT.
+ * Initialization sequence for the application/library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)										\
 do {																	\
-	Elf32_Sym *sym;														\
-	char *strtab;														\
 	unsigned long i;													\
 																		\
 	/* Check if this is the dynamic linker itself */					\
@@ -41,43 +39,6 @@ do {																	\
 	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, 1);		\
-			}															\
-		}																\
-		else if (sym->st_shndx == SHN_COMMON) {							\
-			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
-		}																\
-		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, 1);			\
-		}																\
-																		\
-		++GOT_BASE;														\
-		++sym;															\
-	}																	\
 } while (0)
 
 

+ 59 - 0
ldso/ldso/mips/elfinterp.c

@@ -142,3 +142,62 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt,
 	};
 	return 0;
 }
+
+void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+{
+	Elf32_Sym *sym;
+	char *strtab;
+	unsigned long i;
+	unsigned long *got_entry;
+
+	for (; tpnt ; tpnt = tpnt->next) {
+
+		/* We don't touch the dynamic linker */
+		if (tpnt->libtype == program_interpreter)
+			continue;
+
+		/* Setup the loop variables */
+		got_entry = (unsigned long *) (tpnt->loadaddr +
+			tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
+		sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+			(unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
+		strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
+			(unsigned long) tpnt->loadaddr);
+		i = tpnt->mips_symtabno - tpnt->mips_gotsym;
+
+		/* Relocate the global GOT entries for the object */
+		while(i--) {
+			if (sym->st_shndx == SHN_UNDEF) {
+				if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value)
+					*got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
+				else {
+					*got_entry = (unsigned long) _dl_find_hash(strtab +
+						sym->st_name, tpnt->symbol_scope, NULL, 1);
+				}
+			}
+			else if (sym->st_shndx == SHN_COMMON) {
+				*got_entry = (unsigned long) _dl_find_hash(strtab +
+					sym->st_name, tpnt->symbol_scope, NULL, 1);
+			}
+			else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+				*got_entry != sym->st_value)
+				*got_entry += (unsigned long) tpnt->loadaddr;
+			else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
+				if (sym->st_other == 0)
+					*got_entry += (unsigned long) tpnt->loadaddr;
+			}
+			else {
+				*got_entry = (unsigned long) _dl_find_hash(strtab +
+					sym->st_name, tpnt->symbol_scope, NULL, 1);
+			}
+
+#ifdef DL_DEBUG
+			if (*got_entry == 0)
+				_dl_dprintf(2,"ZERO: %s\n", strtab + sym->st_name);
+#endif
+
+			got_entry++;
+			sym++;
+		}
+	}
+}

+ 1 - 40
ldso/ldso/mips/ld_sysdep.h

@@ -20,12 +20,10 @@
 
 
 /*
- * Initialization sequence for the application or library GOT.
+ * Initialization sequence for the application/library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)										\
 do {																	\
-	Elf32_Sym *sym;														\
-	char *strtab;														\
 	unsigned long i;													\
 																		\
 	/* Check if this is the dynamic linker itself */					\
@@ -41,43 +39,6 @@ do {																	\
 	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, 1);		\
-			}															\
-		}																\
-		else if (sym->st_shndx == SHN_COMMON) {							\
-			*GOT_BASE = (unsigned long) _dl_find_hash(strtab +			\
-				sym->st_name, MODULE->symbol_scope, NULL, 1);			\
-		}																\
-		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, 1);			\
-		}																\
-																		\
-		++GOT_BASE;														\
-		++sym;															\
-	}																	\
 } while (0)
 
 

+ 7 - 7
ldso/ldso/readelflib1.c

@@ -527,14 +527,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 #if defined(__mips__)
 	{
-	    int i = 1;
-	    Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+		int i = 1;
+		Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
 
-	    while(dpnt->d_tag) {
-		dpnt++;
-		i++;
-	    }
-	    dynamic_size = i * sizeof(Elf32_Dyn);
+		while(dpnt->d_tag) {
+			dpnt++;
+			i++;
+		}
+		dynamic_size = i;
 	}
 #endif