forked from OSchip/llvm-project
Teach Undefined symbols from which file they are created from.
This patch increases the size of Undefined by the size of a pointer, but it wouldn't actually increase the size of memory that LLD uses because we are not allocating the exact size but the size of the largest SymbolBody. llvm-svn: 268310
This commit is contained in:
parent
0a99485341
commit
6d0cd2b62b
|
@ -166,7 +166,6 @@ template <class ELFT> void SymbolTable<ELFT>::wrap(StringRef Name) {
|
|||
|
||||
// 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.
|
||||
|
@ -177,21 +176,8 @@ template <class ELFT> InputFile *SymbolTable<ELFT>::findFile(SymbolBody *B) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -253,8 +239,8 @@ template <typename ELFT>
|
|||
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) {
|
||||
|
@ -274,6 +260,7 @@ Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, uint8_t Binding,
|
|||
if (WasInserted) {
|
||||
S->Binding = Binding;
|
||||
replaceBody<Undefined>(S, Name, StOther, Type);
|
||||
cast<Undefined>(S->body())->File = File;
|
||||
return S;
|
||||
}
|
||||
if (Binding != STB_WEAK &&
|
||||
|
|
|
@ -129,6 +129,18 @@ bool SymbolBody::isPreemptible() const {
|
|||
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);
|
||||
|
@ -258,6 +270,11 @@ bool Symbol::includeInDynsym() const {
|
|||
(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;
|
||||
|
|
|
@ -108,6 +108,10 @@ public:
|
|||
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);
|
||||
|
||||
|
@ -259,6 +263,10 @@ public:
|
|||
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 {
|
||||
|
|
|
@ -11,4 +11,4 @@ define void @_start() {
|
|||
ret void
|
||||
}
|
||||
|
||||
; CHECK: undefined symbol: foo in LLD-INTERNAL-combined-lto-object
|
||||
; CHECK: undefined symbol: foo in {{.*}}combined-lto-object-name.ll.tmp.o
|
||||
|
|
Loading…
Reference in New Issue