[ELF] - Introduce std::vector<InputFile *> global arrays.

This patch removes lot of static Instances arrays from different input file 
classes and introduces global arrays for access instead. Similar to arrays we
have for InputSections/OutputSectionCommands.

It allows to iterate over input files in a non-templated code.

Differential revision: https://reviews.llvm.org/D35987

llvm-svn: 313619
This commit is contained in:
George Rimar 2017-09-19 09:20:54 +00:00
parent 8d0180c955
commit 696a7f9ac6
11 changed files with 45 additions and 68 deletions

View File

@ -283,8 +283,9 @@ static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
template <class ELFT> uint32_t elf::getMipsEFlags() {
std::vector<FileFlags> V;
for (ObjFile<ELFT> *F : ObjFile<ELFT>::Instances)
V.push_back({F->getName(), F->getObj().getHeader()->e_flags});
for (InputFile *F : ObjectFiles)
V.push_back(
{F->getName(), cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
if (V.empty())
return 0;
checkFlags(V);

View File

@ -1015,8 +1015,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// producing a shared library.
// We also need one if any shared libraries are used and for pie executables
// (probably because the dynamic linker needs it).
Config->HasDynSymTab = !SharedFile<ELFT>::Instances.empty() || Config->Pic ||
Config->ExportDynamic;
Config->HasDynSymTab =
!SharedFiles.empty() || Config->Pic || Config->ExportDynamic;
// Some symbols (such as __ehdr_start) are defined lazily only when there
// are undefined symbols for them, so we add these to trigger that logic.
@ -1064,11 +1064,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// Now that we have a complete list of input files.
// Beyond this point, no new files are added.
// Aggregate all input sections into one place.
for (ObjFile<ELFT> *F : ObjFile<ELFT>::Instances)
for (InputFile *F : ObjectFiles)
for (InputSectionBase *S : F->getSections())
if (S && S != &InputSection::Discarded)
InputSections.push_back(S);
for (BinaryFile *F : BinaryFile::Instances)
for (BinaryFile *F : BinaryFiles)
for (InputSectionBase *S : F->getSections())
InputSections.push_back(cast<InputSection>(S));

View File

@ -35,6 +35,11 @@ using namespace llvm::sys::fs;
using namespace lld;
using namespace lld::elf;
std::vector<BinaryFile *> elf::BinaryFiles;
std::vector<BitcodeFile *> elf::BitcodeFiles;
std::vector<InputFile *> elf::ObjectFiles;
std::vector<InputFile *> elf::SharedFiles;
TarWriter *elf::Tar;
InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
@ -820,8 +825,6 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
}
}
std::vector<BitcodeFile *> BitcodeFile::Instances;
BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
uint64_t OffsetInArchive)
: InputFile(BitcodeKind, MB) {
@ -917,8 +920,6 @@ static ELFKind getELFKind(MemoryBufferRef MB) {
return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
}
std::vector<BinaryFile *> BinaryFile::Instances;
template <class ELFT> void BinaryFile::parse() {
ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());
auto *Section =

View File

@ -162,8 +162,6 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
public:
static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
static std::vector<ObjFile<ELFT> *> Instances;
ArrayRef<SymbolBody *> getLocalSymbols();
ObjFile(MemoryBufferRef M, StringRef ArchiveName);
@ -221,8 +219,6 @@ private:
llvm::once_flag InitDwarfLine;
};
template <class ELFT> std::vector<ObjFile<ELFT> *> ObjFile<ELFT>::Instances;
// LazyObjFile is analogous to ArchiveFile in the sense that
// the file contains lazy symbols. The difference is that
// LazyObjFile wraps a single file instead of multiple files.
@ -279,7 +275,6 @@ public:
template <class ELFT>
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
std::unique_ptr<llvm::lto::InputFile> Obj;
static std::vector<BitcodeFile *> Instances;
};
// .so file.
@ -299,8 +294,6 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
public:
std::string SoName;
static std::vector<SharedFile<ELFT> *> Instances;
const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
@ -332,21 +325,22 @@ public:
bool isNeeded() const { return !AsNeeded || IsUsed; }
};
template <class ELFT>
std::vector<SharedFile<ELFT> *> SharedFile<ELFT>::Instances;
class BinaryFile : public InputFile {
public:
explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
template <class ELFT> void parse();
static std::vector<BinaryFile *> Instances;
};
InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
uint64_t OffsetInArchive = 0);
InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
extern std::vector<BinaryFile *> BinaryFiles;
extern std::vector<BitcodeFile *> BitcodeFiles;
extern std::vector<InputFile *> ObjectFiles;
extern std::vector<InputFile *> SharedFiles;
} // namespace elf
} // namespace lld

View File

@ -44,7 +44,7 @@ std::string lld::toString(const InputSectionBase *Sec) {
return (toString(Sec->File) + ":(" + Sec->Name + ")").str();
}
template <class ELFT> DenseMap<SectionBase *, int> elf::buildSectionOrder() {
DenseMap<SectionBase *, int> elf::buildSectionOrder() {
// Build a map from symbols to their priorities. Symbols that didn't
// appear in the symbol ordering file have the lowest priority 0.
// All explicitly mentioned symbols have negative (higher) priorities.
@ -55,7 +55,7 @@ template <class ELFT> DenseMap<SectionBase *, int> elf::buildSectionOrder() {
// Build a map from sections to their priorities.
DenseMap<SectionBase *, int> SectionOrder;
for (ObjFile<ELFT> *File : ObjFile<ELFT>::Instances) {
for (InputFile *File : ObjectFiles) {
for (SymbolBody *Body : File->getSymbols()) {
auto *D = dyn_cast<DefinedRegular>(Body);
if (!D || !D->Section)
@ -1001,11 +1001,6 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset) const {
return Piece.OutputOff + Addend;
}
template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF32LE>();
template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF32BE>();
template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF64LE>();
template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF64BE>();
template InputSection::InputSection(ObjFile<ELF32LE> *, const ELF32LE::Shdr *,
StringRef);
template InputSection::InputSection(ObjFile<ELF32BE> *, const ELF32BE::Shdr *,

View File

@ -338,7 +338,7 @@ private:
extern std::vector<InputSectionBase *> InputSections;
// Builds section order for handling --symbol-ordering-file.
template <class ELFT> llvm::DenseMap<SectionBase *, int> buildSectionOrder();
llvm::DenseMap<SectionBase *, int> buildSectionOrder();
} // namespace elf

View File

@ -241,25 +241,10 @@ static void sortSections(InputSection **Begin, InputSection **End,
std::stable_sort(Begin, End, getComparator(K));
}
static llvm::DenseMap<SectionBase *, int> getSectionOrder() {
switch (Config->EKind) {
case ELF32LEKind:
return buildSectionOrder<ELF32LE>();
case ELF32BEKind:
return buildSectionOrder<ELF32BE>();
case ELF64LEKind:
return buildSectionOrder<ELF64LE>();
case ELF64BEKind:
return buildSectionOrder<ELF64BE>();
default:
llvm_unreachable("unknown ELF type");
}
}
static void sortBySymbolOrder(InputSection **Begin, InputSection **End) {
if (Config->SymbolOrderingFile.empty())
return;
static llvm::DenseMap<SectionBase *, int> Order = getSectionOrder();
static llvm::DenseMap<SectionBase *, int> Order = buildSectionOrder();
MutableArrayRef<InputSection *> In(Begin, End - Begin);
sortByOrder(In, [&](InputSectionBase *S) { return Order.lookup(S); });
}

View File

@ -50,7 +50,7 @@ static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
// Returns a list of all symbols that we want to print out.
template <class ELFT> static std::vector<Defined *> getSymbols() {
std::vector<Defined *> V;
for (ObjFile<ELFT> *File : ObjFile<ELFT>::Instances) {
for (InputFile *File : ObjectFiles) {
for (SymbolBody *B : File->getSymbols()) {
if (auto *DR = dyn_cast<DefinedRegular>(B)) {
if (DR->getFile() == File && !DR->isSection() && DR->Section &&

View File

@ -62,7 +62,7 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
// Binary file
if (auto *F = dyn_cast<BinaryFile>(File)) {
BinaryFile::Instances.push_back(F);
BinaryFiles.push_back(F);
F->parse<ELFT>();
return;
}
@ -88,22 +88,21 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
F->parseSoName();
if (ErrorCount || !SoNames.insert(F->SoName).second)
return;
SharedFile<ELFT>::Instances.push_back(F);
SharedFiles.push_back(F);
F->parseRest();
return;
}
// LLVM bitcode file
if (auto *F = dyn_cast<BitcodeFile>(File)) {
BitcodeFile::Instances.push_back(F);
BitcodeFiles.push_back(F);
F->parse<ELFT>(ComdatGroups);
return;
}
// Regular object file
auto *F = cast<ObjFile<ELFT>>(File);
ObjFile<ELFT>::Instances.push_back(F);
F->parse(ComdatGroups);
ObjectFiles.push_back(File);
cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
}
// This function is where all the optimizations of link-time
@ -114,19 +113,18 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
// Because all bitcode files that consist of a program are passed
// to the compiler at once, it can do whole-program optimization.
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
if (BitcodeFile::Instances.empty())
if (BitcodeFiles.empty())
return;
// Compile bitcode files and replace bitcode symbols.
LTO.reset(new BitcodeCompiler);
for (BitcodeFile *F : BitcodeFile::Instances)
for (BitcodeFile *F : BitcodeFiles)
LTO->add(*F);
for (InputFile *File : LTO->compile()) {
ObjFile<ELFT> *Obj = cast<ObjFile<ELFT>>(File);
DenseSet<CachedHashStringRef> DummyGroups;
Obj->parse(DummyGroups);
ObjFile<ELFT>::Instances.push_back(Obj);
cast<ObjFile<ELFT>>(File)->parse(DummyGroups);
ObjectFiles.push_back(File);
}
}
@ -593,8 +591,8 @@ template <class ELFT> void SymbolTable::scanUndefinedFlags() {
// shared libraries can find them.
// Except this, we ignore undefined symbols in DSOs.
template <class ELFT> void SymbolTable::scanShlibUndefined() {
for (SharedFile<ELFT> *File : SharedFile<ELFT>::Instances) {
for (StringRef U : File->getUndefinedSymbols()) {
for (InputFile *F : SharedFiles) {
for (StringRef U : cast<SharedFile<ELFT>>(F)->getUndefinedSymbols()) {
SymbolBody *Sym = find(U);
if (!Sym || !Sym->isDefined())
continue;

View File

@ -1028,9 +1028,11 @@ template <class ELFT> void DynamicSection<ELFT>::addEntries() {
if (!Config->Rpath.empty())
add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
InX::DynStrTab->addString(Config->Rpath)});
for (SharedFile<ELFT> *F : SharedFile<ELFT>::Instances)
for (InputFile *File : SharedFiles) {
SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
if (F->isNeeded())
add({DT_NEEDED, InX::DynStrTab->addString(F->SoName)});
}
if (!Config->SoName.empty())
add({DT_SONAME, InX::DynStrTab->addString(Config->SoName)});

View File

@ -115,9 +115,9 @@ StringRef elf::getOutputSectionName(StringRef Name) {
return Name;
}
template <class ELFT> static bool needsInterpSection() {
return !SharedFile<ELFT>::Instances.empty() &&
!Config->DynamicLinker.empty() && !Script->ignoreInterpSection();
static bool needsInterpSection() {
return !SharedFiles.empty() && !Config->DynamicLinker.empty() &&
!Script->ignoreInterpSection();
}
template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
@ -273,7 +273,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
Out::ProgramHeaders->updateAlignment(Config->Wordsize);
if (needsInterpSection<ELFT>()) {
if (needsInterpSection()) {
InX::Interp = createInterpSection();
Add(InX::Interp);
} else {
@ -454,7 +454,8 @@ static bool includeInSymtab(const SymbolBody &B) {
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
if (!InX::SymTab)
return;
for (ObjFile<ELFT> *F : ObjFile<ELFT>::Instances) {
for (InputFile *File : ObjectFiles) {
ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
for (SymbolBody *B : F->getLocalSymbols()) {
if (!B->IsLocal)
fatal(toString(F) +
@ -862,12 +863,12 @@ static void sortCtorsDtors(OutputSection *Cmd) {
}
// Sort input sections using the list provided by --symbol-ordering-file.
template <class ELFT> static void sortBySymbolsOrder() {
static void sortBySymbolsOrder() {
if (Config->SymbolOrderingFile.empty())
return;
// Sort sections by priority.
DenseMap<SectionBase *, int> SectionOrder = buildSectionOrder<ELFT>();
DenseMap<SectionBase *, int> SectionOrder = buildSectionOrder();
for (BaseCommand *Base : Script->Opt.Commands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
@ -897,7 +898,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
Old.end());
Script->fabricateDefaultCommands();
sortBySymbolsOrder<ELFT>();
sortBySymbolsOrder();
sortInitFini(findSection(".init_array"));
sortInitFini(findSection(".fini_array"));
sortCtorsDtors(findSection(".ctors"));