Skip to content

Commit

Permalink
[ELF] - Introduce std::vector<InputFile *> global arrays.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
George Rimar committed Sep 19, 2017
1 parent 8d0180c commit 696a7f9
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 68 deletions.
5 changes: 3 additions & 2 deletions lld/ELF/Arch/MipsArchTree.cpp
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions lld/ELF/Driver.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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));

Expand Down
9 changes: 5 additions & 4 deletions lld/ELF/InputFiles.cpp
Expand Up @@ -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) {}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 =
Expand Down
16 changes: 5 additions & 11 deletions lld/ELF/InputFiles.h
Expand Up @@ -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);
Expand Down Expand Up @@ -221,8 +219,6 @@ template <class ELFT> class ObjFile : public ELFFileBase<ELFT> {
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.
Expand Down Expand Up @@ -279,7 +275,6 @@ class BitcodeFile : public InputFile {
template <class ELFT>
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
std::unique_ptr<llvm::lto::InputFile> Obj;
static std::vector<BitcodeFile *> Instances;
};

// .so file.
Expand All @@ -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; }

Expand Down Expand Up @@ -332,21 +325,22 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
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

Expand Down
9 changes: 2 additions & 7 deletions lld/ELF/InputSection.cpp
Expand Up @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -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 *,
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/InputSection.h
Expand Up @@ -338,7 +338,7 @@ class InputSection : public InputSectionBase {
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

Expand Down
17 changes: 1 addition & 16 deletions lld/ELF/LinkerScript.cpp
Expand Up @@ -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); });
}
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/MapFile.cpp
Expand Up @@ -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 &&
Expand Down
24 changes: 11 additions & 13 deletions lld/ELF/SymbolTable.cpp
Expand Up @@ -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;
}
Expand All @@ -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
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion lld/ELF/SyntheticSections.cpp
Expand Up @@ -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)});

Expand Down
17 changes: 9 additions & 8 deletions lld/ELF/Writer.cpp
Expand Up @@ -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(); }
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) +
Expand Down Expand Up @@ -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); });
Expand Down Expand Up @@ -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"));
Expand Down

0 comments on commit 696a7f9

Please sign in to comment.