svn commit: branches/uClibc-nptl/ldso/ldso/mips

carmelo at uclibc.org carmelo at uclibc.org
Wed Mar 4 09:56:24 UTC 2009


Author: carmelo
Date: 2009-03-04 09:56:23 +0000 (Wed, 04 Mar 2009)
New Revision: 25520

Log:
Re-add/merge TLS relocations support for MIPS that
have been erroneously removed in rev 24524.

Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com>


Modified:
   branches/uClibc-nptl/ldso/ldso/mips/elfinterp.c


Changeset:
Modified: branches/uClibc-nptl/ldso/ldso/mips/elfinterp.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/mips/elfinterp.c	2009-03-04 01:33:22 UTC (rev 25519)
+++ branches/uClibc-nptl/ldso/ldso/mips/elfinterp.c	2009-03-04 09:56:23 UTC (rev 25520)
@@ -56,7 +56,7 @@
 	symname = strtab + sym->st_name;
 
 	new_addr = (unsigned long) _dl_find_hash(symname,
-			tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+			tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
 	if (unlikely(!new_addr)) {
 		_dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
 				_dl_progname, symname);
@@ -111,7 +111,7 @@
 	got_addr = (char **)instr_addr;
 
 	/* Get the address of the GOT entry. */
-	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
 	if (unlikely(!new_addr)) {
 		_dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
 		_dl_exit(1);
@@ -188,13 +188,66 @@
 			symbol_addr = (unsigned long)_dl_find_hash(symname,
 								   tpnt->symbol_scope,
 								   tpnt,
-								   elf_machine_type_class(reloc_type));
+								   elf_machine_type_class(reloc_type), NULL);
 			if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
 				return 1;
 		}
 
 		switch (reloc_type) {
-#if _MIPS_SIM == _MIPS_SIM_ABI64
+#if USE_TLS
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+		case R_MIPS_TLS_DTPMOD64:
+		case R_MIPS_TLS_DTPREL64:
+		case R_MIPS_TLS_TPREL64:
+# else
+		case R_MIPS_TLS_DTPMOD32:
+		case R_MIPS_TLS_DTPREL32:
+		case R_MIPS_TLS_TPREL32:
+# endif
+			{
+				ElfW(Sym) *sym_tls = &symtab[symtab_index];
+				struct elf_resolve *tpnt_tls = tpnt;
+
+				if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_LOCAL) {
+					_dl_find_hash((strtab + symtab[symtab_index].st_name),
+							_dl_symbol_tables, tpnt_tls, 1, &sym_tls);
+				}
+
+				switch (reloc_type)
+	  			{
+					case R_MIPS_TLS_DTPMOD64:
+					case R_MIPS_TLS_DTPMOD32:
+						if (tpnt_tls)
+							*(ElfW(Word) *)reloc_addr = tpnt_tls->l_tls_modid;
+#if defined (__SUPPORT_LD_DEBUG__)
+_dl_dprintf(2, "TLS_DTPMOD : %s, %d, %d\n", (strtab + symtab[symtab_index].st_name), 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);
+#if defined (__SUPPORT_LD_DEBUG__)
+_dl_dprintf(2, "TLS_DTPREL : %s, %x, %x\n", (strtab + symtab[symtab_index].st_name), old_val, *((unsigned int *)reloc_addr));
+#endif
+						break;
+
+					case R_MIPS_TLS_TPREL32:
+					case R_MIPS_TLS_TPREL64:
+						CHECK_STATIC_TLS((struct link_map *)tpnt_tls);
+						*(ElfW(Word) *)reloc_addr +=
+							TLS_TPREL_VALUE (tpnt_tls, sym_tls);
+#if defined (__SUPPORT_LD_DEBUG__)
+_dl_dprintf(2, "TLS_TPREL  : %s, %x, %x\n", (strtab + symtab[symtab_index].st_name), old_val, *((unsigned int *)reloc_addr));
+#endif
+						break;
+				}
+
+				break;
+			}
+#endif /* USE_TLS */
+#if _MIPS_SIM == _MIS_SIM_ABI64
 		case (R_MIPS_64 << 8) | R_MIPS_REL32:
 #else	/* O32 || N32 */
 		case R_MIPS_REL32:
@@ -241,9 +294,9 @@
 					_dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
 
 #if defined (__SUPPORT_LD_DEBUG__)
-				_dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
+				_dl_dprintf(2, "can't handle reloc type '%s' in lib '%s'\n", _dl_reltypes(reloc_type), tpnt->libname);
 #else
-				_dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
+				_dl_dprintf(2, "can't handle reloc type %x in lib '%s'\n", reloc_type, tpnt->libname);
 #endif
 				_dl_exit(1);
 			}
@@ -292,12 +345,12 @@
 				}
 				else {
 					*got_entry = (unsigned long) _dl_find_hash(strtab +
-						sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+						sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
 				}
 			}
 			else if (sym->st_shndx == SHN_COMMON) {
 				*got_entry = (unsigned long) _dl_find_hash(strtab +
-					sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+					sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
 			}
 			else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
 				*got_entry != sym->st_value && tmp_lazy) {
@@ -309,7 +362,7 @@
 			}
 			else {
 				*got_entry = (unsigned long) _dl_find_hash(strtab +
-					sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+					sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
 			}
 
 			got_entry++;



More information about the uClibc-cvs mailing list