diff options
| -rw-r--r-- | ldso/ldso/mips/dl-sysdep.h | 20 | ||||
| -rw-r--r-- | ldso/ldso/mips/elfinterp.c | 31 | 
2 files changed, 35 insertions, 16 deletions
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h index 30d84fbc5..c1aad6661 100644 --- a/ldso/ldso/mips/dl-sysdep.h +++ b/ldso/ldso/mips/dl-sysdep.h @@ -163,9 +163,25 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy)  #define OFFS_ALIGN (0x10000000000UL-0x1000)  #endif	/* O32 || N32 */ -#define elf_machine_type_class(type) \ -  ((((type) == R_MIPS_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\ +#if defined USE_TLS +# if _MIPS_SIM == _MIPS_SIM_ABI64 +# define elf_machine_type_class(type) 					\ +  ((((type) == R_MIPS_JUMP_SLOT || (type) == R_MIPS_TLS_DTPMOD64	\ +     || (type) == R_MIPS_TLS_DTPREL64 || (type) == R_MIPS_TLS_TPREL64)	\ +    * ELF_RTYPE_CLASS_PLT)						\     | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) +# else +# define elf_machine_type_class(type)					\ +  ((((type) == R_MIPS_JUMP_SLOT || (type) == R_MIPS_TLS_DTPMOD32	\ +     || (type) == R_MIPS_TLS_DTPREL32 || (type) == R_MIPS_TLS_TPREL32)	\ +    * ELF_RTYPE_CLASS_PLT)						\ +   | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) +# endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ +#else +#define elf_machine_type_class(type)					\ +  ((((type) == R_MIPS_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT)			\ +   | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* USE_TLS */  #define OFFSET_GP_GOT 0x7ff0 diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c index 40c3e0939..149fc5674 100644 --- a/ldso/ldso/mips/elfinterp.c +++ b/ldso/ldso/mips/elfinterp.c @@ -156,6 +156,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  	unsigned long symbol_addr;  	int reloc_type, symtab_index;  	struct elf_resolve *tpnt = xpnt->dyn; +	char *symname = NULL;  #if defined (__SUPPORT_LD_DEBUG__)  	unsigned long old_val=0;  #endif @@ -169,7 +170,6 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  	got = (unsigned long *) tpnt->dynamic_info[DT_PLTGOT];  	for (i = 0; i < rel_size; i++, rpnt++) { -		char *symname = NULL;  		reloc_addr = (unsigned long *) (tpnt->loadaddr +  			(unsigned long) rpnt->r_offset);  		reloc_type = ELF32_R_TYPE(rpnt->r_info); @@ -178,13 +178,13 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  		debug_sym(symtab,strtab,symtab_index);  		debug_reloc(symtab,strtab,rpnt); +		symname = strtab + symtab[symtab_index].st_name;  #if defined (__SUPPORT_LD_DEBUG__)  		if (reloc_addr)  			old_val = *reloc_addr;  #endif  		if (reloc_type == R_MIPS_JUMP_SLOT || reloc_type == R_MIPS_COPY) { -			symname = strtab + symtab[symtab_index].st_name;  			symbol_addr = (unsigned long)_dl_find_hash(symname,  								   tpnt->symbol_scope,  								   tpnt, @@ -192,6 +192,13 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  			if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))  				return 1;  		} +		if (!symtab_index) { +			/* Relocs against STN_UNDEF are usually treated as using a +			* symbol value of zero, and using the module containing the +			* reloc itself. +			*/ +			symbol_addr = symtab[symtab_index].st_value; +		}  		switch (reloc_type) {  #if USE_TLS @@ -205,21 +212,17 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  		case R_MIPS_TLS_TPREL32:  # endif  			{ -				ElfW(Sym) *sym_tls = &symtab[symtab_index];  				struct elf_resolve *tpnt_tls = NULL;  				if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_LOCAL) { -					_dl_find_hash((strtab + symtab[symtab_index].st_name), -							_dl_symbol_tables, tpnt, -							elf_machine_type_class(reloc_type), &tpnt_tls); +					symbol_addr = (unsigned long) _dl_find_hash(symname, tpnt->symbol_scope, +						tpnt, elf_machine_type_class(reloc_type), &tpnt_tls);  				} -#if USE_TLS  			    /* In case of a TLS reloc, tpnt_tls NULL means we have an 'anonymous'  			       symbol.  This is the case for a static tls variable, so the lookup  			       module is just that one is referencing the tls variable. */  			    if (!tpnt_tls)  			        tpnt_tls = tpnt; -#endif  				switch (reloc_type) {  					case R_MIPS_TLS_DTPMOD64: @@ -228,17 +231,17 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  							*(ElfW(Word) *)reloc_addr = tpnt_tls->l_tls_modid;  #ifdef __SUPPORT_LD_DEBUG__  						_dl_dprintf(2, "TLS_DTPMOD : %s, %d, %d\n", -							(strtab + symtab[symtab_index].st_name), old_val, *((unsigned int *)reloc_addr)); +							symname, old_val, *((unsigned int *)reloc_addr));  #endif  						break;  					case R_MIPS_TLS_DTPREL64:  					case R_MIPS_TLS_DTPREL32:  						*(ElfW(Word) *)reloc_addr += -							TLS_DTPREL_VALUE (sym_tls); +							TLS_DTPREL_VALUE (symbol_addr);  #ifdef __SUPPORT_LD_DEBUG__  						_dl_dprintf(2, "TLS_DTPREL : %s, %x, %x\n", -							(strtab + symtab[symtab_index].st_name), old_val, *((unsigned int *)reloc_addr)); +							symname, old_val, *((unsigned int *)reloc_addr));  #endif  						break; @@ -246,10 +249,10 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  					case R_MIPS_TLS_TPREL64:  						CHECK_STATIC_TLS((struct link_map *)tpnt_tls);  						*(ElfW(Word) *)reloc_addr += -							TLS_TPREL_VALUE (tpnt_tls, sym_tls); +							TLS_TPREL_VALUE (tpnt_tls, symbol_addr);  #ifdef __SUPPORT_LD_DEBUG__  						_dl_dprintf(2, "TLS_TPREL  : %s, %x, %x\n", -							(strtab + symtab[symtab_index].st_name), old_val, *((unsigned int *)reloc_addr)); +							symname, old_val, *((unsigned int *)reloc_addr));  #endif  						break;  				} @@ -301,7 +304,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,  				_dl_dprintf(2, "\n%s: ",_dl_progname);  				if (symtab_index) -					_dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name); +					_dl_dprintf(2, "symbol '%s': ", symname);  #if defined (__SUPPORT_LD_DEBUG__)  				_dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", _dl_reltypes(reloc_type), tpnt->libname);  | 
