From 37cd1676395e5ebdae3f372bf59d4fef54be9818 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 12 Oct 2018 12:26:44 -0400 Subject: [PATCH] fix dlsym of thread-local symbols on archs with DTP_OFFSET!=0 commit 6ba5517a460c6c438f64d69464fdfc3269a4c91a modified __tls_get_addr to offset the address by +DTP_OFFSET (0x8000 on powerpc, mips, etc.) and adjusted the result of DTPREL relocations by -DTP_OFFSET to compensate, but missed changing the argument setup for calls to __tls_get_addr from dlsym. --- ldso/dynlink.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index a3ca3cdf..42b078cf 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -1918,7 +1918,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) struct symdef def = find_sym(p, s, 0); if (!def.sym) goto failed; if ((def.sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value}); + return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET}); if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC) return def.dso->funcdescs + (def.sym - def.dso->syms); return laddr(def.dso, def.sym->st_value); @@ -1933,7 +1933,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) sym = sysv_lookup(s, h, p); } if (sym && (sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((tls_mod_off_t []){p->tls_id, sym->st_value}); + return __tls_get_addr((tls_mod_off_t []){p->tls_id, sym->st_value-DTP_OFFSET}); if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC) return p->funcdescs + (sym - p->syms); if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) @@ -1947,7 +1947,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) sym = sysv_lookup(s, h, p->deps[i]); } if (sym && (sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((tls_mod_off_t []){p->deps[i]->tls_id, sym->st_value}); + return __tls_get_addr((tls_mod_off_t []){p->deps[i]->tls_id, sym->st_value-DTP_OFFSET}); if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC) return p->deps[i]->funcdescs + (sym - p->deps[i]->syms); if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))