summaryrefslogtreecommitdiff
path: root/ldso/ldso/m68k/elfinterp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/m68k/elfinterp.c')
-rw-r--r--ldso/ldso/m68k/elfinterp.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c
index 15a2c43b1..25ea23067 100644
--- a/ldso/ldso/m68k/elfinterp.c
+++ b/ldso/ldso/m68k/elfinterp.c
@@ -150,6 +150,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
#if defined (__SUPPORT_LD_DEBUG__)
ElfW(Addr) old_val;
#endif
+#if defined USE_TLS && USE_TLS
+ struct elf_resolve *tls_tpnt = NULL;
+#endif
reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
reloc_type = ELF_R_TYPE(rpnt->r_info);
@@ -167,16 +170,28 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
* might have been intentional. We should not be linking local
* symbols here, so all bases should be covered.
*/
- if (unlikely(!symbol_addr && ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK)) {
- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
- _dl_exit(1);
+ if (unlikely (!symbol_addr &&
+ ELF_ST_TYPE (sym_ref.sym->st_info) != STT_TLS &&
+ ELF_ST_BIND (sym_ref.sym->st_info) != STB_WEAK)) {
+ return 1;
}
if (_dl_trace_prelink) {
_dl_debug_lookup (symname, tpnt, &symtab[symtab_index],
&sym_ref, elf_machine_type_class(reloc_type));
}
+#if defined USE_TLS && USE_TLS
+ tls_tpnt = sym_ref.tpnt;
+#endif
}
+#if defined USE_TLS && USE_TLS
+ /* In case of a TLS reloc, tls_tpnt 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 (!tls_tpnt)
+ tls_tpnt = tpnt;
+#endif
+
#if defined (__SUPPORT_LD_DEBUG__)
old_val = *reloc_addr;
#endif
@@ -209,13 +224,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_68K_JMP_SLOT:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
- /* handled by elf_machine_relative()
- case R_68K_RELATIVE:
- *reloc_addr = ((unsigned int) tpnt->loadaddr
- / * Compatibility kludge. * /
- + (rpnt->r_addend ? : *reloc_addr));
- */
- break;
case R_68K_COPY:
if (symbol_addr) {
#if defined (__SUPPORT_LD_DEBUG__)
@@ -234,7 +242,22 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
_dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
#endif
break;
-
+#if defined USE_TLS && USE_TLS
+ case R_68K_TLS_DTPMOD32:
+ *reloc_addr = tls_tpnt->l_tls_modid;
+ break;
+ case R_68K_TLS_DTPREL32:
+ if (sym_ref.sym != NULL)
+ *reloc_addr = TLS_DTPREL_VALUE (sym_ref.sym, rpnt);
+ break;
+ case R_68K_TLS_TPREL32:
+ if (sym_ref.sym != NULL)
+ {
+ CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
+ *reloc_addr = TLS_TPREL_VALUE ((struct link_map *) tls_tpnt, sym_ref.sym, rpnt);
+ }
+ break;
+#endif
default:
return -1; /* Calls _dl_exit(1). */
}