[lld] r357925 - ELF: De-template SharedFile. NFCI.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 8 10:35:55 PDT 2019
Author: pcc
Date: Mon Apr 8 10:35:55 2019
New Revision: 357925
URL: http://llvm.org/viewvc/llvm-project?rev=357925&view=rev
Log:
ELF: De-template SharedFile. NFCI.
Differential Revision: https://reviews.llvm.org/D60305
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputFiles.h
lld/trunk/ELF/MarkLive.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Apr 8 10:35:55 2019
@@ -1289,10 +1289,10 @@ template <class ELFT> static void handle
// to DT_NEEDED. If that happens, we need to eliminate shared symbols
// created from the DSO. Otherwise, they become dangling references
// that point to a non-existent DSO.
-template <class ELFT> static void demoteSharedSymbols() {
+static void demoteSharedSymbols() {
for (Symbol *Sym : Symtab->getSymbols()) {
if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
- if (!S->getFile<ELFT>().IsNeeded) {
+ if (!S->getFile().IsNeeded) {
bool Used = S->Used;
replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
S->Type);
@@ -1644,7 +1644,7 @@ template <class ELFT> void LinkerDriver:
// and identical code folding.
splitSections<ELFT>();
markLive<ELFT>();
- demoteSharedSymbols<ELFT>();
+ demoteSharedSymbols();
mergeSections();
if (Config->ICF != ICFLevel::None) {
findKeepUniqueSections<ELFT>(Args);
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon Apr 8 10:35:55 2019
@@ -43,7 +43,7 @@ std::vector<BinaryFile *> elf::BinaryFil
std::vector<BitcodeFile *> elf::BitcodeFiles;
std::vector<LazyObjFile *> elf::LazyObjFiles;
std::vector<InputFile *> elf::ObjectFiles;
-std::vector<InputFile *> elf::SharedFiles;
+std::vector<SharedFile *> elf::SharedFiles;
std::unique_ptr<TarWriter> elf::Tar;
@@ -869,20 +869,83 @@ InputFile *ArchiveFile::fetch(const Arch
return File;
}
-template <class ELFT>
-SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
+SharedFile::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
: ELFFileBase(SharedKind, M), SoName(DefaultSoName),
- IsNeeded(!Config->AsNeeded) {
- parseHeader<ELFT>();
+ IsNeeded(!Config->AsNeeded) {}
+
+// Parse the version definitions in the object file if present, and return a
+// vector whose nth element contains a pointer to the Elf_Verdef for version
+// identifier n. Version identifiers that are not definitions map to nullptr.
+template <typename ELFT>
+static std::vector<const void *> parseVerdefs(const uint8_t *Base,
+ const typename ELFT::Shdr *Sec) {
+ if (!Sec)
+ return {};
+
+ // We cannot determine the largest verdef identifier without inspecting
+ // every Elf_Verdef, but both bfd and gold assign verdef identifiers
+ // sequentially starting from 1, so we predict that the largest identifier
+ // will be VerdefCount.
+ unsigned VerdefCount = Sec->sh_info;
+ std::vector<const void *> Verdefs(VerdefCount + 1);
+
+ // Build the Verdefs array by following the chain of Elf_Verdef objects
+ // from the start of the .gnu.version_d section.
+ const uint8_t *Verdef = Base + Sec->sh_offset;
+ for (unsigned I = 0; I != VerdefCount; ++I) {
+ auto *CurVerdef = reinterpret_cast<const typename ELFT::Verdef *>(Verdef);
+ Verdef += CurVerdef->vd_next;
+ unsigned VerdefIndex = CurVerdef->vd_ndx;
+ Verdefs.resize(VerdefIndex + 1);
+ Verdefs[VerdefIndex] = CurVerdef;
+ }
+ return Verdefs;
}
-// Partially parse the shared object file so that we can call
-// getSoName on this object.
-template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
+// We do not usually care about alignments of data in shared object
+// files because the loader takes care of it. However, if we promote a
+// DSO symbol to point to .bss due to copy relocation, we need to keep
+// the original alignment requirements. We infer it in this function.
+template <typename ELFT>
+static uint64_t getAlignment(ArrayRef<typename ELFT::Shdr> Sections,
+ const typename ELFT::Sym &Sym) {
+ uint64_t Ret = UINT64_MAX;
+ if (Sym.st_value)
+ Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
+ if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
+ Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
+ return (Ret > UINT32_MAX) ? 0 : Ret;
+}
+
+// Fully parse the shared object file.
+//
+// This function parses symbol versions. If a DSO has version information,
+// the file has a ".gnu.version_d" section which contains symbol version
+// definitions. Each symbol is associated to one version through a table in
+// ".gnu.version" section. That table is a parallel array for the symbol
+// table, and each table entry contains an index in ".gnu.version_d".
+//
+// The special index 0 is reserved for VERF_NDX_LOCAL and 1 is for
+// VER_NDX_GLOBAL. There's no table entry for these special versions in
+// ".gnu.version_d".
+//
+// The file format for symbol versioning is perhaps a bit more complicated
+// than necessary, but you can easily understand the code if you wrap your
+// head around the data structure described above.
+template <class ELFT> void SharedFile::parse() {
+ using Elf_Dyn = typename ELFT::Dyn;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Sym = typename ELFT::Sym;
+ using Elf_Verdef = typename ELFT::Verdef;
+ using Elf_Versym = typename ELFT::Versym;
+
ArrayRef<Elf_Dyn> DynamicTags;
const ELFFile<ELFT> Obj = this->getObj<ELFT>();
ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
+ const Elf_Shdr *VersymSec = nullptr;
+ const Elf_Shdr *VerdefSec = nullptr;
+
// Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
for (const Elf_Shdr &Sec : Sections) {
switch (Sec.sh_type) {
@@ -896,16 +959,18 @@ template <class ELFT> void SharedFile<EL
CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(&Sec), this);
break;
case SHT_GNU_versym:
- this->VersymSec = &Sec;
+ VersymSec = &Sec;
break;
case SHT_GNU_verdef:
- this->VerdefSec = &Sec;
+ VerdefSec = &Sec;
break;
}
}
- if (this->VersymSec && this->getELFSyms<ELFT>().empty())
+ if (VersymSec && this->getELFSyms<ELFT>().empty()) {
error("SHT_GNU_versym should be associated with symbol table");
+ return;
+ }
// Search for a DT_SONAME tag to initialize this->SoName.
for (const Elf_Dyn &Dyn : DynamicTags) {
@@ -921,91 +986,38 @@ template <class ELFT> void SharedFile<EL
SoName = this->StringTable.data() + Val;
}
}
-}
-// Parses ".gnu.version" section which is a parallel array for the symbol table.
-// If a given file doesn't have ".gnu.version" section, returns VER_NDX_GLOBAL.
-template <class ELFT> std::vector<uint32_t> SharedFile<ELFT>::parseVersyms() {
- size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
- if (!VersymSec)
- return std::vector<uint32_t>(Size, VER_NDX_GLOBAL);
+ // DSOs are uniquified not by filename but by soname.
+ DenseMap<StringRef, SharedFile *>::iterator It;
+ bool WasInserted;
+ std::tie(It, WasInserted) = Symtab->SoNames.try_emplace(SoName, this);
+
+ // If a DSO appears more than once on the command line with and without
+ // --as-needed, --no-as-needed takes precedence over --as-needed because a
+ // user can add an extra DSO with --no-as-needed to force it to be added to
+ // the dependency list.
+ It->second->IsNeeded |= IsNeeded;
+ if (!WasInserted)
+ return;
- const char *Base = this->MB.getBuffer().data();
- const Elf_Versym *Versym =
- reinterpret_cast<const Elf_Versym *>(Base + VersymSec->sh_offset) +
- this->FirstGlobal;
-
- std::vector<uint32_t> Ret(Size);
- for (size_t I = 0; I < Size; ++I)
- Ret[I] = Versym[I].vs_index;
- return Ret;
-}
-
-// Parse the version definitions in the object file if present. Returns a vector
-// whose nth element contains a pointer to the Elf_Verdef for version identifier
-// n. Version identifiers that are not definitions map to nullptr.
-template <class ELFT>
-std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {
- if (!VerdefSec)
- return {};
+ SharedFiles.push_back(this);
- // We cannot determine the largest verdef identifier without inspecting
- // every Elf_Verdef, but both bfd and gold assign verdef identifiers
- // sequentially starting from 1, so we predict that the largest identifier
- // will be VerdefCount.
- unsigned VerdefCount = VerdefSec->sh_info;
- std::vector<const Elf_Verdef *> Verdefs(VerdefCount + 1);
+ Verdefs = parseVerdefs<ELFT>(Obj.base(), VerdefSec);
- // Build the Verdefs array by following the chain of Elf_Verdef objects
- // from the start of the .gnu.version_d section.
- const char *Base = this->MB.getBuffer().data();
- const char *Verdef = Base + VerdefSec->sh_offset;
- for (unsigned I = 0; I != VerdefCount; ++I) {
- auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);
- Verdef += CurVerdef->vd_next;
- unsigned VerdefIndex = CurVerdef->vd_ndx;
- Verdefs.resize(VerdefIndex + 1);
- Verdefs[VerdefIndex] = CurVerdef;
+ // Parse ".gnu.version" section which is a parallel array for the symbol
+ // table. If a given file doesn't have a ".gnu.version" section, we use
+ // VER_NDX_GLOBAL.
+ size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
+ std::vector<uint32_t> Versyms(Size, VER_NDX_GLOBAL);
+ if (VersymSec) {
+ ArrayRef<Elf_Versym> Versym =
+ CHECK(Obj.template getSectionContentsAsArray<Elf_Versym>(VersymSec),
+ this)
+ .slice(FirstGlobal);
+ for (size_t I = 0; I < Size; ++I)
+ Versyms[I] = Versym[I].vs_index;
}
- return Verdefs;
-}
-
-// We do not usually care about alignments of data in shared object
-// files because the loader takes care of it. However, if we promote a
-// DSO symbol to point to .bss due to copy relocation, we need to keep
-// the original alignment requirements. We infer it in this function.
-template <class ELFT>
-uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
- const Elf_Sym &Sym) {
- uint64_t Ret = UINT64_MAX;
- if (Sym.st_value)
- Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
- if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
- Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
- return (Ret > UINT32_MAX) ? 0 : Ret;
-}
-
-// Fully parse the shared object file. This must be called after parseDynamic().
-//
-// This function parses symbol versions. If a DSO has version information,
-// the file has a ".gnu.version_d" section which contains symbol version
-// definitions. Each symbol is associated to one version through a table in
-// ".gnu.version" section. That table is a parallel array for the symbol
-// table, and each table entry contains an index in ".gnu.version_d".
-//
-// The special index 0 is reserved for VERF_NDX_LOCAL and 1 is for
-// VER_NDX_GLOBAL. There's no table entry for these special versions in
-// ".gnu.version_d".
-//
-// The file format for symbol versioning is perhaps a bit more complicated
-// than necessary, but you can easily understand the code if you wrap your
-// head around the data structure described above.
-template <class ELFT> void SharedFile<ELFT>::parseRest() {
- Verdefs = parseVerdefs(); // parse .gnu.version_d
- std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version
- ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj<ELFT>().sections(), this);
-
// System libraries can have a lot of symbols with versions. Using a
// fixed buffer for computing the versions name (foo at ver) can save a
// lot of allocations.
@@ -1043,9 +1055,9 @@ template <class ELFT> void SharedFile<EL
Name == "_gp_disp")
continue;
- uint64_t Alignment = getAlignment(Sections, Sym);
+ uint64_t Alignment = getAlignment<ELFT>(Sections, Sym);
if (!(Versyms[I] & VERSYM_HIDDEN))
- Symtab->addShared(Name, *this, Sym, Alignment, Idx);
+ Symtab->addShared<ELFT>(Name, *this, Sym, Alignment, Idx);
// Also add the symbol with the versioned name to handle undefined symbols
// with explicit versions.
@@ -1060,10 +1072,11 @@ template <class ELFT> void SharedFile<EL
}
StringRef VerName =
- this->StringTable.data() + Verdefs[Idx]->getAux()->vda_name;
+ this->StringTable.data() +
+ reinterpret_cast<const Elf_Verdef *>(Verdefs[Idx])->getAux()->vda_name;
VersionedNameBuffer.clear();
Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
- Symtab->addShared(Saver.save(Name), *this, Sym, Alignment, Idx);
+ Symtab->addShared<ELFT>(Saver.save(Name), *this, Sym, Alignment, Idx);
}
}
@@ -1259,18 +1272,24 @@ InputFile *elf::createObjectFile(MemoryB
}
InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) {
+ auto *F = make<SharedFile>(MB, DefaultSoName);
switch (getELFKind(MB, "")) {
case ELF32LEKind:
- return make<SharedFile<ELF32LE>>(MB, DefaultSoName);
+ F->parseHeader<ELF32LE>();
+ break;
case ELF32BEKind:
- return make<SharedFile<ELF32BE>>(MB, DefaultSoName);
+ F->parseHeader<ELF32BE>();
+ break;
case ELF64LEKind:
- return make<SharedFile<ELF64LE>>(MB, DefaultSoName);
+ F->parseHeader<ELF64LE>();
+ break;
case ELF64BEKind:
- return make<SharedFile<ELF64BE>>(MB, DefaultSoName);
+ F->parseHeader<ELF64BE>();
+ break;
default:
llvm_unreachable("getELFKind");
}
+ return F;
}
MemoryBufferRef LazyObjFile::getBuffer() {
@@ -1355,7 +1374,7 @@ template class elf::ObjFile<ELF32BE>;
template class elf::ObjFile<ELF64LE>;
template class elf::ObjFile<ELF64BE>;
-template class elf::SharedFile<ELF32LE>;
-template class elf::SharedFile<ELF32BE>;
-template class elf::SharedFile<ELF64LE>;
-template class elf::SharedFile<ELF64BE>;
+template void SharedFile::parse<ELF32LE>();
+template void SharedFile::parse<ELF32BE>();
+template void SharedFile::parse<ELF64LE>();
+template void SharedFile::parse<ELF64BE>();
Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Mon Apr 8 10:35:55 2019
@@ -328,19 +328,10 @@ public:
};
// .so file.
-template <class ELFT> class SharedFile : public ELFFileBase {
- using Elf_Dyn = typename ELFT::Dyn;
- using Elf_Shdr = typename ELFT::Shdr;
- using Elf_Sym = typename ELFT::Sym;
- using Elf_Sym_Range = typename ELFT::SymRange;
- using Elf_Verdef = typename ELFT::Verdef;
- using Elf_Versym = typename ELFT::Versym;
-
- const Elf_Shdr *VersymSec = nullptr;
- const Elf_Shdr *VerdefSec = nullptr;
-
+class SharedFile : public ELFFileBase {
public:
- std::vector<const Elf_Verdef *> Verdefs;
+ // This is actually a vector of Elf_Verdef pointers.
+ std::vector<const void *> Verdefs;
std::vector<StringRef> DtNeeded;
std::string SoName;
@@ -348,11 +339,7 @@ public:
SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
- void parseDynamic();
- void parseRest();
- uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym);
- std::vector<const Elf_Verdef *> parseVerdefs();
- std::vector<uint32_t> parseVersyms();
+ template <typename ELFT> void parse();
struct NeededVer {
// The string table offset of the version name in the output file.
@@ -364,7 +351,7 @@ public:
// Mapping from Elf_Verdef data structures to information about Elf_Vernaux
// data structures in the output file.
- std::map<const Elf_Verdef *, NeededVer> VerdefMap;
+ std::map<const void *, NeededVer> VerdefMap;
// Used for --no-allow-shlib-undefined.
bool AllNeededIsKnown;
@@ -394,7 +381,7 @@ extern std::vector<BinaryFile *> BinaryF
extern std::vector<BitcodeFile *> BitcodeFiles;
extern std::vector<LazyObjFile *> LazyObjFiles;
extern std::vector<InputFile *> ObjectFiles;
-extern std::vector<InputFile *> SharedFiles;
+extern std::vector<SharedFile *> SharedFiles;
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Mon Apr 8 10:35:55 2019
@@ -103,7 +103,7 @@ void MarkLive<ELFT>::resolveReloc(InputS
if (auto *SS = dyn_cast<SharedSymbol>(&Sym))
if (!SS->isWeak())
- SS->getFile<ELFT>().IsNeeded = true;
+ SS->getFile().IsNeeded = true;
for (InputSectionBase *Sec : CNamedSections.lookup(Sym.getName()))
enqueue(Sec, 0);
@@ -276,7 +276,7 @@ template <class ELFT> void elf::markLive
for (Symbol *Sym : Symtab->getSymbols())
if (auto *S = dyn_cast<SharedSymbol>(Sym))
if (S->IsUsedInRegularObj && !S->isWeak())
- S->getFile<ELFT>().IsNeeded = true;
+ S->getFile().IsNeeded = true;
return;
}
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Apr 8 10:35:55 2019
@@ -482,7 +482,7 @@ template <class ELFT> static bool isRead
using Elf_Phdr = typename ELFT::Phdr;
// Determine if the symbol is read-only by scanning the DSO's program headers.
- const SharedFile<ELFT> &File = SS.getFile<ELFT>();
+ const SharedFile &File = SS.getFile();
for (const Elf_Phdr &Phdr :
check(File.template getObj<ELFT>().program_headers()))
if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
@@ -501,7 +501,7 @@ template <class ELFT>
static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
using Elf_Sym = typename ELFT::Sym;
- SharedFile<ELFT> &File = SS.getFile<ELFT>();
+ SharedFile &File = SS.getFile();
SmallSet<SharedSymbol *, 4> Ret;
for (const Elf_Sym &S : File.template getGlobalELFSyms<ELFT>()) {
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon Apr 8 10:35:55 2019
@@ -90,25 +90,8 @@ template <class ELFT> void SymbolTable::
message(toString(File));
// .so file
- if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
- // DSOs are uniquified not by filename but by soname.
- F->parseDynamic();
- if (errorCount())
- return;
-
- // If a DSO appears more than once on the command line with and without
- // --as-needed, --no-as-needed takes precedence over --as-needed because a
- // user can add an extra DSO with --no-as-needed to force it to be added to
- // the dependency list.
- DenseMap<StringRef, InputFile *>::iterator It;
- bool WasInserted;
- std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
- cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
- if (!WasInserted)
- return;
-
- SharedFiles.push_back(F);
- F->parseRest();
+ if (auto *F = dyn_cast<SharedFile>(File)) {
+ F->parse<ELFT>();
return;
}
@@ -485,7 +468,7 @@ Defined *SymbolTable::addDefined(StringR
}
template <typename ELFT>
-void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
+void SymbolTable::addShared(StringRef Name, SharedFile &File,
const typename ELFT::Sym &Sym, uint32_t Alignment,
uint32_t VerdefIndex) {
// DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
@@ -802,15 +785,15 @@ template void SymbolTable::fetchLazy<ELF
template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
-template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &,
+template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile &,
const typename ELF32LE::Sym &,
uint32_t Alignment, uint32_t);
-template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> &,
+template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile &,
const typename ELF32BE::Sym &,
uint32_t Alignment, uint32_t);
-template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &,
+template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile &,
const typename ELF64LE::Sym &,
uint32_t Alignment, uint32_t);
-template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
+template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile &,
const typename ELF64BE::Sym &,
uint32_t Alignment, uint32_t);
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Mon Apr 8 10:35:55 2019
@@ -49,9 +49,8 @@ public:
SectionBase *Section, InputFile *File);
template <class ELFT>
- void addShared(StringRef Name, SharedFile<ELFT> &F,
- const typename ELFT::Sym &Sym, uint32_t Alignment,
- uint32_t VerdefIndex);
+ void addShared(StringRef Name, SharedFile &F, const typename ELFT::Sym &Sym,
+ uint32_t Alignment, uint32_t VerdefIndex);
template <class ELFT>
void addLazyArchive(StringRef Name, ArchiveFile &F,
@@ -80,7 +79,7 @@ public:
void handleDynamicList();
// Set of .so files to not link the same shared object file more than once.
- llvm::DenseMap<StringRef, InputFile *> SoNames;
+ llvm::DenseMap<StringRef, SharedFile *> SoNames;
private:
std::pair<Symbol *, bool> insertName(StringRef Name);
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Mon Apr 8 10:35:55 2019
@@ -13,6 +13,7 @@
#ifndef LLD_ELF_SYMBOLS_H
#define LLD_ELF_SYMBOLS_H
+#include "InputFiles.h"
#include "InputSection.h"
#include "lld/Common/LLVM.h"
#include "lld/Common/Strings.h"
@@ -30,8 +31,6 @@ std::string toString(const elf::InputFil
namespace elf {
-template <class ELFT> class SharedFile;
-
// This is a StringRef-like container that doesn't run strlen().
//
// ELF string tables contain a lot of null-terminated strings. Most of them
@@ -266,9 +265,7 @@ public:
this->Type = llvm::ELF::STT_FUNC;
}
- template <class ELFT> SharedFile<ELFT> &getFile() const {
- return *cast<SharedFile<ELFT>>(File);
- }
+ SharedFile &getFile() const { return *cast<SharedFile>(File); }
uint32_t Alignment;
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Apr 8 10:35:55 2019
@@ -1263,11 +1263,9 @@ template <class ELFT> void DynamicSectio
addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
In.DynStrTab->addString(Config->Rpath));
- for (InputFile *File : SharedFiles) {
- SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
- if (F->IsNeeded)
- addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
- }
+ for (SharedFile *File : SharedFiles)
+ if (File->IsNeeded)
+ addInt(DT_NEEDED, In.DynStrTab->addString(File->SoName));
if (!Config->SoName.empty())
addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));
@@ -2792,7 +2790,7 @@ VersionNeedBaseSection::VersionNeedBaseS
}
template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
- auto &File = cast<SharedFile<ELFT>>(*SS->File);
+ auto &File = cast<SharedFile>(*SS->File);
if (SS->VerdefIndex == VER_NDX_GLOBAL) {
SS->VersionId = VER_NDX_GLOBAL;
return;
@@ -2803,8 +2801,9 @@ template <class ELFT> void VersionNeedSe
// for the soname.
if (File.VerdefMap.empty())
Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
- const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
- typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
+ auto *Ver = reinterpret_cast<const typename ELFT::Verdef *>(
+ File.Verdefs[SS->VerdefIndex]);
+ typename SharedFile::NeededVer &NV = File.VerdefMap[Ver];
// If we don't already know that we need an Elf_Vernaux for this Elf_Verdef,
// prepare to create one by allocating a version identifier and creating a
@@ -2822,7 +2821,7 @@ template <class ELFT> void VersionNeedSe
auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Needed.size());
- for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed) {
+ for (std::pair<SharedFile *, size_t> &P : Needed) {
// Create an Elf_Verneed for this DSO.
Verneed->vn_version = 1;
Verneed->vn_cnt = P.first->VerdefMap.size();
@@ -2839,7 +2838,8 @@ template <class ELFT> void VersionNeedSe
// pointers, but is deterministic because the pointers refer to Elf_Verdef
// data structures within a single input file.
for (auto &NV : P.first->VerdefMap) {
- Vernaux->vna_hash = NV.first->vd_hash;
+ Vernaux->vna_hash =
+ reinterpret_cast<const typename ELFT::Verdef *>(NV.first)->vd_hash;
Vernaux->vna_flags = 0;
Vernaux->vna_other = NV.second.Index;
Vernaux->vna_name = NV.second.StrTab;
@@ -2860,7 +2860,7 @@ template <class ELFT> void VersionNeedSe
template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
unsigned Size = Needed.size() * sizeof(Elf_Verneed);
- for (const std::pair<SharedFile<ELFT> *, size_t> &P : Needed)
+ for (const std::pair<SharedFile *, size_t> &P : Needed)
Size += P.first->VerdefMap.size() * sizeof(Elf_Vernaux);
return Size;
}
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Apr 8 10:35:55 2019
@@ -809,7 +809,7 @@ class VersionNeedSection final : public
// A vector of shared files that need Elf_Verneed data structures and the
// string table offsets of their sonames.
- std::vector<std::pair<SharedFile<ELFT> *, size_t>> Needed;
+ std::vector<std::pair<SharedFile *, size_t>> Needed;
public:
void addSymbol(Symbol *Sym) override;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Apr 8 10:35:55 2019
@@ -1628,15 +1628,14 @@ template <class ELFT> void Writer<ELFT>:
// ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
// catch more cases. That is too much for us. Our approach resembles the one
// used in ld.gold, achieves a good balance to be useful but not too smart.
- for (InputFile *File : SharedFiles) {
- SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
- F->AllNeededIsKnown = llvm::all_of(F->DtNeeded, [&](StringRef Needed) {
- return Symtab->SoNames.count(Needed);
- });
- }
+ for (SharedFile *File : SharedFiles)
+ File->AllNeededIsKnown =
+ llvm::all_of(File->DtNeeded, [&](StringRef Needed) {
+ return Symtab->SoNames.count(Needed);
+ });
for (Symbol *Sym : Symtab->getSymbols())
if (Sym->isUndefined() && !Sym->isWeak())
- if (auto *F = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+ if (auto *F = dyn_cast_or_null<SharedFile>(Sym->File))
if (F->AllNeededIsKnown)
error(toString(F) + ": undefined reference to " + toString(*Sym));
}
@@ -1651,7 +1650,7 @@ template <class ELFT> void Writer<ELFT>:
if (Sym->includeInDynsym()) {
In.DynSymTab->addSymbol(Sym);
- if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+ if (auto *File = dyn_cast_or_null<SharedFile>(Sym->File))
if (File->IsNeeded && !Sym->isUndefined())
In.VerNeed->addSymbol(Sym);
}
More information about the llvm-commits
mailing list