It owns and manages passes.
llvm-svn: 173287
--- /dev/null
+//===- lld/Core/PassManager.h - Manage linker passes ----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_PASS_MANAGER_H
+#define LLD_CORE_PASS_MANAGER_H
+
+#include "lld/Core/LLVM.h"
+
+#include <memory>
+#include <vector>
+
+namespace lld {
+class MutableFile;
+class Pass;
+
+/// \brief Owns and runs a collection of passes.
+///
+/// This class is currently just a container for passes and a way to run them.
+///
+/// In the future this should handle timing pass runs, running parallel passes,
+/// and validate/satisfy pass dependencies.
+class PassManager {
+public:
+ void add(std::unique_ptr<Pass> pass) {
+ _passes.push_back(std::move(pass));
+ }
+
+ ErrorOr<void> runOnFile(MutableFile &);
+
+private:
+ /// \brief Passes in the order they should run.
+ std::vector<std::unique_ptr<Pass>> _passes;
+};
+} // end namespace lld
+
+#endif
namespace lld {
struct LinkerOptions;
-class GOTPass;
-class StubsPass;
+class PassManager;
class TargetInfo {
protected:
virtual StringRef getEntry() const;
- virtual StubsPass *getStubPass() const { return nullptr; }
- virtual GOTPass *getGOTPass() const { return nullptr; }
+ virtual void addPasses(PassManager &pm) const {}
// TODO: Split out to TargetRelocationInfo.
virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const {
namespace lld {
class ELFTargetInfo;
class File;
-class GOTPass;
class InputFiles;
class MachOTargetInfo;
-class StubsPass;
class TargetInfo;
/// \brief The Writer is an abstract class for writing object files, shared
/// \brief Write a file from the supplied File object
virtual error_code writeFile(const File &linkedFile, StringRef path) = 0;
- /// \brief Return a Pass object for creating stubs/PLT entries
- virtual StubsPass *stubPass() {
- return nullptr;
- }
-
- /// \brief Return a Pass object for creating GOT entries
- virtual GOTPass *gotPass() {
- return nullptr;
- }
-
/// \brief This method is called by Core Linking to give the Writer a chance
/// to add file format specific "files" to set of files to be linked. This is
/// how file format specific atoms can be added to the link.
Error.cpp
File.cpp
InputFiles.cpp
+ PassManager.cpp
Resolver.cpp
SymbolTable.cpp
TargetInfo.cpp
--- /dev/null
+//===- lib/Core/PassManager.cpp - Manage linker passes --------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/Core/PassManager.h"
+
+#include "lld/Core/Pass.h"
+
+#include "llvm/Support/ErrorOr.h"
+
+namespace lld {
+ErrorOr<void> PassManager::runOnFile(MutableFile &mf) {
+ for (auto &pass : _passes) {
+ pass->perform(mf);
+ }
+ return llvm::error_code::success();
+}
+} // end namespace lld
//===----------------------------------------------------------------------===//
#include "lld/ReaderWriter/MachOTargetInfo.h"
+#include "GOTPass.hpp"
+#include "StubsPass.hpp"
#include "lld/Core/LinkerOptions.h"
+#include "lld/Core/PassManager.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/MachO.h"
return _options._entrySymbol;
return "_main";
}
+
+ virtual void addPasses(PassManager &pm) const {
+ pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
+ pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
+ }
};
std::unique_ptr<MachOTargetInfo>
#include "llvm/ADT/DenseMap.h"
#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/LinkerOptions.h"
#include "lld/Core/SharedLibraryAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
#include "MachOFormat.hpp"
#include "ReferenceKinds.h"
#include "ExecutableAtoms.hpp"
-#include "GOTPass.hpp"
-#include "StubsPass.hpp"
-
namespace lld {
namespace mach_o {
MachOWriter(const MachOTargetInfo &ti);
virtual error_code writeFile(const lld::File &file, StringRef path);
- virtual StubsPass *stubPass();
- virtual GOTPass *gotPass();
virtual void addFiles(InputFiles&);
uint64_t addressOfAtom(const Atom *atom);
const MachOTargetInfo &_targetInfo;
KindHandler *_referenceKindHandler;
- StubsPass _stubsPass;
- GOTPass _gotPass;
CRuntimeFile _cRuntimeFile;
LoadCommandsChunk *_loadCommandsChunk;
LoadCommandPaddingChunk *_paddingChunk;
MachOWriter::MachOWriter(const MachOTargetInfo &ti)
: _targetInfo(ti),
_referenceKindHandler(KindHandler::makeHandler(ti.getTriple().getArch())),
- _stubsPass(ti), _cRuntimeFile(ti),
+ _cRuntimeFile(ti),
_bindingInfo(nullptr), _lazyBindingInfo(nullptr),
_symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
_linkEditStartOffset(0), _linkEditStartAddress(0) {
return error_code::success();
}
-
-StubsPass *MachOWriter::stubPass() {
- return &_stubsPass;
-}
-
-GOTPass *MachOWriter::gotPass() {
- return &_gotPass;
-}
-
void MachOWriter::addFiles(InputFiles &inputFiles) {
inputFiles.prependFile(_cRuntimeFile);
}
return error_code::success();
}
- virtual StubsPass *stubPass() {
- return _targetInfo.getStubPass();
- }
-
- virtual GOTPass *gotPass() {
- return _targetInfo.getGOTPass();
- }
-
-
private:
const TargetInfo &_targetInfo;
};
#include "lld/Core/LinkerOptions.h"
#include "lld/Core/LLVM.h"
#include "lld/Core/Pass.h"
+#include "lld/Core/PassManager.h"
#include "lld/Core/Resolver.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "lld/ReaderWriter/MachOTargetInfo.h"
virtual uint64_t getPageSize() const { return 0x1000; }
- virtual StubsPass *getStubPass() const {
+ virtual void addPasses(PassManager &pm) const {
if (_doStubs)
- return const_cast<TestingStubsPass*>(&_stubsPass);
- else
- return nullptr;
- }
-
- virtual GOTPass *getGOTPass() const {
- if (_doGOT)
- return const_cast<TestingGOTPass*>(&_gotPass);
- else
- return nullptr;
+ pm.add(std::unique_ptr<Pass>(new TestingStubsPass));
+ if (_doGOT)
+ pm.add(std::unique_ptr<Pass>(new TestingGOTPass));
}
virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const {
private:
bool _doStubs;
bool _doGOT;
- TestingStubsPass _stubsPass;
- TestingGOTPass _gotPass;
};
int main(int argc, char *argv[]) {
std::unique_ptr<ELFTargetInfo> eti = ELFTargetInfo::create(lo);
std::unique_ptr<MachOTargetInfo> mti = MachOTargetInfo::create(lo);
std::unique_ptr<Writer> writer;
+ const TargetInfo *ti = 0;
switch ( writeSelected ) {
case writeYAML:
writer = createWriterYAML(tti);
+ ti = &tti;
break;
case writeMachO:
writer = createWriterMachO(*mti);
+ ti = mti.get();
break;
case writePECOFF:
writer = createWriterPECOFF(tti);
+ ti = &tti;
break;
case writeELF:
writer = createWriterELF(*eti);
+ ti = eti.get();
break;
}
resolver.resolve();
MutableFile &mergedMasterFile = resolver.resultFile();
- // run passes
- if ( GOTPass *pass = writer->gotPass() ) {
- pass->perform(mergedMasterFile);
- }
- if ( StubsPass *pass = writer->stubPass() ) {
- pass->perform(mergedMasterFile);
- }
+ PassManager pm;
+ if (ti)
+ ti->addPasses(pm);
+ pm.runOnFile(mergedMasterFile);
// showing yaml at this stage can help when debugging
const bool dumpIntermediateYAML = false;