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.
This commit is contained in:
Rich Felker 2012-10-06 01:36:11 -04:00
parent cf3fd3d002
commit bd17431a2c
1 changed files with 14 additions and 8 deletions

View File

@ -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;
}