diff options
Diffstat (limited to 'ldso/ldso/m68k/elfinterp.c')
-rw-r--r-- | ldso/ldso/m68k/elfinterp.c | 45 |
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). */ } |