diff options
| -rw-r--r-- | ldso/ldso/ldso.c | 5 | ||||
| -rw-r--r-- | ldso/ldso/mips/dl-sysdep.h | 2 | ||||
| -rw-r--r-- | ldso/ldso/mips/elfinterp.c | 115 | 
3 files changed, 44 insertions, 78 deletions
| diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 568081acd..5afc4a8f7 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -275,6 +275,11 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,  				INIT_GOT(lpnt, _dl_loaded_modules);  		} +#if defined(__mips__) +		/* Relocate any global GOT entries for the application */ +		_dl_perform_mips_global_got_relocations(app_tpnt); +#endif +  		/* OK, fill this in - we did not have this before */  		if (ppnt->p_type == PT_INTERP) {  			int readsize = 0; diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h index 9c4a21580..549bcef9e 100644 --- a/ldso/ldso/mips/dl-sysdep.h +++ b/ldso/ldso/mips/dl-sysdep.h @@ -42,6 +42,8 @@ do {										\  unsigned long _dl_linux_resolver(unsigned long sym_index,  	unsigned long old_gpreg); +struct elf_resolve; +void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt);  #define do_rem(result, n, base)  result = (n % base) diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c index 3e7672757..e9c6294ca 100644 --- a/ldso/ldso/mips/elfinterp.c +++ b/ldso/ldso/mips/elfinterp.c @@ -178,6 +178,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  	Elf32_Sym *symtab;  	Elf32_Rel *rpnt;  	char *strtab; +	unsigned long i;  	unsigned long *got;  	unsigned long *reloc_addr=NULL;  	unsigned long symbol_addr; @@ -186,47 +187,9 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  #if defined (__SUPPORT_LD_DEBUG__)  	unsigned long old_val=0;  #endif -	Elf32_Sym *sym; -	unsigned long i; -	unsigned long *got_entry; -	/* 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, ELF_RTYPE_CLASS_PLT); -			} -		} -		else if (sym->st_shndx == SHN_COMMON) { -			*got_entry = (unsigned long) _dl_find_hash(strtab + -								   sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT); -		} -		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, ELF_RTYPE_CLASS_PLT); -		} -		 -		got_entry++; -		sym++; -	} +	/* Relocate any global GOT entries for the object */ +	_dl_perform_mips_global_got_relocations(tpnt);  	/* Now parse the relocation information */  	rel_size = rel_size / sizeof(Elf32_Rel); @@ -294,54 +257,50 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  	return 0;  } -/* This function should be removed */ +/* Relocate the global GOT entries for the object */  void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)  { -#if 0 -	Elf32_Sym *sym;  	char *strtab; +	Elf32_Sym *sym;  	unsigned long i;  	unsigned long *got_entry; +	/* 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; -	for (; tpnt ; tpnt = tpnt->next) { -		/* 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, ELF_RTYPE_CLASS_PLT); -				} -			} -			else if (sym->st_shndx == SHN_COMMON) { -				*got_entry = (unsigned long) _dl_find_hash(strtab + -					sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT); -			} -			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; +	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, ELF_RTYPE_CLASS_PLT); +									   sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT);  			} - -			got_entry++; -			sym++;  		} +		else if (sym->st_shndx == SHN_COMMON) { +			*got_entry = (unsigned long) _dl_find_hash(strtab + +								   sym->st_name, tpnt->symbol_scope, ELF_RTYPE_CLASS_PLT); +		} +		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, ELF_RTYPE_CLASS_PLT); +		} + +		got_entry++; +		sym++;  	} -#endif  } | 
