[git commit master] mips/ldso: Check for TLS relocation in elf_machine_type_class.

Khem Raj raj.khem at gmail.com
Mon Jan 25 22:24:26 UTC 2010


commit: http://git.uclibc.org/uClibc/commit/?id=37e26d6e19558d9f149722e513cb29c4374b8d8d
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/master

* Store the symbol adress received from _dl_find_hash
  and do not recompute it.

Signed-off-by: Khem Raj <raj.khem at gmail.com>
---
 ldso/ldso/mips/dl-sysdep.h |   20 ++++++++++++++++++--
 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 30d84fb..c1aad66 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 40c3e09..149fc56 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);
-- 
1.6.3.3



More information about the uClibc-cvs mailing list