forked from OSchip/llvm-project
Add a pointer to a source file to SymbolBody.
Previously, each subclass of SymbolBody had a pointer to a source file from which it was created. So, there was no single way to get a source file for a symbol. We had getSourceFile<ELFT>(), but the function was a bit inconvenient as it's a template. This patch makes SymbolBody have a pointer to a source file. If a symbol is not created from a file, the pointer has a nullptr. llvm-svn: 275701
This commit is contained in:
parent
7a7a96e199
commit
434b56179e
|
@ -352,7 +352,7 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
|
|||
if (Binding == STB_LOCAL) {
|
||||
if (Sym->st_shndx == SHN_UNDEF)
|
||||
return new (this->Alloc)
|
||||
Undefined(Sym->st_name, Sym->st_other, Sym->getType());
|
||||
Undefined(Sym->st_name, Sym->st_other, Sym->getType(), this);
|
||||
return new (this->Alloc) DefinedRegular<ELFT>(*Sym, Sec);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,8 @@ BitcodeCompiler::BitcodeCompiler()
|
|||
: Combined(new Module("ld-temp.o", Driver->Context)) {}
|
||||
|
||||
static void undefine(Symbol *S) {
|
||||
replaceBody<Undefined>(S, S->body()->getName(), STV_DEFAULT, S->body()->Type);
|
||||
replaceBody<Undefined>(S, S->body()->getName(), STV_DEFAULT, S->body()->Type,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
static void handleUndefinedAsmRefs(const BasicSymbolRef &Sym, GlobalValue *GV,
|
||||
|
@ -198,7 +199,7 @@ void BitcodeCompiler::add(BitcodeFile &F) {
|
|||
continue;
|
||||
}
|
||||
auto *B = dyn_cast<DefinedBitcode>(S->body());
|
||||
if (!B || B->File != &F)
|
||||
if (!B || B->file() != &F)
|
||||
continue;
|
||||
|
||||
// We collect the set of symbols we want to internalize here
|
||||
|
|
|
@ -1570,7 +1570,7 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol<ELFT> *SS) {
|
|||
SS->symbol()->VersionId = VER_NDX_GLOBAL;
|
||||
return;
|
||||
}
|
||||
SharedFile<ELFT> *F = SS->File;
|
||||
SharedFile<ELFT> *F = SS->file();
|
||||
// If we don't already know that we need an Elf_Verneed for this DSO, prepare
|
||||
// to create one by adding it to our needed list and creating a dynstr entry
|
||||
// for the soname.
|
||||
|
@ -1582,7 +1582,7 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol<ELFT> *SS) {
|
|||
// dynstr entry for the version name.
|
||||
if (NV.Index == 0) {
|
||||
NV.StrTab = Out<ELFT>::DynStrTab->addString(
|
||||
SS->File->getStringTable().data() + SS->Verdef->getAux()->vda_name);
|
||||
SS->file()->getStringTable().data() + SS->Verdef->getAux()->vda_name);
|
||||
NV.Index = NextIndex++;
|
||||
}
|
||||
SS->symbol()->VersionId = NV.Index;
|
||||
|
|
|
@ -359,7 +359,7 @@ static RelExpr fromPlt(RelExpr Expr) {
|
|||
template <class ELFT> static uint32_t getAlignment(SharedSymbol<ELFT> *SS) {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
uintX_t SecAlign = SS->File->getSection(SS->Sym)->sh_addralign;
|
||||
uintX_t SecAlign = SS->file()->getSection(SS->Sym)->sh_addralign;
|
||||
uintX_t SymValue = SS->Sym.st_value;
|
||||
int TrailingZeros =
|
||||
std::min(countTrailingZeros(SecAlign), countTrailingZeros(SymValue));
|
||||
|
@ -385,11 +385,11 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) {
|
|||
// Look through the DSO's dynamic symbol table for aliases and create a
|
||||
// dynamic symbol for each one. This causes the copy relocation to correctly
|
||||
// interpose any aliases.
|
||||
for (const Elf_Sym &S : SS->File->getElfSymbols(true)) {
|
||||
for (const Elf_Sym &S : SS->file()->getElfSymbols(true)) {
|
||||
if (S.st_shndx != Shndx || S.st_value != Value)
|
||||
continue;
|
||||
auto *Alias = dyn_cast_or_null<SharedSymbol<ELFT>>(
|
||||
Symtab<ELFT>::X->find(check(S.getName(SS->File->getStringTable()))));
|
||||
Symtab<ELFT>::X->find(check(S.getName(SS->file()->getStringTable()))));
|
||||
if (!Alias)
|
||||
continue;
|
||||
Alias->OffsetInBss = Off;
|
||||
|
|
|
@ -253,7 +253,7 @@ std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Existing,
|
|||
std::string Sym = Existing->getName();
|
||||
if (Config->Demangle)
|
||||
Sym = demangle(Sym);
|
||||
return Sym + " in " + getFilename(Existing->getSourceFile<ELFT>()) + " and " +
|
||||
return Sym + " in " + getFilename(Existing->File) + " and " +
|
||||
getFilename(NewFile);
|
||||
}
|
||||
|
||||
|
@ -274,22 +274,21 @@ Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, uint8_t Binding,
|
|||
/*IsUsedInRegularObj*/ !File || !isa<BitcodeFile>(File), File);
|
||||
if (WasInserted) {
|
||||
S->Binding = Binding;
|
||||
replaceBody<Undefined>(S, Name, StOther, Type);
|
||||
cast<Undefined>(S->body())->File = File;
|
||||
replaceBody<Undefined>(S, Name, StOther, Type, File);
|
||||
return S;
|
||||
}
|
||||
if (Binding != STB_WEAK) {
|
||||
if (S->body()->isShared() || S->body()->isLazy())
|
||||
S->Binding = Binding;
|
||||
if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(S->body()))
|
||||
SS->File->IsUsed = true;
|
||||
SS->file()->IsUsed = true;
|
||||
}
|
||||
if (auto *L = dyn_cast<Lazy>(S->body())) {
|
||||
// An undefined weak will not fetch archive members, but we have to remember
|
||||
// its type. See also comment in addLazyArchive.
|
||||
if (S->isWeak())
|
||||
L->Type = Type;
|
||||
else if (auto F = L->getFile())
|
||||
else if (auto F = L->fetch())
|
||||
addFile(std::move(F));
|
||||
}
|
||||
return S;
|
||||
|
@ -535,7 +534,7 @@ void SymbolTable<ELFT>::addLazyObject(StringRef Name, LazyObjectFile &Obj) {
|
|||
template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() {
|
||||
for (StringRef S : Config->Undefined)
|
||||
if (auto *L = dyn_cast_or_null<Lazy>(find(S)))
|
||||
if (std::unique_ptr<InputFile> File = L->getFile())
|
||||
if (std::unique_ptr<InputFile> File = L->fetch())
|
||||
addFile(std::move(File));
|
||||
}
|
||||
|
||||
|
@ -653,9 +652,9 @@ template <class ELFT> void SymbolTable<ELFT>::traceDefined() {
|
|||
for (const auto &Symbol : Config->TraceSymbol)
|
||||
if (SymbolBody *B = find(Symbol.getKey()))
|
||||
if (B->isDefined() || B->isCommon())
|
||||
if (InputFile *File = B->getSourceFile<ELFT>())
|
||||
outs() << getFilename(File) << ": definition of "
|
||||
<< B->getName() << "\n";
|
||||
if (B->File)
|
||||
outs() << getFilename(B->File) << ": definition of " << B->getName()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
template class elf::SymbolTable<ELF32LE>;
|
||||
|
|
|
@ -142,18 +142,6 @@ template <class ELFT> bool SymbolBody::hasThunk() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -207,17 +195,25 @@ Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type)
|
|||
|
||||
DefinedBitcode::DefinedBitcode(StringRef Name, uint8_t StOther, uint8_t Type,
|
||||
BitcodeFile *F)
|
||||
: Defined(DefinedBitcodeKind, Name, StOther, Type), File(F) {}
|
||||
: Defined(DefinedBitcodeKind, Name, StOther, Type) {
|
||||
this->File = F;
|
||||
}
|
||||
|
||||
bool DefinedBitcode::classof(const SymbolBody *S) {
|
||||
return S->kind() == DefinedBitcodeKind;
|
||||
}
|
||||
|
||||
Undefined::Undefined(StringRef Name, uint8_t StOther, uint8_t Type)
|
||||
: SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) {}
|
||||
Undefined::Undefined(StringRef Name, uint8_t StOther, uint8_t Type,
|
||||
InputFile *File)
|
||||
: SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) {
|
||||
this->File = File;
|
||||
}
|
||||
|
||||
Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type)
|
||||
: SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type) {}
|
||||
Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type,
|
||||
InputFile *File)
|
||||
: SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type) {
|
||||
this->File = File;
|
||||
}
|
||||
|
||||
template <typename ELFT>
|
||||
DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
|
||||
|
@ -230,24 +226,35 @@ DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
|
|||
: Defined(SymbolBody::DefinedCommonKind, N, StOther, Type),
|
||||
Alignment(Alignment), Size(Size) {}
|
||||
|
||||
std::unique_ptr<InputFile> Lazy::getFile() {
|
||||
std::unique_ptr<InputFile> Lazy::fetch() {
|
||||
if (auto *S = dyn_cast<LazyArchive>(this))
|
||||
return S->getFile();
|
||||
return cast<LazyObject>(this)->getFile();
|
||||
return S->fetch();
|
||||
return cast<LazyObject>(this)->fetch();
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> LazyArchive::getFile() {
|
||||
MemoryBufferRef MBRef = File.getMember(&Sym);
|
||||
LazyArchive::LazyArchive(ArchiveFile &File,
|
||||
const llvm::object::Archive::Symbol S, uint8_t Type)
|
||||
: Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {
|
||||
this->File = &File;
|
||||
}
|
||||
|
||||
LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
|
||||
: Lazy(LazyObjectKind, Name, Type) {
|
||||
this->File = &File;
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> LazyArchive::fetch() {
|
||||
MemoryBufferRef MBRef = file()->getMember(&Sym);
|
||||
|
||||
// getMember returns an empty buffer if the member was already
|
||||
// read from the library.
|
||||
if (MBRef.getBuffer().empty())
|
||||
return std::unique_ptr<InputFile>(nullptr);
|
||||
return createObjectFile(MBRef, File.getName());
|
||||
return createObjectFile(MBRef, file()->getName());
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> LazyObject::getFile() {
|
||||
MemoryBufferRef MBRef = File.getBuffer();
|
||||
std::unique_ptr<InputFile> LazyObject::fetch() {
|
||||
MemoryBufferRef MBRef = file()->getBuffer();
|
||||
if (MBRef.getBuffer().empty())
|
||||
return std::unique_ptr<InputFile>(nullptr);
|
||||
return createObjectFile(MBRef);
|
||||
|
@ -264,11 +271,6 @@ template bool SymbolBody::hasThunk<ELF32BE>() const;
|
|||
template bool SymbolBody::hasThunk<ELF64LE>() const;
|
||||
template bool SymbolBody::hasThunk<ELF64BE>() const;
|
||||
|
||||
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;
|
||||
|
|
|
@ -99,9 +99,8 @@ 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();
|
||||
// The file from which this symbol was created.
|
||||
InputFile *File = nullptr;
|
||||
|
||||
protected:
|
||||
SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type);
|
||||
|
@ -163,8 +162,7 @@ class DefinedBitcode : public Defined {
|
|||
public:
|
||||
DefinedBitcode(StringRef Name, uint8_t StOther, uint8_t Type, BitcodeFile *F);
|
||||
static bool classof(const SymbolBody *S);
|
||||
|
||||
BitcodeFile *File;
|
||||
BitcodeFile *file() { return (BitcodeFile *)this->File; }
|
||||
};
|
||||
|
||||
class DefinedCommon : public Defined {
|
||||
|
@ -197,7 +195,10 @@ public:
|
|||
: Defined(SymbolBody::DefinedRegularKind, Name, Sym.st_other,
|
||||
Sym.getType()),
|
||||
Value(Sym.st_value), Size(Sym.st_size),
|
||||
Section(Section ? Section->Repl : NullInputSection) {}
|
||||
Section(Section ? Section->Repl : NullInputSection) {
|
||||
if (Section)
|
||||
this->File = Section->getFile();
|
||||
}
|
||||
|
||||
DefinedRegular(const Elf_Sym &Sym, InputSectionBase<ELFT> *Section)
|
||||
: Defined(SymbolBody::DefinedRegularKind, Sym.st_name, Sym.st_other,
|
||||
|
@ -205,6 +206,8 @@ public:
|
|||
Value(Sym.st_value), Size(Sym.st_size),
|
||||
Section(Section ? Section->Repl : NullInputSection) {
|
||||
assert(isLocal());
|
||||
if (Section)
|
||||
this->File = Section->getFile();
|
||||
}
|
||||
|
||||
DefinedRegular(StringRef Name, uint8_t StOther)
|
||||
|
@ -263,16 +266,14 @@ public:
|
|||
|
||||
class Undefined : public SymbolBody {
|
||||
public:
|
||||
Undefined(StringRef Name, uint8_t StOther, uint8_t Type);
|
||||
Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type);
|
||||
Undefined(StringRef Name, uint8_t StOther, uint8_t Type, InputFile *F);
|
||||
Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type, InputFile *F);
|
||||
|
||||
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;
|
||||
InputFile *file() { return this->File; }
|
||||
};
|
||||
|
||||
template <class ELFT> class SharedSymbol : public Defined {
|
||||
|
@ -288,13 +289,16 @@ public:
|
|||
SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
|
||||
const Elf_Verdef *Verdef)
|
||||
: Defined(SymbolBody::SharedKind, Name, Sym.st_other, Sym.getType()),
|
||||
File(F), Sym(Sym), Verdef(Verdef) {
|
||||
Sym(Sym), Verdef(Verdef) {
|
||||
// IFuncs defined in DSOs are treated as functions by the static linker.
|
||||
if (isGnuIFunc())
|
||||
Type = llvm::ELF::STT_FUNC;
|
||||
this->File = F;
|
||||
}
|
||||
|
||||
SharedFile<ELFT> *File;
|
||||
SharedFile<ELFT> *file() { return (SharedFile<ELFT> *)this->File; }
|
||||
|
||||
public:
|
||||
const Elf_Sym &Sym;
|
||||
|
||||
// This field is a pointer to the symbol's version definition.
|
||||
|
@ -323,24 +327,23 @@ public:
|
|||
|
||||
// Returns an object file for this symbol, or a nullptr if the file
|
||||
// was already returned.
|
||||
std::unique_ptr<InputFile> getFile();
|
||||
std::unique_ptr<InputFile> fetch();
|
||||
};
|
||||
|
||||
// LazyArchive symbols represents symbols in archive files.
|
||||
class LazyArchive : public Lazy {
|
||||
public:
|
||||
LazyArchive(ArchiveFile &File, const llvm::object::Archive::Symbol S,
|
||||
uint8_t Type)
|
||||
: Lazy(LazyArchiveKind, S.getName(), Type), File(File), Sym(S) {}
|
||||
uint8_t Type);
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == LazyArchiveKind;
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> getFile();
|
||||
ArchiveFile *file() { return (ArchiveFile *)this->File; }
|
||||
std::unique_ptr<InputFile> fetch();
|
||||
|
||||
private:
|
||||
ArchiveFile &File;
|
||||
const llvm::object::Archive::Symbol Sym;
|
||||
};
|
||||
|
||||
|
@ -348,17 +351,14 @@ private:
|
|||
// --start-lib and --end-lib options.
|
||||
class LazyObject : public Lazy {
|
||||
public:
|
||||
LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
|
||||
: Lazy(LazyObjectKind, Name, Type), File(File) {}
|
||||
LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type);
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == LazyObjectKind;
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> getFile();
|
||||
|
||||
private:
|
||||
LazyObjectFile &File;
|
||||
LazyObjectFile *file() { return (LazyObjectFile *)this->File; }
|
||||
std::unique_ptr<InputFile> fetch();
|
||||
};
|
||||
|
||||
// Some linker-generated symbols need to be created as
|
||||
|
|
|
@ -275,8 +275,8 @@ static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
|
|||
return;
|
||||
|
||||
std::string Msg = "undefined symbol: " + Sym->getName().str();
|
||||
if (InputFile *File = Sym->getSourceFile<ELFT>())
|
||||
Msg += " in " + getFilename(File);
|
||||
if (Sym->File)
|
||||
Msg += " in " + getFilename(Sym->File);
|
||||
if (Config->UnresolvedSymbols == UnresolvedPolicy::Warn)
|
||||
warning(Msg);
|
||||
else
|
||||
|
@ -715,7 +715,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
|||
if (isOutputDynamic() && S->includeInDynsym()) {
|
||||
Out<ELFT>::DynSymTab->addSymbol(Body);
|
||||
if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
|
||||
if (SS->File->isNeeded())
|
||||
if (SS->file()->isNeeded())
|
||||
Out<ELFT>::VerNeed->addSymbol(SS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue