diff options
author | Rich Felker <dalias@aerifal.cx> | 2012-10-06 01:36:11 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2012-10-06 01:36:11 -0400 |
commit | bd17431a2cba8aafd1e4f95f9b70e5800ee51d24 (patch) | |
tree | 7dbe1f313dbdcb2275452b921b02ec58085be94a /src | |
parent | cf3fd3d002c728ed0ef5d3aef856ff3e1d418da0 (diff) | |
download | musl-bd17431a2cba8aafd1e4f95f9b70e5800ee51d24.tar.gz musl-bd17431a2cba8aafd1e4f95f9b70e5800ee51d24.tar.xz musl-bd17431a2cba8aafd1e4f95f9b70e5800ee51d24.zip |
fix symbol acceptance/rejection rules for TLS
symbol value of 0 is not "undefined" for TLS; it's the address of the first symbol in the TLS segment. however, non-definition TLS references also have values of 0, so check the section. hopefully the new logic is more clear, too.
Diffstat (limited to 'src')
-rw-r--r-- | src/ldso/dynlink.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 21c3ebad..db7770b9 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -209,14 +209,20 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def) if (!h) h = sysv_hash(s); sym = sysv_lookup(s, h, dso); } - if (sym && (!need_def || sym->st_shndx) && sym->st_value - && (1<<(sym->st_info&0xf) & OK_TYPES) - && (1<<(sym->st_info>>4) & OK_BINDS)) { - if (def.sym && sym->st_info>>4 == STB_WEAK) continue; - def.sym = sym; - def.dso = dso; - if (sym->st_info>>4 == STB_GLOBAL) break; - } + if (!sym) continue; + if (!sym->st_shndx) + if (need_def || (sym->st_info&0xf) == STT_TLS) + continue; + if (!sym->st_value) + if ((sym->st_info&0xf) != STT_TLS) + continue; + if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue; + if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue; + + if (def.sym && sym->st_info>>4 == STB_WEAK) continue; + def.sym = sym; + def.dso = dso; + if (sym->st_info>>4 == STB_GLOBAL) break; } return def; } |