// Returns a file from which symbol B was created.
// If B does not belong to any file, returns a nullptr.
-// This function is slow, but it's okay as it is used only for error messages.
template <class ELFT> InputFile *SymbolTable<ELFT>::findFile(SymbolBody *B) {
// If this symbol has a definition, follow pointers in the symbol to its
// defining file.
return SS->File;
if (auto *BC = dyn_cast<DefinedBitcode>(B))
return BC->File;
- // If not, we might be able to find it by searching symbol tables of files.
- // This code is generally only used for undefined symbols. Note that we can't
- // rely exclusively on a file search because we may find what was originally
- // an undefined symbol that was later replaced with a defined symbol, and we
- // want to return the file that defined the symbol.
- for (const std::unique_ptr<ObjectFile<ELFT>> &F : ObjectFiles) {
- ArrayRef<SymbolBody *> Syms = F->getSymbols();
- if (std::find(Syms.begin(), Syms.end(), B) != Syms.end())
- return F.get();
- }
- for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles) {
- ArrayRef<Symbol *> Syms = F->getSymbols();
- if (std::find(Syms.begin(), Syms.end(), B->symbol()) != Syms.end())
- return F.get();
- }
+ if (auto *U = dyn_cast<Undefined>(B))
+ return U->File;
return nullptr;
}
std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Existing,
InputFile *NewFile) {
StringRef Sym = Existing->getName();
- return demangle(Sym) + " in " + getFilename(findFile(Existing)) + " and " +
- getFilename(NewFile);
+ return demangle(Sym) + " in " + getFilename(Existing->getSourceFile<ELFT>()) +
+ " and " + getFilename(NewFile);
}
template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) {
if (WasInserted) {
S->Binding = Binding;
replaceBody<Undefined>(S, Name, StOther, Type);
+ cast<Undefined>(S->body())->File = File;
return S;
}
if (Binding != STB_WEAK &&
return symbol()->Visibility == STV_DEFAULT;
}
+template <class ELFT> InputFile *SymbolBody::getSourceFile() {
+ if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))
+ return S->Section ? S->Section->getFile() : nullptr;
+ if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
+ return S->File;
+ if (auto *S = dyn_cast<DefinedBitcode>(this))
+ return S->File;
+ if (auto *S = dyn_cast<Undefined>(this))
+ return S->File;
+ return nullptr;
+}
+
template <class ELFT>
typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
(body()->isUndefined() && Config->Shared);
}
+template InputFile *SymbolBody::template getSourceFile<ELF32LE>();
+template InputFile *SymbolBody::template getSourceFile<ELF32BE>();
+template InputFile *SymbolBody::template getSourceFile<ELF64LE>();
+template InputFile *SymbolBody::template getSourceFile<ELF64BE>();
+
template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
template <class ELFT> typename ELFT::uint getThunkVA() const;
template <class ELFT> typename ELFT::uint getSize() const;
+ // Returns the file from which the symbol was created.
+ // For logging purpose only.
+ template <class ELFT> InputFile *getSourceFile();
+
protected:
SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type);
static bool classof(const SymbolBody *S) {
return S->kind() == UndefinedKind;
}
+
+ // The file this undefined symbol was created from.
+ // For logging purpose only.
+ InputFile *File = nullptr;
};
template <class ELFT> class SharedSymbol : public Defined {