From 434b56179ea65655fa802eb3dab1b0eb8002e372 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 17 Jul 2016 03:11:46 +0000 Subject: [PATCH] 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(), 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 --- lld/ELF/InputFiles.cpp | 2 +- lld/ELF/LTO.cpp | 5 ++-- lld/ELF/OutputSections.cpp | 4 +-- lld/ELF/Relocations.cpp | 6 ++--- lld/ELF/SymbolTable.cpp | 17 ++++++------- lld/ELF/Symbols.cpp | 62 ++++++++++++++++++++++++---------------------- lld/ELF/Symbols.h | 48 +++++++++++++++++------------------ lld/ELF/Writer.cpp | 6 ++--- 8 files changed, 76 insertions(+), 74 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 6055d08..dbc004c 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -352,7 +352,7 @@ SymbolBody *elf::ObjectFile::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(*Sym, Sec); } diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 0a2e636..0e8006a 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -147,7 +147,8 @@ BitcodeCompiler::BitcodeCompiler() : Combined(new Module("ld-temp.o", Driver->Context)) {} static void undefine(Symbol *S) { - replaceBody(S, S->body()->getName(), STV_DEFAULT, S->body()->Type); + replaceBody(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(S->body()); - if (!B || B->File != &F) + if (!B || B->file() != &F) continue; // We collect the set of symbols we want to internalize here diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 6fa0183..50b9401 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1570,7 +1570,7 @@ void VersionNeedSection::addSymbol(SharedSymbol *SS) { SS->symbol()->VersionId = VER_NDX_GLOBAL; return; } - SharedFile *F = SS->File; + SharedFile *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::addSymbol(SharedSymbol *SS) { // dynstr entry for the version name. if (NV.Index == 0) { NV.StrTab = Out::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; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index e39eef7..c09cf6b 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -359,7 +359,7 @@ static RelExpr fromPlt(RelExpr Expr) { template static uint32_t getAlignment(SharedSymbol *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 static void addCopyRelSymbol(SharedSymbol *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>( - Symtab::X->find(check(S.getName(SS->File->getStringTable())))); + Symtab::X->find(check(S.getName(SS->file()->getStringTable())))); if (!Alias) continue; Alias->OffsetInBss = Off; diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 5ebfe8a..4fb2b87 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -253,7 +253,7 @@ std::string SymbolTable::conflictMsg(SymbolBody *Existing, std::string Sym = Existing->getName(); if (Config->Demangle) Sym = demangle(Sym); - return Sym + " in " + getFilename(Existing->getSourceFile()) + " and " + + return Sym + " in " + getFilename(Existing->File) + " and " + getFilename(NewFile); } @@ -274,22 +274,21 @@ Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding, /*IsUsedInRegularObj*/ !File || !isa(File), File); if (WasInserted) { S->Binding = Binding; - replaceBody(S, Name, StOther, Type); - cast(S->body())->File = File; + replaceBody(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>(S->body())) - SS->File->IsUsed = true; + SS->file()->IsUsed = true; } if (auto *L = dyn_cast(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::addLazyObject(StringRef Name, LazyObjectFile &Obj) { template void SymbolTable::scanUndefinedFlags() { for (StringRef S : Config->Undefined) if (auto *L = dyn_cast_or_null(find(S))) - if (std::unique_ptr File = L->getFile()) + if (std::unique_ptr File = L->fetch()) addFile(std::move(File)); } @@ -653,9 +652,9 @@ template void SymbolTable::traceDefined() { for (const auto &Symbol : Config->TraceSymbol) if (SymbolBody *B = find(Symbol.getKey())) if (B->isDefined() || B->isCommon()) - if (InputFile *File = B->getSourceFile()) - outs() << getFilename(File) << ": definition of " - << B->getName() << "\n"; + if (B->File) + outs() << getFilename(B->File) << ": definition of " << B->getName() + << "\n"; } template class elf::SymbolTable; diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 0c3a116..7c9c748 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -142,18 +142,6 @@ template bool SymbolBody::hasThunk() const { return false; } -template InputFile *SymbolBody::getSourceFile() { - if (auto *S = dyn_cast>(this)) - return S->Section ? S->Section->getFile() : nullptr; - if (auto *S = dyn_cast>(this)) - return S->File; - if (auto *S = dyn_cast(this)) - return S->File; - if (auto *S = dyn_cast(this)) - return S->File; - return nullptr; -} - template typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const { typename ELFT::uint OutVA = getSymVA(*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 DefinedSynthetic::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 Lazy::getFile() { +std::unique_ptr Lazy::fetch() { if (auto *S = dyn_cast(this)) - return S->getFile(); - return cast(this)->getFile(); + return S->fetch(); + return cast(this)->fetch(); } -std::unique_ptr 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 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(nullptr); - return createObjectFile(MBRef, File.getName()); + return createObjectFile(MBRef, file()->getName()); } -std::unique_ptr LazyObject::getFile() { - MemoryBufferRef MBRef = File.getBuffer(); +std::unique_ptr LazyObject::fetch() { + MemoryBufferRef MBRef = file()->getBuffer(); if (MBRef.getBuffer().empty()) return std::unique_ptr(nullptr); return createObjectFile(MBRef); @@ -264,11 +271,6 @@ template bool SymbolBody::hasThunk() const; template bool SymbolBody::hasThunk() const; template bool SymbolBody::hasThunk() const; -template InputFile *SymbolBody::template getSourceFile(); -template InputFile *SymbolBody::template getSourceFile(); -template InputFile *SymbolBody::template getSourceFile(); -template InputFile *SymbolBody::template getSourceFile(); - template uint32_t SymbolBody::template getVA(uint32_t) const; template uint32_t SymbolBody::template getVA(uint32_t) const; template uint64_t SymbolBody::template getVA(uint64_t) const; diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index bab4282..f4b810d 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -99,9 +99,8 @@ public: template typename ELFT::uint getThunkVA() const; template typename ELFT::uint getSize() const; - // Returns the file from which the symbol was created. - // For logging purpose only. - template 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 *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 SharedSymbol : public Defined { @@ -288,13 +289,16 @@ public: SharedSymbol(SharedFile *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 *File; + SharedFile *file() { return (SharedFile *)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 getFile(); + std::unique_ptr 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 getFile(); + ArchiveFile *file() { return (ArchiveFile *)this->File; } + std::unique_ptr 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 getFile(); - -private: - LazyObjectFile &File; + LazyObjectFile *file() { return (LazyObjectFile *)this->File; } + std::unique_ptr fetch(); }; // Some linker-generated symbols need to be created as diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 455a136..387bec3 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -275,8 +275,8 @@ static void reportUndefined(SymbolTable &Symtab, SymbolBody *Sym) { return; std::string Msg = "undefined symbol: " + Sym->getName().str(); - if (InputFile *File = Sym->getSourceFile()) - 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 void Writer::createSections() { if (isOutputDynamic() && S->includeInDynsym()) { Out::DynSymTab->addSymbol(Body); if (auto *SS = dyn_cast>(Body)) - if (SS->File->isNeeded()) + if (SS->file()->isNeeded()) Out::VerNeed->addSymbol(SS); } } -- 2.7.4