[ELF] Pass Ctx & to Symbol

This commit is contained in:
Fangrui Song 2024-10-11 23:34:43 -07:00
parent a62768c427
commit dbd197118d
12 changed files with 104 additions and 100 deletions

View File

@ -1466,7 +1466,7 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
for (auto &p : ctx.symtab->cmseSymMap) {
Defined *d = cast<Defined>(p.second.sym);
impSymTab->addSymbol(makeDefined(
ctx.internalFile, d->getName(), d->computeBinding(),
ctx.internalFile, d->getName(), d->computeBinding(ctx),
/*stOther=*/0, STT_FUNC, d->getVA(), d->getSize(), nullptr));
}

View File

@ -254,9 +254,9 @@ static bool addOptional(Ctx &ctx, StringRef name, uint64_t value,
Symbol *sym = ctx.symtab->find(name);
if (!sym || sym->isDefined())
return false;
sym->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
STT_FUNC, value,
/*size=*/0, /*section=*/nullptr});
sym->resolve(ctx, Defined{ctx.internalFile, StringRef(), STB_GLOBAL,
STV_HIDDEN, STT_FUNC, value,
/*size=*/0, /*section=*/nullptr});
defined.push_back(cast<Defined>(sym));
return true;
}

View File

@ -2186,7 +2186,7 @@ static void handleUndefined(Ctx &ctx, Symbol *sym, const char *option) {
if (!sym->isLazy())
return;
sym->extract();
sym->extract(ctx);
if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back(option, sym->file, *sym);
}
@ -2217,7 +2217,7 @@ static void handleLibcall(Ctx &ctx, StringRef name) {
if (sym && sym->isLazy() && isa<BitcodeFile>(sym->file)) {
if (!ctx.arg.whyExtract.empty())
ctx.whyExtractRecords.emplace_back("<libcall>", sym->file, *sym);
sym->extract();
sym->extract(ctx);
}
}
@ -2416,7 +2416,7 @@ static void findKeepUniqueSections(Ctx &ctx, opt::InputArgList &args) {
// or DSOs, so we conservatively mark them as address-significant.
bool icfSafe = ctx.arg.icf == ICFLevel::Safe;
for (Symbol *sym : ctx.symtab->getSymbols())
if (sym->includeInDynsym())
if (sym->includeInDynsym(ctx))
markAddrsig(icfSafe, sym);
// Visit the address-significance table in each object file and mark each
@ -2465,7 +2465,7 @@ static void readSymbolPartitionSection(Ctx &ctx, InputSectionBase *s) {
sym = readEntry(s->file, rels.rels);
else
sym = readEntry(s->file, rels.relas);
if (!isa_and_nonnull<Defined>(sym) || !sym->includeInDynsym())
if (!isa_and_nonnull<Defined>(sym) || !sym->includeInDynsym(ctx))
return;
StringRef partName = reinterpret_cast<const char *>(s->content().data());
@ -2551,7 +2551,7 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
if (!ctx.arg.relocatable)
for (Symbol *sym : obj->getGlobalSymbols())
if (sym->hasVersionSuffix)
sym->parseSymbolVersion();
sym->parseSymbolVersion(ctx);
ctx.objectFiles.push_back(obj);
}
}
@ -2648,12 +2648,12 @@ static void combineVersionedSymbol(Ctx &ctx, Symbol &sym,
// If both foo@v1 and foo@@v1 are defined and non-weak, report a
// duplicate definition error.
if (sym.isDefined()) {
sym2->checkDuplicate(cast<Defined>(sym));
sym2->resolve(cast<Defined>(sym));
sym2->checkDuplicate(ctx, cast<Defined>(sym));
sym2->resolve(ctx, cast<Defined>(sym));
} else if (sym.isUndefined()) {
sym2->resolve(cast<Undefined>(sym));
sym2->resolve(ctx, cast<Undefined>(sym));
} else {
sym2->resolve(cast<SharedSymbol>(sym));
sym2->resolve(ctx, cast<SharedSymbol>(sym));
}
// Eliminate foo@v1 from the symbol table.
sym.symbolKind = Symbol::PlaceholderKind;

View File

@ -1156,14 +1156,14 @@ void ObjFile<ELFT>::initializeSymbols(const object::ELFFile<ELFT> &obj) {
fatal(toString(this) + ": common symbol '" + sym->getName() +
"' has invalid alignment: " + Twine(value));
hasCommonSyms = true;
sym->resolve(
CommonSymbol{this, StringRef(), binding, stOther, type, value, size});
sym->resolve(ctx, CommonSymbol{this, StringRef(), binding, stOther, type,
value, size});
continue;
}
// Handle global defined symbols. Defined::section will be set in postParse.
sym->resolve(Defined{this, StringRef(), binding, stOther, type, value, size,
nullptr});
sym->resolve(ctx, Defined{this, StringRef(), binding, stOther, type, value,
size, nullptr});
}
// Undefined symbols (excluding those defined relative to non-prevailing
@ -1175,8 +1175,8 @@ void ObjFile<ELFT>::initializeSymbols(const object::ELFFile<ELFT> &obj) {
for (unsigned i : undefineds) {
const Elf_Sym &eSym = eSyms[i];
Symbol *sym = symbols[i];
sym->resolve(Undefined{this, StringRef(), eSym.getBinding(), eSym.st_other,
eSym.getType()});
sym->resolve(ctx, Undefined{this, StringRef(), eSym.getBinding(),
eSym.st_other, eSym.getType()});
sym->isUsedInRegularObj = true;
sym->referenced = true;
}
@ -1759,20 +1759,20 @@ static void createBitcodeSymbol(Ctx &ctx, Symbol *&sym,
int c = objSym.getComdatIndex();
if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
Undefined newSym(&f, StringRef(), binding, visibility, type);
sym->resolve(newSym);
sym->resolve(ctx, newSym);
sym->referenced = true;
return;
}
if (objSym.isCommon()) {
sym->resolve(CommonSymbol{&f, StringRef(), binding, visibility, STT_OBJECT,
objSym.getCommonAlignment(),
objSym.getCommonSize()});
sym->resolve(ctx, CommonSymbol{&f, StringRef(), binding, visibility,
STT_OBJECT, objSym.getCommonAlignment(),
objSym.getCommonSize()});
} else {
Defined newSym(&f, StringRef(), binding, visibility, type, 0, 0, nullptr);
if (objSym.canBeOmittedFromSymbolTable())
newSym.exportDynamic = false;
sym->resolve(newSym);
sym->resolve(ctx, newSym);
}
}
@ -1813,7 +1813,7 @@ void BitcodeFile::parseLazy() {
irSym.Name = uniqueSaver().save(irSym.getName());
if (!irSym.isUndefined()) {
auto *sym = ctx.symtab->insert(irSym.getName());
sym->resolve(LazySymbol{*this});
sym->resolve(ctx, LazySymbol{*this});
symbols[i] = sym;
}
}
@ -1849,15 +1849,15 @@ void BinaryFile::parse() {
llvm::StringSaver &saver = lld::saver();
ctx.symtab->addAndCheckDuplicate(Defined{this, saver.save(s + "_start"),
STB_GLOBAL, STV_DEFAULT, STT_OBJECT,
0, 0, section});
ctx.symtab->addAndCheckDuplicate(Defined{this, saver.save(s + "_end"),
STB_GLOBAL, STV_DEFAULT, STT_OBJECT,
data.size(), 0, section});
ctx.symtab->addAndCheckDuplicate(Defined{this, saver.save(s + "_size"),
STB_GLOBAL, STV_DEFAULT, STT_OBJECT,
data.size(), 0, nullptr});
ctx.symtab->addAndCheckDuplicate(ctx, Defined{this, saver.save(s + "_start"),
STB_GLOBAL, STV_DEFAULT,
STT_OBJECT, 0, 0, section});
ctx.symtab->addAndCheckDuplicate(
ctx, Defined{this, saver.save(s + "_end"), STB_GLOBAL, STV_DEFAULT,
STT_OBJECT, data.size(), 0, section});
ctx.symtab->addAndCheckDuplicate(
ctx, Defined{this, saver.save(s + "_size"), STB_GLOBAL, STV_DEFAULT,
STT_OBJECT, data.size(), 0, nullptr});
}
InputFile *elf::createInternalFile(Ctx &ctx, StringRef name) {
@ -1906,7 +1906,7 @@ template <class ELFT> void ObjFile<ELFT>::parseLazy() {
if (eSyms[i].st_shndx == SHN_UNDEF)
continue;
symbols[i] = symtab->insert(CHECK(eSyms[i].getName(stringTable), this));
symbols[i]->resolve(LazySymbol{*this});
symbols[i]->resolve(ctx, LazySymbol{*this});
if (!lazy)
break;
}

View File

@ -249,12 +249,12 @@ void BitcodeCompiler::add(BitcodeFile &f) {
// 5) Symbols that will be referenced after linker wrapping is performed.
r.VisibleToRegularObj = ctx.arg.relocatable || sym->isUsedInRegularObj ||
sym->referencedAfterWrap ||
(r.Prevailing && sym->includeInDynsym()) ||
(r.Prevailing && sym->includeInDynsym(ctx)) ||
usedStartStop.count(objSym.getSectionName());
// Identify symbols exported dynamically, and that therefore could be
// referenced by a shared library not visible to the linker.
r.ExportDynamic =
sym->computeBinding() != STB_LOCAL &&
sym->computeBinding(ctx) != STB_LOCAL &&
(ctx.arg.exportDynamic || sym->exportDynamic || sym->inDynamicList);
const auto *dr = dyn_cast<Defined>(sym);
r.FinalDefinitionInLinkageUnit =

View File

@ -221,7 +221,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
// Preserve externally-visible symbols if the symbols defined by this
// file can interpose other ELF file's symbols at runtime.
for (Symbol *sym : ctx.symtab->getSymbols())
if (sym->includeInDynsym() && sym->partition == partition)
if (sym->includeInDynsym(ctx) && sym->partition == partition)
markSymbol(sym);
// If this isn't the main partition, that's all that we need to preserve.

View File

@ -98,11 +98,11 @@ Symbol *SymbolTable::insert(StringRef name) {
// This variant of addSymbol is used by BinaryFile::parse to check duplicate
// symbol errors.
Symbol *SymbolTable::addAndCheckDuplicate(const Defined &newSym) {
Symbol *SymbolTable::addAndCheckDuplicate(Ctx &ctx, const Defined &newSym) {
Symbol *sym = insert(newSym.getName());
if (sym->isDefined())
sym->checkDuplicate(newSym);
sym->resolve(newSym);
sym->checkDuplicate(ctx, newSym);
sym->resolve(ctx, newSym);
sym->isUsedInRegularObj = true;
return sym;
}
@ -227,7 +227,7 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
for (Symbol *sym : syms) {
// For a non-local versionId, skip symbols containing version info because
// symbol versions specified by symbol names take precedence over version
// scripts. See parseSymbolVersion().
// scripts. See parseSymbolVersion(ctx).
if (!includeNonDefault && versionId != VER_NDX_LOCAL &&
sym->getName().contains('@'))
continue;
@ -353,10 +353,10 @@ void SymbolTable::scanVersionScript() {
// Let them parse and update their names to exclude version suffix.
for (Symbol *sym : symVector)
if (sym->hasVersionSuffix)
sym->parseSymbolVersion();
sym->parseSymbolVersion(ctx);
// isPreemptible is false at this point. To correctly compute the binding of a
// Defined (which is used by includeInDynsym()), we need to know if it is
// Defined (which is used by includeInDynsym(ctx)), we need to know if it is
// VER_NDX_LOCAL or not. Compute symbol versions before handling
// --dynamic-list.
handleDynamicList();

View File

@ -47,10 +47,10 @@ public:
template <typename T> Symbol *addSymbol(const T &newSym) {
Symbol *sym = insert(newSym.getName());
sym->resolve(newSym);
sym->resolve(ctx, newSym);
return sym;
}
Symbol *addAndCheckDuplicate(const Defined &newSym);
Symbol *addAndCheckDuplicate(Ctx &, const Defined &newSym);
void scanVersionScript();

View File

@ -199,7 +199,7 @@ OutputSection *Symbol::getOutputSection() const {
// If a symbol name contains '@', the characters after that is
// a symbol version name. This function parses that.
void Symbol::parseSymbolVersion() {
void Symbol::parseSymbolVersion(Ctx &ctx) {
// Return if localized by a local: pattern in a version script.
if (versionId == VER_NDX_LOCAL)
return;
@ -247,14 +247,14 @@ void Symbol::parseSymbolVersion() {
verstr);
}
void Symbol::extract() const {
void Symbol::extract(Ctx &ctx) const {
if (file->lazy) {
file->lazy = false;
parseFile(ctx, file);
}
}
uint8_t Symbol::computeBinding() const {
uint8_t Symbol::computeBinding(Ctx &ctx) const {
auto v = visibility();
if ((v != STV_DEFAULT && v != STV_PROTECTED) || versionId == VER_NDX_LOCAL)
return STB_LOCAL;
@ -263,8 +263,8 @@ uint8_t Symbol::computeBinding() const {
return binding;
}
bool Symbol::includeInDynsym() const {
if (computeBinding() == STB_LOCAL)
bool Symbol::includeInDynsym(Ctx &ctx) const {
if (computeBinding(ctx) == STB_LOCAL)
return false;
if (!isDefined() && !isCommon())
// This should unconditionally return true, unfortunately glibc -static-pie
@ -293,7 +293,7 @@ void elf::printTraceSymbol(const Symbol &sym, StringRef name) {
message(toString(sym.file) + s + name);
}
static void recordWhyExtract(const InputFile *reference,
static void recordWhyExtract(Ctx &ctx, const InputFile *reference,
const InputFile &extracted, const Symbol &sym) {
ctx.whyExtractRecords.emplace_back(toString(reference), &extracted, sym);
}
@ -339,7 +339,7 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
// Only symbols with default visibility that appear in dynsym can be
// preempted. Symbols with protected visibility cannot be preempted.
if (!sym.includeInDynsym() || sym.visibility() != STV_DEFAULT)
if (!sym.includeInDynsym(ctx) || sym.visibility() != STV_DEFAULT)
return false;
// At this point copy relocations have not been created yet, so any
@ -380,7 +380,7 @@ void Symbol::mergeProperties(const Symbol &other) {
}
}
void Symbol::resolve(const Undefined &other) {
void Symbol::resolve(Ctx &ctx, const Undefined &other) {
if (other.visibility() != STV_DEFAULT) {
uint8_t v = visibility(), ov = other.visibility();
setVisibility(v == STV_DEFAULT ? ov : std::min(v, ov));
@ -460,10 +460,10 @@ void Symbol::resolve(const Undefined &other) {
// group assignment rule simulates the traditional linker's semantics.
bool backref = ctx.arg.warnBackrefs && other.file &&
file->groupId < other.file->groupId;
extract();
extract(ctx);
if (!ctx.arg.whyExtract.empty())
recordWhyExtract(other.file, *file, *this);
recordWhyExtract(ctx, other.file, *file, *this);
// We don't report backward references to weak symbols as they can be
// overridden later.
@ -493,7 +493,7 @@ void Symbol::resolve(const Undefined &other) {
}
// Compare two symbols. Return true if the new symbol should win.
bool Symbol::shouldReplace(const Defined &other) const {
bool Symbol::shouldReplace(Ctx &ctx, const Defined &other) const {
if (LLVM_UNLIKELY(isCommon())) {
if (ctx.arg.warnCommon)
warn("common " + getName() + " is overridden");
@ -553,14 +553,14 @@ void elf::reportDuplicate(Ctx &ctx, const Symbol &sym, const InputFile *newFile,
errorOrWarn(msg);
}
void Symbol::checkDuplicate(const Defined &other) const {
void Symbol::checkDuplicate(Ctx &ctx, const Defined &other) const {
if (isDefined() && !isWeak() && !other.isWeak())
reportDuplicate(ctx, *this, other.file,
dyn_cast_or_null<InputSectionBase>(other.section),
other.value);
}
void Symbol::resolve(const CommonSymbol &other) {
void Symbol::resolve(Ctx &ctx, const CommonSymbol &other) {
if (other.exportDynamic)
exportDynamic = true;
if (other.visibility() != STV_DEFAULT) {
@ -598,18 +598,18 @@ void Symbol::resolve(const CommonSymbol &other) {
}
}
void Symbol::resolve(const Defined &other) {
void Symbol::resolve(Ctx &ctx, const Defined &other) {
if (other.exportDynamic)
exportDynamic = true;
if (other.visibility() != STV_DEFAULT) {
uint8_t v = visibility(), ov = other.visibility();
setVisibility(v == STV_DEFAULT ? ov : std::min(v, ov));
}
if (shouldReplace(other))
if (shouldReplace(ctx, other))
other.overwrite(*this);
}
void Symbol::resolve(const LazySymbol &other) {
void Symbol::resolve(Ctx &ctx, const LazySymbol &other) {
if (isPlaceholder()) {
other.overwrite(*this);
return;
@ -621,7 +621,7 @@ void Symbol::resolve(const LazySymbol &other) {
other.file->shouldExtractForCommon(getName())) {
ctx.backwardReferences.erase(this);
other.overwrite(*this);
other.extract();
other.extract(ctx);
return;
}
@ -643,12 +643,12 @@ void Symbol::resolve(const LazySymbol &other) {
}
const InputFile *oldFile = file;
other.extract();
other.extract(ctx);
if (!ctx.arg.whyExtract.empty())
recordWhyExtract(oldFile, *file, *this);
recordWhyExtract(ctx, oldFile, *file, *this);
}
void Symbol::resolve(const SharedSymbol &other) {
void Symbol::resolve(Ctx &ctx, const SharedSymbol &other) {
exportDynamic = true;
if (isPlaceholder()) {
other.overwrite(*this);

View File

@ -166,8 +166,8 @@ public:
stOther = (stOther & ~3) | visibility;
}
bool includeInDynsym() const;
uint8_t computeBinding() const;
bool includeInDynsym(Ctx &) const;
uint8_t computeBinding(Ctx &) const;
bool isGlobal() const { return binding == llvm::ELF::STB_GLOBAL; }
bool isWeak() const { return binding == llvm::ELF::STB_WEAK; }
@ -192,12 +192,12 @@ public:
nameSize = s.size();
}
void parseSymbolVersion();
void parseSymbolVersion(Ctx &);
// Get the NUL-terminated version suffix ("", "@...", or "@@...").
//
// For @@, the name has been truncated by insert(). For @, the name has been
// truncated by Symbol::parseSymbolVersion().
// truncated by Symbol::parseSymbolVersion(ctx).
const char *getVersionSuffix() const { return nameData + nameSize; }
uint32_t getGotIdx(Ctx &ctx) const { return ctx.symAux[auxIdx].gotIdx; }
@ -234,21 +234,21 @@ public:
// For example, if "this" is an undefined symbol and a new symbol is
// a defined symbol, "this" is replaced with the new symbol.
void mergeProperties(const Symbol &other);
void resolve(const Undefined &other);
void resolve(const CommonSymbol &other);
void resolve(const Defined &other);
void resolve(const LazySymbol &other);
void resolve(const SharedSymbol &other);
void resolve(Ctx &, const Undefined &other);
void resolve(Ctx &, const CommonSymbol &other);
void resolve(Ctx &, const Defined &other);
void resolve(Ctx &, const LazySymbol &other);
void resolve(Ctx &, const SharedSymbol &other);
// If this is a lazy symbol, extract an input file and add the symbol
// in the file to the symbol table. Calling this function on
// non-lazy object causes a runtime error.
void extract() const;
void extract(Ctx &) const;
void checkDuplicate(const Defined &other) const;
void checkDuplicate(Ctx &, const Defined &other) const;
private:
bool shouldReplace(const Defined &other) const;
bool shouldReplace(Ctx &, const Defined &other) const;
protected:
Symbol(Kind k, InputFile *file, StringRef name, uint8_t binding,

View File

@ -1283,7 +1283,9 @@ void StringTableSection::writeTo(uint8_t *buf) {
// Returns the number of entries in .gnu.version_d: the number of
// non-VER_NDX_LOCAL-non-VER_NDX_GLOBAL definitions, plus 1.
// Note that we don't support vd_cnt > 1 yet.
static unsigned getVerDefNum() { return namedVersionDefs(ctx).size() + 1; }
static unsigned getVerDefNum(Ctx &ctx) {
return namedVersionDefs(ctx).size() + 1;
}
template <class ELFT>
DynamicSection<ELFT>::DynamicSection(Ctx &ctx)
@ -1530,7 +1532,7 @@ DynamicSection<ELFT>::computeContents() {
addInSec(DT_VERSYM, *part.verSym);
if (part.verDef && part.verDef->isLive()) {
addInSec(DT_VERDEF, *part.verDef);
addInt(DT_VERDEFNUM, getVerDefNum());
addInt(DT_VERDEFNUM, getVerDefNum(ctx));
}
if (part.verNeed && part.verNeed->isNeeded()) {
addInSec(DT_VERNEED, *part.verNeed);
@ -3711,7 +3713,7 @@ void VersionDefinitionSection::finalizeContents() {
// sh_info should be set to the number of definitions. This fact is missed in
// documentation, but confirmed by binutils community:
// https://sourceware.org/ml/binutils/2014-11/msg00355.html
getParent()->info = getVerDefNum();
getParent()->info = getVerDefNum(ctx);
}
void VersionDefinitionSection::writeOne(uint8_t *buf, uint32_t index,
@ -3746,7 +3748,7 @@ void VersionDefinitionSection::writeTo(uint8_t *buf) {
}
size_t VersionDefinitionSection::getSize() const {
return EntrySize * getVerDefNum();
return EntrySize * getVerDefNum(ctx);
}
// .gnu.version is a table where each entry is 2 byte long.
@ -3792,10 +3794,10 @@ void elf::addVerneed(Symbol *ss) {
// Select a version identifier for the vernaux data structure, if we haven't
// already allocated one. The verdef identifiers cover the range
// [1..getVerDefNum()]; this causes the vernaux identifiers to start from
// getVerDefNum()+1.
// [1..getVerDefNum(ctx)]; this causes the vernaux identifiers to start from
// getVerDefNum(ctx)+1.
if (file.vernauxs[ss->versionId] == 0)
file.vernauxs[ss->versionId] = ++SharedFile::vernauxNum + getVerDefNum();
file.vernauxs[ss->versionId] = ++SharedFile::vernauxNum + getVerDefNum(ctx);
ss->versionId = file.vernauxs[ss->versionId];
}
@ -3828,7 +3830,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
if (isGlibc2) {
const char *ver = "GLIBC_ABI_DT_RELR";
vn.vernauxs.push_back({hashSysV(ver),
++SharedFile::vernauxNum + getVerDefNum(),
++SharedFile::vernauxNum + getVerDefNum(ctx),
getPartition().dynStrTab->addString(ver)});
}
}
@ -4671,9 +4673,9 @@ static Defined *addOptionalRegular(Ctx &ctx, StringRef name, SectionBase *sec,
if (!s || s->isDefined() || s->isCommon())
return nullptr;
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, stOther,
STT_NOTYPE, val,
/*size=*/0, sec});
s->resolve(ctx, Defined{ctx.internalFile, StringRef(), STB_GLOBAL, stOther,
STT_NOTYPE, val,
/*size=*/0, sec});
s->isUsedInRegularObj = true;
return cast<Defined>(s);
}
@ -4756,7 +4758,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
add(*part.buildId);
}
// dynSymTab is always present to simplify sym->includeInDynsym() in
// dynSymTab is always present to simplify sym->includeInDynsym(ctx) in
// finalizeSections.
part.dynStrTab = std::make_unique<StringTableSection>(ctx, ".dynstr", true);
part.dynSymTab =

View File

@ -145,9 +145,9 @@ static Defined *addOptionalRegular(Ctx &ctx, StringRef name, SectionBase *sec,
if (!s || s->isDefined() || s->isCommon())
return nullptr;
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, stOther,
STT_NOTYPE, val,
/*size=*/0, sec});
s->resolve(ctx, Defined{ctx.internalFile, StringRef(), STB_GLOBAL, stOther,
STT_NOTYPE, val,
/*size=*/0, sec});
s->isUsedInRegularObj = true;
return cast<Defined>(s);
}
@ -211,7 +211,8 @@ void elf::addReservedSymbols(Ctx &ctx) {
if (ctx.arg.emachine == EM_PPC64)
gotOff = 0x8000;
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
s->resolve(ctx,
Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
STT_NOTYPE, gotOff, /*size=*/0, ctx.out.elfHeader});
ctx.sym.globalOffsetTable = cast<Defined>(s);
}
@ -1774,9 +1775,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// define _TLS_MODULE_BASE_ relative to the first TLS section.
Symbol *s = ctx.symtab->find("_TLS_MODULE_BASE_");
if (s && s->isUndefined()) {
s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL,
STV_HIDDEN, STT_TLS, /*value=*/0, 0,
/*section=*/nullptr});
s->resolve(ctx, Defined{ctx.internalFile, StringRef(), STB_GLOBAL,
STV_HIDDEN, STT_TLS, /*value=*/0, 0,
/*section=*/nullptr});
ctx.sym.tlsModuleBase = cast<Defined>(s);
}
}
@ -1851,7 +1852,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
diagnose("undefined reference: " + toString(*sym) +
"\n>>> referenced by " + toString(file) +
" (disallowed by --no-allow-shlib-undefined)");
} else if (sym->isDefined() && sym->computeBinding() == STB_LOCAL) {
} else if (sym->isDefined() &&
sym->computeBinding(ctx) == STB_LOCAL) {
diagnose("non-exported symbol '" + toString(*sym) + "' in '" +
toString(sym->file) + "' is referenced by DSO '" +
toString(file) + "'");
@ -1869,11 +1871,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (!sym->isUsedInRegularObj || !includeInSymtab(ctx, *sym))
continue;
if (!ctx.arg.relocatable)
sym->binding = sym->computeBinding();
sym->binding = sym->computeBinding(ctx);
if (ctx.in.symTab)
ctx.in.symTab->addSymbol(sym);
if (sym->includeInDynsym()) {
if (sym->includeInDynsym(ctx)) {
ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
if (file->isNeeded && !sym->isUndefined())