浏览代码

support looking up thread-local objects with dlsym

Rich Felker 12 年之前
父节点
当前提交
0a1c2c1c17
共有 1 个文件被更改,包括 6 次插入0 次删除
  1. 6 0
      src/ldso/dynlink.c

+ 6 - 0
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;
 	}