summaryrefslogtreecommitdiff
path: root/gnu/llvm
diff options
context:
space:
mode:
authorRobert Nagy <robert@cvs.openbsd.org>2022-11-17 12:24:03 +0000
committerRobert Nagy <robert@cvs.openbsd.org>2022-11-17 12:24:03 +0000
commit0a96cf0b0a3b31f2ae329f624cabd9295bca7281 (patch)
tree4c2e43ab72fc3f24c4a87ac3b2e5ed3c1cb0af28 /gnu/llvm
parent3cb5d42025e6c024c6e514144a5ad1cfb92149a1 (diff)
add .gnu.warning.SYMBOL support to ld.lld(1) to display the warnings in
these sections like ld.bfd(1) e.g: add.c(add.o:(add)): warning: sprintf() is often misused, please use snprintf() add.c(add.o:(add)): warning: strcpy() is almost always misused, please use strlcpy() add.c(add.o:(add)): warning: strcat() is almost always misused, please use strlcat() ok deraadt@
Diffstat (limited to 'gnu/llvm')
-rw-r--r--gnu/llvm/lld/ELF/InputFiles.cpp31
-rw-r--r--gnu/llvm/lld/ELF/InputFiles.h73
-rw-r--r--gnu/llvm/lld/ELF/Relocations.cpp14
-rw-r--r--gnu/llvm/lld/ELF/SymbolTable.cpp167
-rw-r--r--gnu/llvm/lld/ELF/Symbols.h8
5 files changed, 217 insertions, 76 deletions
diff --git a/gnu/llvm/lld/ELF/InputFiles.cpp b/gnu/llvm/lld/ELF/InputFiles.cpp
index ab65571887d..75652403e1d 100644
--- a/gnu/llvm/lld/ELF/InputFiles.cpp
+++ b/gnu/llvm/lld/ELF/InputFiles.cpp
@@ -52,6 +52,8 @@ std::vector<SharedFile *> elf::sharedFiles;
std::unique_ptr<TarWriter> elf::tar;
+DenseMap<StringRef, StringRef> elf::gnuWarnings;
+
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
std::string lld::toString(const InputFile *f) {
if (!f)
@@ -66,6 +68,17 @@ std::string lld::toString(const InputFile *f) {
return f->toStringCache;
}
+// .gnu.warning.SYMBOL are treated as warning symbols for the given symbol
+void lld::parseGNUWarning(StringRef name, ArrayRef<char> data, size_t size) {
+ if (!name.empty() && name.startswith(".gnu.warning.")) {
+ StringRef wsym = name.substr(13);
+ StringRef s(data.begin());
+ StringRef wng(s.substr(0, size));
+ symtab->insert(wsym)->gwarn = true;
+ gnuWarnings.insert({wsym, wng});
+ }
+}
+
static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
unsigned char size;
unsigned char endian;
@@ -647,6 +660,14 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
case SHT_RELA:
case SHT_NULL:
break;
+ case SHT_PROGBITS: {
+ this->sections[i] = createInputSection(sec);
+ StringRef name = CHECK(obj.getSectionName(sec, this->sectionStringTable), this);
+ ArrayRef<char> data =
+ CHECK(obj.template getSectionContentsAsArray<char>(sec), this);
+ parseGNUWarning(name, data, sec.sh_size);
+ }
+ break;
default:
this->sections[i] = createInputSection(sec);
}
@@ -1450,6 +1471,9 @@ template <class ELFT> void SharedFile::parse() {
const ELFFile<ELFT> obj = this->getObj<ELFT>();
ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
+ StringRef sectionStringTable =
+ CHECK(obj.getSectionStringTable(sections), this);
+
const Elf_Shdr *versymSec = nullptr;
const Elf_Shdr *verdefSec = nullptr;
const Elf_Shdr *verneedSec = nullptr;
@@ -1472,6 +1496,13 @@ template <class ELFT> void SharedFile::parse() {
case SHT_GNU_verneed:
verneedSec = &sec;
break;
+ case SHT_PROGBITS: {
+ StringRef name = CHECK(obj.getSectionName(sec, sectionStringTable), this);
+ ArrayRef<char> data =
+ CHECK(obj.template getSectionContentsAsArray<char>(sec), this);
+ parseGNUWarning(name, data, sec.sh_size);
+ break;
+ }
}
}
diff --git a/gnu/llvm/lld/ELF/InputFiles.h b/gnu/llvm/lld/ELF/InputFiles.h
index a310ba551bd..4d64a6551d0 100644
--- a/gnu/llvm/lld/ELF/InputFiles.h
+++ b/gnu/llvm/lld/ELF/InputFiles.h
@@ -37,9 +37,9 @@ class DWARFCache;
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
std::string toString(const elf::InputFile *f);
+void parseGNUWarning(StringRef name, ArrayRef<char> data, size_t size);
+
namespace elf {
-class InputFile;
-class InputSectionBase;
using llvm::object::Archive;
@@ -94,9 +94,11 @@ public:
return symbols;
}
- // Filename of .a which contained this file. If this file was
- // not in an archive file, it is the empty string. We use this
- // string for creating error messages.
+ // Get filename to use for linker script processing.
+ StringRef getNameForScript() const;
+
+ // If not empty, this stores the name of the archive containing this file.
+ // We use this string for creating error messages.
std::string archiveName;
// If this is an architecture-specific file, the following members
@@ -130,6 +132,10 @@ public:
// [.got, .got + 0xFFFC].
bool ppc64SmallCodeModelTocRelocs = false;
+ // True if the file has TLSGD/TLSLD GOT relocations without R_PPC64_TLSGD or
+ // R_PPC64_TLSLD. Disable TLS relaxation to avoid bad code generation.
+ bool ppc64DisableTLSRelax = false;
+
// groupId is used for --warn-backrefs which is an optional error
// checking feature. All files within the same --{start,end}-group or
// --{start,end}-lib get the same group ID. Otherwise, each file gets a new
@@ -149,6 +155,9 @@ protected:
private:
const Kind fileKind;
+
+ // Cache for getNameForScript().
+ mutable std::string nameForScriptCache;
};
class ELFFileBase : public InputFile {
@@ -182,12 +191,7 @@ protected:
// .o file.
template <class ELFT> class ObjFile : public ELFFileBase {
- using Elf_Rel = typename ELFT::Rel;
- using Elf_Rela = typename ELFT::Rela;
- using Elf_Sym = typename ELFT::Sym;
- using Elf_Shdr = typename ELFT::Shdr;
- using Elf_Word = typename ELFT::Word;
- using Elf_CGProfile = typename ELFT::CGProfile;
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
public:
static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
@@ -200,7 +204,7 @@ public:
ArrayRef<Symbol *> getGlobalSymbols();
ObjFile(MemoryBufferRef m, StringRef archiveName) : ELFFileBase(ObjKind, m) {
- this->archiveName = archiveName;
+ this->archiveName = std::string(archiveName);
}
void parse(bool ignoreComdats = false);
@@ -247,14 +251,17 @@ public:
// Pointer to this input file's .llvm_addrsig section, if it has one.
const Elf_Shdr *addrsigSec = nullptr;
- // SHT_LLVM_CALL_GRAPH_PROFILE table
- ArrayRef<Elf_CGProfile> cgProfile;
+ // SHT_LLVM_CALL_GRAPH_PROFILE section index.
+ uint32_t cgProfileSectionIndex = 0;
+
+ // Get cached DWARF information.
+ DWARFCache *getDwarf();
private:
void initializeSections(bool ignoreComdats);
void initializeSymbols();
void initializeJustSymbols();
- void initializeDwarf();
+
InputSectionBase *getRelocTarget(const Elf_Shdr &sec);
InputSectionBase *createInputSection(const Elf_Shdr &sec);
StringRef getSectionName(const Elf_Shdr &sec);
@@ -282,8 +289,8 @@ private:
// reporting. Linker may find reasonable number of errors in a
// single object file, so we cache debugging information in order to
// parse it only once for each object file we link.
- DWARFCache *dwarf;
- llvm::once_flag initDwarfLine;
+ std::unique_ptr<DWARFCache> dwarf;
+ llvm::once_flag initDwarf;
};
// LazyObjFile is analogous to ArchiveFile in the sense that
@@ -298,7 +305,7 @@ public:
LazyObjFile(MemoryBufferRef m, StringRef archiveName,
uint64_t offsetInArchive)
: InputFile(LazyObjKind, m), offsetInArchive(offsetInArchive) {
- this->archiveName = archiveName;
+ this->archiveName = std::string(archiveName);
}
static bool classof(const InputFile *f) { return f->kind() == LazyObjKind; }
@@ -306,6 +313,12 @@ public:
template <class ELFT> void parse();
void fetch();
+ // Check if a non-common symbol should be fetched to override a common
+ // definition.
+ bool shouldFetchForCommon(const StringRef &name);
+
+ bool fetched = false;
+
private:
uint64_t offsetInArchive;
};
@@ -323,6 +336,15 @@ public:
// more than once.)
void fetch(const Archive::Symbol &sym);
+ // Check if a non-common symbol should be fetched to override a common
+ // definition.
+ bool shouldFetchForCommon(const Archive::Symbol &sym);
+
+ size_t getMemberCount() const;
+ size_t getFetchedMemberCount() const { return seen.size(); }
+
+ bool parsed = false;
+
private:
std::unique_ptr<Archive> file;
llvm::DenseSet<uint64_t> seen;
@@ -341,7 +363,7 @@ public:
class SharedFile : public ELFFileBase {
public:
SharedFile(MemoryBufferRef m, StringRef defaultSoName)
- : ELFFileBase(SharedKind, m), soName(defaultSoName),
+ : ELFFileBase(SharedKind, m), soName(std::string(defaultSoName)),
isNeeded(!config->asNeeded) {}
// This is actually a vector of Elf_Verdef pointers.
@@ -361,11 +383,17 @@ public:
template <typename ELFT> void parse();
- // Used for --no-allow-shlib-undefined.
- bool allNeededIsKnown;
-
// Used for --as-needed
bool isNeeded;
+
+ // Non-weak undefined symbols which are not yet resolved when the SO is
+ // parsed. Only filled for `--no-allow-shlib-undefined`.
+ std::vector<Symbol *> requiredSymbols;
+
+private:
+ template <typename ELFT>
+ std::vector<uint32_t> parseVerneed(const llvm::object::ELFFile<ELFT> &obj,
+ const typename ELFT::Shdr *sec);
};
class BinaryFile : public InputFile {
@@ -384,6 +412,7 @@ inline bool isBitcode(MemoryBufferRef mb) {
std::string replaceThinLTOSuffix(StringRef path);
+extern std::vector<ArchiveFile *> archiveFiles;
extern std::vector<BinaryFile *> binaryFiles;
extern std::vector<BitcodeFile *> bitcodeFiles;
extern std::vector<LazyObjFile *> lazyObjFiles;
diff --git a/gnu/llvm/lld/ELF/Relocations.cpp b/gnu/llvm/lld/ELF/Relocations.cpp
index bf576752c54..114780e0f9a 100644
--- a/gnu/llvm/lld/ELF/Relocations.cpp
+++ b/gnu/llvm/lld/ELF/Relocations.cpp
@@ -954,6 +954,18 @@ template <class ELFT> void elf::reportUndefinedSymbols() {
undefs.clear();
}
+static void reportGNUWarning(Symbol &sym, InputSectionBase &sec,
+ uint64_t offset) {
+ if (sym.gwarn) {
+ StringRef gnuWarning = gnuWarnings.lookup(sym.getName());
+ // report first occurance only
+ sym.gwarn = false;
+ if (!gnuWarning.empty())
+ message(sec.getSrcMsg(sym, offset) + "(" + sec.getObjMsg(offset) +
+ "): warning: " + gnuWarning);
+ }
+}
+
// Report an undefined symbol if necessary.
// Returns true if the undefined symbol will produce an error message.
static bool maybeReportUndefined(Symbol &sym, InputSectionBase &sec,
@@ -1327,6 +1339,8 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
if (symIndex != 0 && maybeReportUndefined(sym, sec, rel.r_offset))
return;
+ reportGNUWarning(sym, sec, rel.r_offset);
+
const uint8_t *relocatedAddr = sec.data().begin() + rel.r_offset;
RelExpr expr = target->getRelExpr(type, sym, relocatedAddr);
diff --git a/gnu/llvm/lld/ELF/SymbolTable.cpp b/gnu/llvm/lld/ELF/SymbolTable.cpp
index f7a8a99cf8f..da1684a91ee 100644
--- a/gnu/llvm/lld/ELF/SymbolTable.cpp
+++ b/gnu/llvm/lld/ELF/SymbolTable.cpp
@@ -26,10 +26,10 @@
using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;
+using namespace lld;
+using namespace lld::elf;
-namespace lld {
-namespace elf {
-SymbolTable *symtab;
+SymbolTable *elf::symtab;
void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// Swap symbols as instructed by -wrap.
@@ -40,12 +40,20 @@ void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
idx2 = idx1;
idx1 = idx3;
- // Now renaming is complete. No one refers Real symbol. We could leave
- // Real as-is, but if Real is written to the symbol table, that may
- // contain irrelevant values. So, we copy all values from Sym to Real.
- StringRef s = real->getName();
+ if (real->exportDynamic)
+ sym->exportDynamic = true;
+ if (!real->isUsedInRegularObj && sym->isUndefined())
+ sym->isUsedInRegularObj = false;
+
+ // Now renaming is complete, and no one refers to real. We drop real from
+ // .symtab and .dynsym. If real is undefined, it is important that we don't
+ // leave it in .dynsym, because otherwise it might lead to an undefined symbol
+ // error in a subsequent link. If real is defined, we could emit real as an
+ // alias for sym, but that could degrade the user experience of some tools
+ // that can print out only one symbol for each location: sym is a preferred
+ // name than real, but they might print out real instead.
memcpy(real, sym, sizeof(SymbolUnion));
- real->setName(s);
+ real->isUsedInRegularObj = false;
}
// Find an existing symbol or create a new one.
@@ -82,13 +90,14 @@ Symbol *SymbolTable::insert(StringRef name) {
sym->canInline = true;
sym->referenced = false;
sym->traced = false;
+ sym->gwarn = false;
sym->scriptDefined = false;
sym->partition = 1;
return sym;
}
Symbol *SymbolTable::addSymbol(const Symbol &newSym) {
- Symbol *sym = symtab->insert(newSym.getName());
+ Symbol *sym = insert(newSym.getName());
sym->resolve(newSym);
return sym;
}
@@ -103,6 +112,13 @@ Symbol *SymbolTable::find(StringRef name) {
return sym;
}
+// A version script/dynamic list is only meaningful for a Defined symbol.
+// A CommonSymbol will be converted to a Defined in replaceCommonSymbols().
+// A lazy symbol may be made Defined if an LTO libcall fetches it.
+static bool canBeVersioned(const Symbol &sym) {
+ return sym.isDefined() || sym.isCommon() || sym.isLazy();
+}
+
// Initialize demangledSyms with a map from demangled symbols to symbol
// objects. Used to handle "extern C++" directive in version scripts.
//
@@ -119,11 +135,20 @@ Symbol *SymbolTable::find(StringRef name) {
StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
if (!demangledSyms) {
demangledSyms.emplace();
- for (Symbol *sym : symVector) {
- if (!sym->isDefined() && !sym->isCommon())
- continue;
- (*demangledSyms)[demangleItanium(sym->getName())].push_back(sym);
- }
+ std::string demangled;
+ for (Symbol *sym : symVector)
+ if (canBeVersioned(*sym)) {
+ StringRef name = sym->getName();
+ size_t pos = name.find('@');
+ if (pos == std::string::npos)
+ demangled = demangleItanium(name);
+ else if (pos + 1 == name.size() || name[pos + 1] == '@')
+ demangled = demangleItanium(name.substr(0, pos));
+ else
+ demangled =
+ (demangleItanium(name.substr(0, pos)) + name.substr(pos)).str();
+ (*demangledSyms)[demangled].push_back(sym);
+ }
}
return *demangledSyms;
}
@@ -131,25 +156,35 @@ StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
if (ver.isExternCpp)
return getDemangledSyms().lookup(ver.name);
- if (Symbol *b = find(ver.name))
- if (b->isDefined() || b->isCommon())
- return {b};
+ if (Symbol *sym = find(ver.name))
+ if (canBeVersioned(*sym))
+ return {sym};
return {};
}
-std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver) {
+std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver,
+ bool includeNonDefault) {
std::vector<Symbol *> res;
- StringMatcher m(ver.name);
+ SingleStringMatcher m(ver.name);
+ auto check = [&](StringRef name) {
+ size_t pos = name.find('@');
+ if (!includeNonDefault)
+ return pos == StringRef::npos;
+ return !(pos + 1 < name.size() && name[pos + 1] == '@');
+ };
if (ver.isExternCpp) {
for (auto &p : getDemangledSyms())
if (m.match(p.first()))
- res.insert(res.end(), p.second.begin(), p.second.end());
+ for (Symbol *sym : p.second)
+ if (check(sym->getName()))
+ res.push_back(sym);
return res;
}
for (Symbol *sym : symVector)
- if ((sym->isDefined() || sym->isCommon()) && m.match(sym->getName()))
+ if (canBeVersioned(*sym) && check(sym->getName()) &&
+ m.match(sym->getName()))
res.push_back(sym);
return res;
}
@@ -159,7 +194,7 @@ void SymbolTable::handleDynamicList() {
for (SymbolVersion &ver : config->dynamicList) {
std::vector<Symbol *> syms;
if (ver.hasWildcard)
- syms = findAllByVersion(ver);
+ syms = findAllByVersion(ver, /*includeNonDefault=*/true);
else
syms = findByVersion(ver);
@@ -168,21 +203,13 @@ void SymbolTable::handleDynamicList() {
}
}
-// Set symbol versions to symbols. This function handles patterns
-// containing no wildcard characters.
-void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
- StringRef versionName) {
- if (ver.hasWildcard)
- return;
-
+// Set symbol versions to symbols. This function handles patterns containing no
+// wildcard characters. Return false if no symbol definition matches ver.
+bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
+ StringRef versionName,
+ bool includeNonDefault) {
// Get a list of symbols which we need to assign the version to.
std::vector<Symbol *> syms = findByVersion(ver);
- if (syms.empty()) {
- if (!config->undefinedVersion)
- error("version script assignment of '" + versionName + "' to symbol '" +
- ver.name + "' failed: symbol not defined");
- return;
- }
auto getName = [](uint16_t ver) -> std::string {
if (ver == VER_NDX_LOCAL)
@@ -194,10 +221,11 @@ void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
// Assign the version.
for (Symbol *sym : syms) {
- // Skip symbols containing version info because symbol versions
- // specified by symbol names take precedence over version scripts.
- // See parseSymbolVersion().
- if (sym->getName().contains('@'))
+ // For a non-local versionId, skip symbols containing version info because
+ // symbol versions specified by symbol names take precedence over version
+ // scripts. See parseSymbolVersion().
+ if (!includeNonDefault && versionId != VER_NDX_LOCAL &&
+ sym->getName().contains('@'))
continue;
// If the version has not been assigned, verdefIndex is -1. Use an arbitrary
@@ -212,13 +240,15 @@ void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
warn("attempt to reassign symbol '" + ver.name + "' of " +
getName(sym->versionId) + " to " + getName(versionId));
}
+ return !syms.empty();
}
-void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {
+void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
+ bool includeNonDefault) {
// Exact matching takes precedence over fuzzy matching,
// so we set a version to a symbol only if no version has been assigned
// to the symbol. This behavior is compatible with GNU.
- for (Symbol *sym : findAllByVersion(ver))
+ for (Symbol *sym : findAllByVersion(ver, includeNonDefault))
if (sym->verdefIndex == UINT32_C(-1)) {
sym->verdefIndex = 0;
sym->versionId = versionId;
@@ -231,26 +261,60 @@ void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {
// script file, the script does not actually define any symbol version,
// but just specifies symbols visibilities.
void SymbolTable::scanVersionScript() {
+ SmallString<128> buf;
// First, we assign versions to exact matching symbols,
// i.e. version definitions not containing any glob meta-characters.
- for (VersionDefinition &v : config->versionDefinitions)
- for (SymbolVersion &pat : v.patterns)
- assignExactVersion(pat, v.id, v.name);
+ std::vector<Symbol *> syms;
+ for (VersionDefinition &v : config->versionDefinitions) {
+ auto assignExact = [&](SymbolVersion pat, uint16_t id, StringRef ver) {
+ bool found =
+ assignExactVersion(pat, id, ver, /*includeNonDefault=*/false);
+ buf.clear();
+ found |= assignExactVersion({(pat.name + "@" + v.name).toStringRef(buf),
+ pat.isExternCpp, /*hasWildCard=*/false},
+ id, ver, /*includeNonDefault=*/true);
+ if (!found && !config->undefinedVersion)
+ errorOrWarn("version script assignment of '" + ver + "' to symbol '" +
+ pat.name + "' failed: symbol not defined");
+ };
+ for (SymbolVersion &pat : v.nonLocalPatterns)
+ if (!pat.hasWildcard)
+ assignExact(pat, v.id, v.name);
+ for (SymbolVersion pat : v.localPatterns)
+ if (!pat.hasWildcard)
+ assignExact(pat, VER_NDX_LOCAL, "local");
+ }
// Next, assign versions to wildcards that are not "*". Note that because the
// last match takes precedence over previous matches, we iterate over the
// definitions in the reverse order.
- for (VersionDefinition &v : llvm::reverse(config->versionDefinitions))
- for (SymbolVersion &pat : v.patterns)
+ auto assignWildcard = [&](SymbolVersion pat, uint16_t id, StringRef ver) {
+ assignWildcardVersion(pat, id, /*includeNonDefault=*/false);
+ buf.clear();
+ assignWildcardVersion({(pat.name + "@" + ver).toStringRef(buf),
+ pat.isExternCpp, /*hasWildCard=*/true},
+ id,
+ /*includeNonDefault=*/true);
+ };
+ for (VersionDefinition &v : llvm::reverse(config->versionDefinitions)) {
+ for (SymbolVersion &pat : v.nonLocalPatterns)
+ if (pat.hasWildcard && pat.name != "*")
+ assignWildcard(pat, v.id, v.name);
+ for (SymbolVersion &pat : v.localPatterns)
if (pat.hasWildcard && pat.name != "*")
- assignWildcardVersion(pat, v.id);
+ assignWildcard(pat, VER_NDX_LOCAL, v.name);
+ }
// Then, assign versions to "*". In GNU linkers they have lower priority than
// other wildcards.
- for (VersionDefinition &v : config->versionDefinitions)
- for (SymbolVersion &pat : v.patterns)
+ for (VersionDefinition &v : config->versionDefinitions) {
+ for (SymbolVersion &pat : v.nonLocalPatterns)
if (pat.hasWildcard && pat.name == "*")
- assignWildcardVersion(pat, v.id);
+ assignWildcard(pat, v.id, v.name);
+ for (SymbolVersion &pat : v.localPatterns)
+ if (pat.hasWildcard && pat.name == "*")
+ assignWildcard(pat, VER_NDX_LOCAL, v.name);
+ }
// Symbol themselves might know their versions because symbols
// can contain versions in the form of <name>@<version>.
@@ -264,6 +328,3 @@ void SymbolTable::scanVersionScript() {
// --dynamic-list.
handleDynamicList();
}
-
-} // namespace elf
-} // namespace lld
diff --git a/gnu/llvm/lld/ELF/Symbols.h b/gnu/llvm/lld/ELF/Symbols.h
index d4a589ee600..3a4f851a7d4 100644
--- a/gnu/llvm/lld/ELF/Symbols.h
+++ b/gnu/llvm/lld/ELF/Symbols.h
@@ -142,6 +142,9 @@ public:
// True if this symbol is specified by --trace-symbol option.
uint8_t traced : 1;
+ // True if the .gnu.warning.SYMBOL is set for the symbol
+ uint8_t gwarn : 1;
+
inline void replace(const Symbol &newSym);
bool includeInDynsym() const;
@@ -247,7 +250,7 @@ protected:
type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
- canInline(false), referenced(false), traced(false), needsPltAddr(false),
+ canInline(false), referenced(false), traced(false), gwarn(false), needsPltAddr(false),
isInIplt(false), gotInIgot(false), isPreemptible(false),
used(!config->gcSections), needsTocRestore(false),
scriptDefined(false) {}
@@ -560,6 +563,7 @@ void Symbol::replace(const Symbol &newSym) {
canInline = old.canInline;
referenced = old.referenced;
traced = old.traced;
+ gwarn = old.gwarn;
isPreemptible = old.isPreemptible;
scriptDefined = old.scriptDefined;
partition = old.partition;
@@ -579,6 +583,8 @@ void maybeWarnUnorderableSymbol(const Symbol *sym);
bool computeIsPreemptible(const Symbol &sym);
void reportBackrefs();
+extern llvm::DenseMap<StringRef, StringRef> gnuWarnings;
+
// A mapping from a symbol to an InputFile referencing it backward. Used by
// --warn-backrefs.
extern llvm::DenseMap<const Symbol *,