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 | |
| parent | cf3fd3d002c728ed0ef5d3aef856ff3e1d418da0 (diff) | |
| download | musl-bd17431a2cba8aafd1e4f95f9b70e5800ee51d24.tar.gz | |
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.
| -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;  } | 
