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