summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-10-19 21:57:56 -0400
committerRich Felker <dalias@aerifal.cx>2012-10-19 21:57:56 -0400
commit0a1c2c1c1755d03d7d3db11df612bbe7c5b69c46 (patch)
tree57136fffdafc1f475e8b44b01f942684f4ac97d7
parentdeb15b3cf23cb6093f439f7b37eaeb1263df5399 (diff)
downloadmusl-0a1c2c1c1755d03d7d3db11df612bbe7c5b69c46.tar.gz
musl-0a1c2c1c1755d03d7d3db11df612bbe7c5b69c46.tar.bz2
musl-0a1c2c1c1755d03d7d3db11df612bbe7c5b69c46.tar.xz
musl-0a1c2c1c1755d03d7d3db11df612bbe7c5b69c46.zip
support looking up thread-local objects with dlsym
-rw-r--r--src/ldso/dynlink.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 39a27608..a6dbaf01 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -1089,6 +1089,8 @@ 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((size_t []){def.dso->tls_id, def.sym->st_value});
return def.dso->base + def.sym->st_value;
}
if (p->ghashtab) {
@@ -1098,6 +1100,8 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
h = sysv_hash(s);
sym = sysv_lookup(s, h, p);
}
+ if (sym && (sym->st_info&0xf) == STT_TLS)
+ return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
return p->base + sym->st_value;
if (p->deps) for (i=0; p->deps[i]; i++) {
@@ -1108,6 +1112,8 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
if (!h) h = sysv_hash(s);
sym = sysv_lookup(s, h, p->deps[i]);
}
+ if (sym && (sym->st_info&0xf) == STT_TLS)
+ return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
return p->deps[i]->base + sym->st_value;
}