SimpleFile is the only derived class of MutableFile.
This patch reduces the height of class hierarchy by removing
MutableFile class.
llvm-svn: 234354
std::mutex _parseMutex;
};
-/// \brief A mutable File.
-class MutableFile : public File {
-public:
- /// \brief Add an atom to the file. Invalidates iterators for all returned
- /// containters.
- virtual void addAtom(const Atom&) = 0;
-
- typedef range<std::vector<const DefinedAtom *>::iterator> DefinedAtomRange;
- virtual DefinedAtomRange definedAtoms() = 0;
-
- virtual void
- removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) = 0;
-
-protected:
- /// \brief only subclasses of MutableFile can be instantiated
- MutableFile(StringRef p) : File(p, kindObject) {}
-};
-
/// An ErrorFile represents a file that doesn't exist.
/// If you try to parse a file which doesn't exist, an instance of this
/// class will be returned. That's parse method always returns an error.
#include <vector>
namespace lld {
-class MutableFile;
+class SimpleFile;
/// Once the core linking is done (which resolves references, coalesces atoms
/// and produces a complete Atom graph), the linker runs a series of passes
virtual ~Pass() { }
/// Do the actual work of the Pass.
- virtual void perform(std::unique_ptr<MutableFile> &mergedFile) = 0;
+ virtual void perform(std::unique_ptr<SimpleFile> &mergedFile) = 0;
protected:
// Only subclassess can be instantiated.
#include <vector>
namespace lld {
-class MutableFile;
+class SimpleFile;
class Pass;
/// \brief Owns and runs a collection of passes.
_passes.push_back(std::move(pass));
}
- std::error_code runOnFile(std::unique_ptr<MutableFile> &file) {
+ std::error_code runOnFile(std::unique_ptr<SimpleFile> &file) {
for (std::unique_ptr<Pass> &pass : _passes)
pass->perform(file);
return std::error_code();
/// @brief do work of merging and resolving and return list
bool resolve();
- std::unique_ptr<MutableFile> resultFile() { return std::move(_result); }
+ std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); }
private:
typedef std::function<void(StringRef, bool)> UndefCallback;
namespace lld {
-class SimpleFile : public MutableFile {
+class SimpleFile : public File {
public:
- SimpleFile(StringRef path) : MutableFile(path) {}
+ SimpleFile(StringRef path) : File(path, kindObject) {}
- void addAtom(const Atom &atom) override {
+ void addAtom(const Atom &atom) {
if (auto *defAtom = dyn_cast<DefinedAtom>(&atom)) {
_definedAtoms._atoms.push_back(defAtom);
} else if (auto *undefAtom = dyn_cast<UndefinedAtom>(&atom)) {
}
}
- void
- removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) override {
+ void removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) {
auto &atoms = _definedAtoms._atoms;
auto newEnd = std::remove_if(atoms.begin(), atoms.end(), pred);
atoms.erase(newEnd, atoms.end());
return _absoluteAtoms;
}
- DefinedAtomRange definedAtoms() override {
- return make_range(_definedAtoms._atoms);
- }
+ typedef range<std::vector<const DefinedAtom *>::iterator> DefinedAtomRange;
+ DefinedAtomRange definedAtoms() { return make_range(_definedAtoms._atoms); }
private:
atom_collection_vector<DefinedAtom> _definedAtoms;
ctx.getTaskGroup().sync();
return false;
}
- std::unique_ptr<MutableFile> merged = resolver.resultFile();
+ std::unique_ptr<SimpleFile> merged = resolver.resultFile();
resolveTask.end();
// Run passes on linked atoms.
class OrderPass : public Pass {
public:
/// Sorts atoms by position
- void perform(std::unique_ptr<MutableFile> &file) override {
- MutableFile::DefinedAtomRange defined = file->definedAtoms();
+ void perform(std::unique_ptr<SimpleFile> &file) override {
+ SimpleFile::DefinedAtomRange defined = file->definedAtoms();
std::sort(defined.begin(), defined.end(), DefinedAtom::compareByPosition);
}
};
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
- void perform(std::unique_ptr<MutableFile> &mf) override {
+ void perform(std::unique_ptr<SimpleFile> &mf) override {
ScopedTask task(getDefaultDomain(), "AArch64 GOT/PLT Pass");
DEBUG_WITH_TYPE(
"AArch64", llvm::dbgs() << "Undefined Atoms"
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
- void perform(std::unique_ptr<MutableFile> &mf) override {
+ void perform(std::unique_ptr<SimpleFile> &mf) override {
ScopedTask task(getDefaultDomain(), "ARM GOT/PLT Pass");
DEBUG_WITH_TYPE(
"ARM", llvm::dbgs() << "Undefined Atoms" << "\n";
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
- void perform(std::unique_ptr<MutableFile> &mf) override {
+ void perform(std::unique_ptr<SimpleFile> &mf) override {
// Process all references.
for (const auto &atom : mf->defined())
for (const auto &ref : *atom)
//===----------------------------------------------------------------------===//
#include "MipsCtorsOrderPass.h"
+#include "lld/Core/Simple.h"
#include <algorithm>
#include <climits>
return priority;
}
-void MipsCtorsOrderPass::perform(std::unique_ptr<MutableFile> &f) {
+void MipsCtorsOrderPass::perform(std::unique_ptr<SimpleFile> &f) {
auto definedAtoms = f->definedAtoms();
auto last = std::stable_partition(definedAtoms.begin(), definedAtoms.end(),
/// \brief This pass sorts atoms in .{ctors,dtors}.<priority> sections.
class MipsCtorsOrderPass : public Pass {
public:
- void perform(std::unique_ptr<MutableFile> &mergedFile) override;
+ void perform(std::unique_ptr<SimpleFile> &mergedFile) override;
};
}
}
public:
RelocationPass(MipsLinkingContext &ctx);
- void perform(std::unique_ptr<MutableFile> &mf) override;
+ void perform(std::unique_ptr<SimpleFile> &mf) override;
private:
/// \brief Reference to the linking context.
}
template <typename ELFT>
-void RelocationPass<ELFT>::perform(std::unique_ptr<MutableFile> &mf) {
+void RelocationPass<ELFT>::perform(std::unique_ptr<SimpleFile> &mf) {
for (const auto &atom : mf->defined())
for (const auto &ref : *atom)
collectReferenceInfo(*cast<MipsELFDefinedAtom<ELFT>>(atom),
/// \brief This pass sorts atoms by file and atom ordinals.
class OrderPass : public Pass {
public:
- void perform(std::unique_ptr<MutableFile> &file) override {
+ void perform(std::unique_ptr<SimpleFile> &file) override {
parallel_sort(file->definedAtoms().begin(), file->definedAtoms().end(),
DefinedAtom::compareByPosition);
}
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
- void perform(std::unique_ptr<MutableFile> &mf) override {
+ void perform(std::unique_ptr<SimpleFile> &mf) override {
ScopedTask task(getDefaultDomain(), "X86-64 GOT/PLT Pass");
// Process all references.
for (const auto &atom : mf->defined())
_isBig(MachOLinkingContext::isBigEndian(_context.arch())) {}
private:
- void perform(std::unique_ptr<MutableFile> &mergedFile) override {
+ void perform(std::unique_ptr<SimpleFile> &mergedFile) override {
DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n");
std::map<const Atom *, CompactUnwindEntry> unwindLocs;
}
void collectCompactUnwindEntries(
- std::unique_ptr<MutableFile> &mergedFile,
+ std::unique_ptr<SimpleFile> &mergedFile,
std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
std::vector<const Atom *> &personalities, uint32_t &numLSDAs) {
DEBUG(llvm::dbgs() << " Collecting __compact_unwind entries\n");
}
void
- collectDwarfFrameEntries(std::unique_ptr<MutableFile> &mergedFile,
+ collectDwarfFrameEntries(std::unique_ptr<SimpleFile> &mergedFile,
std::map<const Atom *, const Atom *> &dwarfFrames) {
for (const DefinedAtom *ehFrameAtom : mergedFile->defined()) {
if (ehFrameAtom->contentType() != DefinedAtom::typeCFI)
/// + A synthesised reference to __eh_frame if there's no __compact_unwind
/// or too many personality functions to be accommodated.
std::vector<CompactUnwindEntry> createUnwindInfoEntries(
- const std::unique_ptr<MutableFile> &mergedFile,
+ const std::unique_ptr<SimpleFile> &mergedFile,
const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
const std::vector<const Atom *> &personalities,
const std::map<const Atom *, const Atom *> &dwarfFrames) {
_file("<mach-o GOT Pass>") { }
private:
-
- void perform(std::unique_ptr<MutableFile> &mergedFile) override {
+ void perform(std::unique_ptr<SimpleFile> &mergedFile) override {
// Scan all references in all atoms.
for (const DefinedAtom *atom : mergedFile->defined()) {
for (const Reference *ref : *atom) {
}
}
-static void printDefinedAtoms(const MutableFile::DefinedAtomRange &atomRange) {
+static void printDefinedAtoms(const SimpleFile::DefinedAtomRange &atomRange) {
for (const DefinedAtom *atom : atomRange) {
llvm::dbgs() << " file=" << atom->file().path()
<< ", name=" << atom->name()
/// Verify that the followon chain is sane. Should not be called in
/// release binary.
-void LayoutPass::checkFollowonChain(MutableFile::DefinedAtomRange &range) {
+void LayoutPass::checkFollowonChain(SimpleFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::checkFollowonChain");
// Verify that there's no cycle in follow-on chain.
/// d) If the targetAtom is part of a different chain and the root of the
/// targetAtom until the targetAtom has all atoms of size 0, then chain the
/// targetAtoms and its tree to the current chain
-void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
+void LayoutPass::buildFollowOnTable(SimpleFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::buildFollowOnTable");
// Set the initial size of the followon and the followonNext hash to the
// number of atoms that we have.
/// assigning ordinals to each atom, if the atoms have their ordinals
/// already assigned skip the atom and move to the next. This is the
/// main map thats used to sort the atoms while comparing two atoms together
-void LayoutPass::buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range) {
+void LayoutPass::buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range) {
ScopedTask task(getDefaultDomain(), "LayoutPass::buildOrdinalOverrideMap");
uint64_t index = 0;
for (const DefinedAtom *ai : range) {
}
std::vector<LayoutPass::SortKey>
-LayoutPass::decorate(MutableFile::DefinedAtomRange &atomRange) const {
+LayoutPass::decorate(SimpleFile::DefinedAtomRange &atomRange) const {
std::vector<SortKey> ret;
for (const DefinedAtom *atom : atomRange) {
auto ri = _followOnRoots.find(atom);
return ret;
}
-void LayoutPass::undecorate(MutableFile::DefinedAtomRange &atomRange,
+void LayoutPass::undecorate(SimpleFile::DefinedAtomRange &atomRange,
std::vector<SortKey> &keys) const {
size_t i = 0;
for (SortKey &k : keys)
}
/// Perform the actual pass
-void LayoutPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
+void LayoutPass::perform(std::unique_ptr<SimpleFile> &mergedFile) {
// sort the atoms
ScopedTask task(getDefaultDomain(), "LayoutPass");
- MutableFile::DefinedAtomRange atomRange = mergedFile->definedAtoms();
+ SimpleFile::DefinedAtomRange atomRange = mergedFile->definedAtoms();
// Build follow on tables
buildFollowOnTable(atomRange);
#include "lld/Core/File.h"
#include "lld/Core/Pass.h"
#include "lld/Core/Reader.h"
+#include "lld/Core/Simple.h"
#include "llvm/ADT/DenseMap.h"
#include <map>
#include <string>
namespace lld {
class DefinedAtom;
-class MutableFile;
+class SimpleFile;
namespace mach_o {
LayoutPass(const Registry ®istry, SortOverride sorter);
/// Sorts atoms in mergedFile by content type then by command line order.
- void perform(std::unique_ptr<MutableFile> &mergedFile) override;
+ void perform(std::unique_ptr<SimpleFile> &mergedFile) override;
virtual ~LayoutPass() {}
private:
// Build the followOn atoms chain as specified by the kindLayoutAfter
// reference type
- void buildFollowOnTable(MutableFile::DefinedAtomRange &range);
+ void buildFollowOnTable(SimpleFile::DefinedAtomRange &range);
// Build a map of Atoms to ordinals for sorting the atoms
- void buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range);
+ void buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range);
const Registry &_registry;
SortOverride _customSorter;
void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root);
- std::vector<SortKey> decorate(MutableFile::DefinedAtomRange &atomRange) const;
- void undecorate(MutableFile::DefinedAtomRange &atomRange,
+ std::vector<SortKey> decorate(SimpleFile::DefinedAtomRange &atomRange) const;
+ void undecorate(SimpleFile::DefinedAtomRange &atomRange,
std::vector<SortKey> &keys) const;
// Check if the follow-on graph is a correct structure. For debugging only.
- void checkFollowonChain(MutableFile::DefinedAtomRange &range);
+ void checkFollowonChain(SimpleFile::DefinedAtomRange &range);
};
} // namespace mach_o
, _file("<mach-o shim pass>") {
}
-
- void perform(std::unique_ptr<MutableFile> &mergedFile) override {
+ void perform(std::unique_ptr<SimpleFile> &mergedFile) override {
// Scan all references in all atoms.
for (const DefinedAtom *atom : mergedFile->defined()) {
for (const Reference *ref : *atom) {
: _context(context), _archHandler(_context.archHandler()),
_stubInfo(_archHandler.stubInfo()), _file("<mach-o Stubs pass>") { }
-
- void perform(std::unique_ptr<MutableFile> &mergedFile) override {
+ void perform(std::unique_ptr<SimpleFile> &mergedFile) override {
// Skip this pass if output format uses text relocations instead of stubs.
if (!this->noTextRelocs())
return;
desc.ordinal = nextOrdinal++;
}
-static bool getExportedAtoms(PECOFFLinkingContext &ctx, MutableFile *file,
+static bool getExportedAtoms(PECOFFLinkingContext &ctx, SimpleFile *file,
std::vector<TableEntry> &ret) {
std::map<StringRef, const DefinedAtom *> definedAtoms;
for (const DefinedAtom *atom : file->defined())
edata::EdataAtom *
EdataPass::createNamePointerTable(const PECOFFLinkingContext &ctx,
const std::vector<TableEntry> &entries,
- MutableFile *file) {
+ SimpleFile *file) {
EdataAtom *table =
new (_alloc) EdataAtom(_file, sizeof(uint32_t) * entries.size());
return ret;
}
-void EdataPass::perform(std::unique_ptr<MutableFile> &file) {
+void EdataPass::perform(std::unique_ptr<SimpleFile> &file) {
dedupExports(_ctx);
assignOrdinals(_ctx);
EdataPass(PECOFFLinkingContext &ctx)
: _ctx(ctx), _file(ctx), _is64(ctx.is64Bit()), _stringOrdinal(1024) {}
- void perform(std::unique_ptr<MutableFile> &file) override;
+ void perform(std::unique_ptr<SimpleFile> &file) override;
private:
edata::EdataAtom *
edata::EdataAtom *
createNamePointerTable(const PECOFFLinkingContext &ctx,
const std::vector<edata::TableEntry> &entries,
- MutableFile *file);
+ SimpleFile *file);
edata::EdataAtom *
createOrdinalTable(const std::vector<edata::TableEntry> &entries,
// Find "___delayLoadHelper2@8" (or "__delayLoadHelper2" on x64).
// This is not efficient but should be OK for now.
-static const Atom *
-findDelayLoadHelper(MutableFile &file, const PECOFFLinkingContext &ctx) {
+static const Atom *findDelayLoadHelper(SimpleFile &file,
+ const PECOFFLinkingContext &ctx) {
StringRef sym = ctx.getDelayLoadHelperName();
for (const DefinedAtom *atom : file.defined())
if (atom->name() == sym)
} // namespace idata
-void IdataPass::perform(std::unique_ptr<MutableFile> &file) {
+void IdataPass::perform(std::unique_ptr<SimpleFile> &file) {
if (file->sharedLibrary().empty())
return;
replaceSharedLibraryAtoms(*file);
}
-std::map<StringRef, std::vector<COFFSharedLibraryAtom *> >
-IdataPass::groupByLoadName(MutableFile &file) {
+std::map<StringRef, std::vector<COFFSharedLibraryAtom *>>
+IdataPass::groupByLoadName(SimpleFile &file) {
std::map<StringRef, COFFSharedLibraryAtom *> uniqueAtoms;
for (const SharedLibraryAtom *atom : file.sharedLibrary())
uniqueAtoms[atom->name()] =
}
/// Transforms a reference to a COFFSharedLibraryAtom to a real reference.
-void IdataPass::replaceSharedLibraryAtoms(MutableFile &file) {
+void IdataPass::replaceSharedLibraryAtoms(SimpleFile &file) {
for (const DefinedAtom *atom : file.defined()) {
for (const Reference *ref : *atom) {
const Atom *target = ref->target();
// A state object of this pass.
struct IdataContext {
- IdataContext(MutableFile &f, VirtualFile &g, const PECOFFLinkingContext &c)
+ IdataContext(SimpleFile &f, VirtualFile &g, const PECOFFLinkingContext &c)
: file(f), dummyFile(g), ctx(c) {}
- MutableFile &file;
+ SimpleFile &file;
VirtualFile &dummyFile;
const PECOFFLinkingContext &ctx;
};
public:
IdataPass(const PECOFFLinkingContext &ctx) : _dummyFile(ctx), _ctx(ctx) {}
- void perform(std::unique_ptr<MutableFile> &file) override;
+ void perform(std::unique_ptr<SimpleFile> &file) override;
private:
std::map<StringRef, std::vector<COFFSharedLibraryAtom *>>
- groupByLoadName(MutableFile &file);
+ groupByLoadName(SimpleFile &file);
- void replaceSharedLibraryAtoms(MutableFile &file);
+ void replaceSharedLibraryAtoms(SimpleFile &file);
// A dummy file with which all the atoms created in the pass will be
// associated. Atoms need to be associated to an input file even if it's not
public:
InferSubsystemPass(PECOFFLinkingContext &ctx) : _ctx(ctx) {}
- void perform(std::unique_ptr<MutableFile> &file) override {
+ void perform(std::unique_ptr<SimpleFile> &file) override {
if (_ctx.getSubsystem() != WindowsSubsystem::IMAGE_SUBSYSTEM_UNKNOWN)
return;
} // namespace loadcfg
-void LoadConfigPass::perform(std::unique_ptr<MutableFile> &file) {
+void LoadConfigPass::perform(std::unique_ptr<SimpleFile> &file) {
if (_ctx.noSEH())
return;
public:
LoadConfigPass(PECOFFLinkingContext &ctx) : _ctx(ctx), _file(ctx) {}
- void perform(std::unique_ptr<MutableFile> &file) override;
+ void perform(std::unique_ptr<SimpleFile> &file) override;
private:
PECOFFLinkingContext &_ctx;
class OrderPass : public lld::Pass {
public:
- void perform(std::unique_ptr<MutableFile> &file) override {
- MutableFile::DefinedAtomRange defined = file->definedAtoms();
+ void perform(std::unique_ptr<SimpleFile> &file) override {
+ SimpleFile::DefinedAtomRange defined = file->definedAtoms();
parallel_sort(defined.begin(), defined.end(), compare);
}
};
public:
PDBPass(PECOFFLinkingContext &ctx) : _ctx(ctx) {}
- void perform(std::unique_ptr<MutableFile> &file) override {
+ void perform(std::unique_ptr<SimpleFile> &file) override {
if (_ctx.getDebug())
touch(_ctx.getPDBFilePath());
}