forked from OSchip/llvm-project
[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:
parent
8d0180c955
commit
696a7f9ac6
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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); });
|
||||
}
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)});
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in New Issue