[PassManager] add ReaderWriter{Native,YAML} to the Driver.

Enable this for the following flavors

a) core
b) gnu
c) darwin

Its disabled for the flavor PECOFF. Convenient markers are added with FIXME
comments in the Driver that would be removed and code removed from each flavor.

llvm-svn: 193585
This commit is contained in:
Shankar Easwaran 2013-10-29 05:12:14 +00:00
parent 3aca58f135
commit 2bc24928d3
37 changed files with 297 additions and 70 deletions

View File

@ -293,7 +293,7 @@ public:
/// This method is called by core linking to build the list of Passes to be
/// run on the merged/linked graph of all input files.
virtual void addPasses(PassManager &pm) const;
virtual void addPasses(PassManager &pm);
/// Calls through to the writeFile() method on the specified Writer.
///

View File

@ -36,7 +36,7 @@ public:
virtual ~Pass() { }
/// Do the actual work of the Pass.
virtual void perform(MutableFile &mergedFile) = 0;
virtual void perform(std::unique_ptr<MutableFile> &mergedFile) = 0;
protected:
// Only subclassess can be instantiated.
@ -53,7 +53,7 @@ public:
/// Scans all Atoms looking for call-site uses of SharedLibraryAtoms
/// and transfroms the call-site to call a stub instead using the
/// helper methods below.
virtual void perform(MutableFile &mergedFile);
virtual void perform(std::unique_ptr<MutableFile> &mergedFile);
/// If true, the pass should use stubs for references
/// to shared library symbols. If false, the pass
@ -87,7 +87,7 @@ public:
/// Scans all Atoms looking for pointer to SharedLibraryAtoms
/// and transfroms them to a pointer to a GOT entry using the
/// helper methods below.
virtual void perform(MutableFile &mergedFile);
virtual void perform(std::unique_ptr<MutableFile> &mergedFile);
/// If true, the pass will use GOT entries for references
/// to shared library symbols. If false, the pass

View File

@ -32,7 +32,7 @@ public:
_passes.push_back(std::move(pass));
}
ErrorOr<void> runOnFile(MutableFile &);
ErrorOr<void> runOnFile(std::unique_ptr<MutableFile> &);
private:
/// \brief Passes in the order they should run.

View File

@ -37,8 +37,9 @@ public:
};
Resolver(LinkingContext &context)
: _context(context), _symbolTable(context), _result(context),
_haveLLVMObjs(false), _addToFinalSection(false) {}
: _context(context), _symbolTable(context),
_result(new MergedFile(context)), _haveLLVMObjs(false),
_addToFinalSection(false) {}
virtual ~Resolver() {}
@ -62,9 +63,7 @@ public:
/// @brief do work of merging and resolving and return list
bool resolve();
MutableFile& resultFile() {
return _result;
}
std::unique_ptr<MutableFile> resultFile() { return std::move(_result); }
private:
@ -117,7 +116,7 @@ private:
std::set<const Atom *> _deadStripRoots;
std::vector<const Atom *> _atomsWithUnresolvedReferences;
llvm::DenseSet<const Atom *> _liveAtoms;
MergedFile _result;
std::unique_ptr<MergedFile> _result;
bool _haveLLVMObjs;
bool _addToFinalSection;
};

View File

@ -48,7 +48,7 @@ public:
LayoutPass() : Pass(), _compareAtoms(*this) {}
/// Sorts atoms in mergedFile by content type then by command line order.
virtual void perform(MutableFile &mergedFile);
virtual void perform(std::unique_ptr<MutableFile> &mergedFile);
virtual ~LayoutPass() {}

View File

@ -0,0 +1,41 @@
//===--Passes/RoundTripNativePass.h - Write Native file/Read it back------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_PASSES_ROUND_TRIP_NATIVE_PASS_H
#define LLD_PASSES_ROUND_TRIP_NATIVE_PASS_H
#include "lld/Core/File.h"
#include "lld/Core/LinkingContext.h"
#include "lld/Core/Pass.h"
#include <map>
#include <vector>
namespace lld {
class RoundTripNativePass : public Pass {
public:
RoundTripNativePass(LinkingContext &context) : Pass(), _context(context) {}
/// Writes to a native file and reads the atoms from the native file back.
/// Replaces mergedFile with the contents of the native File.
virtual void perform(std::unique_ptr<MutableFile> &mergedFile);
virtual ~RoundTripNativePass() {}
private:
LinkingContext &_context;
// Keep the parsed file alive for the rest of the link. All atoms
// that are created by the RoundTripNativePass are owned by the
// nativeFile.
std::vector<std::unique_ptr<File> > _nativeFile;
};
} // namespace lld
#endif // LLD_PASSES_ROUND_TRIP_NATIVE_PASS_H

View File

@ -0,0 +1,41 @@
//===--Passes/RoundTripYAMLPass.h- Write YAML file/Read it back-----------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_PASSES_ROUND_TRIP_YAML_PASS_H
#define LLD_PASSES_ROUND_TRIP_YAML_PASS_H
#include "lld/Core/File.h"
#include "lld/Core/LinkingContext.h"
#include "lld/Core/Pass.h"
#include <map>
#include <vector>
namespace lld {
class RoundTripYAMLPass : public Pass {
public:
RoundTripYAMLPass(LinkingContext &context) : Pass(), _context(context) {}
/// Writes to a YAML file and reads the atoms from the YAML file back.
/// Replaces the mergedFile with new contents.
virtual void perform(std::unique_ptr<MutableFile> &mergedFile);
virtual ~RoundTripYAMLPass() {}
private:
LinkingContext &_context;
// Keep the parsed file alive for the rest of the link. All atoms
// that are created by the RoundTripYAMLPass are owned by the
// yamlFile.
std::vector<std::unique_ptr<File> > _yamlFile;
};
} // namespace lld
#endif // LLD_PASSES_ROUND_TRIP_YAML_PASS_H

View File

@ -23,7 +23,7 @@ public:
CoreLinkingContext();
virtual bool validateImpl(raw_ostream &diagnostics);
virtual void addPasses(PassManager &pm) const;
virtual void addPasses(PassManager &pm);
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;

View File

@ -130,7 +130,7 @@ public:
return static_cast<lld::elf::TargetHandler<ELFT> &>(*_targetHandler.get());
}
virtual void addPasses(PassManager &pm) const;
virtual void addPasses(PassManager &pm);
void setTriple(llvm::Triple trip) { _triple = trip; }
void setNoInhibitExec(bool v) { _noInhibitExec = v; }

View File

@ -27,7 +27,7 @@ public:
MachOLinkingContext();
~MachOLinkingContext();
virtual void addPasses(PassManager &pm) const;
virtual void addPasses(PassManager &pm);
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual bool validateImpl(raw_ostream &diagnostics);

View File

@ -65,7 +65,7 @@ public:
virtual Writer &writer() const;
virtual bool validateImpl(raw_ostream &diagnostics);
virtual void addPasses(PassManager &pm) const;
virtual void addPasses(PassManager &pm);
virtual bool
createImplicitFiles(std::vector<std::unique_ptr<File> > &result) const;

View File

@ -62,13 +62,31 @@ public:
return make_range(_definedAtoms._atoms);
}
private:
protected:
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
};
class FileToMutable : public SimpleFile {
public:
explicit FileToMutable(const LinkingContext &context, File &file)
: SimpleFile(context, file.path()), _file(file) {
for (auto definedAtom : _file.defined())
_definedAtoms._atoms.push_back(std::move(definedAtom));
for (auto undefAtom : _file.undefined())
_undefinedAtoms._atoms.push_back(std::move(undefAtom));
for (auto shlibAtom : _file.sharedLibrary())
_sharedLibraryAtoms._atoms.push_back(std::move(shlibAtom));
for (auto absAtom : _file.absolute())
_absoluteAtoms._atoms.push_back(std::move(absAtom));
}
private:
const File &_file;
};
class SimpleReference : public Reference {
public:
SimpleReference(Reference::Kind k, uint64_t off, const Atom *t,

View File

@ -108,6 +108,6 @@ ErrorOr<File &> LinkingContext::nextFile() {
}
}
void LinkingContext::addPasses(PassManager &pm) const {}
void LinkingContext::addPasses(PassManager &pm) {}
} // end namespace lld

View File

@ -15,7 +15,7 @@
#include "llvm/Support/ErrorOr.h"
namespace lld {
ErrorOr<void> PassManager::runOnFile(MutableFile &mf) {
ErrorOr<void> PassManager::runOnFile(std::unique_ptr<MutableFile> &mf) {
for (auto &pass : _passes) {
pass->perform(mf);
}

View File

@ -480,7 +480,7 @@ bool Resolver::resolve() {
}
this->removeCoalescedAwayAtoms();
this->linkTimeOptimize();
this->_result.addAtoms(_atoms);
this->_result->addAtoms(_atoms);
return true;
}

View File

@ -16,6 +16,8 @@
#include "lld/Core/Resolver.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
@ -105,19 +107,27 @@ bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) {
Resolver resolver(context);
if (!resolver.resolve())
return false;
MutableFile &merged = resolver.resultFile();
std::unique_ptr<MutableFile> merged = resolver.resultFile();
resolveTask.end();
// Run passes on linked atoms.
ScopedTask passTask(getDefaultDomain(), "Passes");
PassManager pm;
context.addPasses(pm);
// TODO: Replace the code with #ifndef NDEBUG after fixing the
// failures with pecoff
#ifdef FIXME
pm.add(std::unique_ptr<Pass>(new RoundTripNativePass(context)));
pm.add(std::unique_ptr<Pass>(new RoundTripYAMLPass(context)));
#endif
pm.runOnFile(merged);
passTask.end();
// Give linked atoms to Writer to generate output file.
ScopedTask writeTask(getDefaultDomain(), "Write");
if (error_code ec = context.writeFile(merged)) {
if (error_code ec = context.writeFile(*merged)) {
diagnostics << "Failed to write file '" << context.outputPath()
<< "': " << ec.message() << "\n";
return false;

View File

@ -2,4 +2,8 @@ add_lld_library(lldPasses
GOTPass.cpp
StubsPass.cpp
LayoutPass.cpp
RoundTripNativePass.cpp
RoundTripYAMLPass.cpp
)
target_link_libraries(lldPasses lldReaderWriter)

View File

@ -67,12 +67,12 @@ findGOTAtom(const Atom *target,
}
} // end anonymous namespace
void GOTPass::perform(MutableFile &mergedFile) {
void GOTPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
// Use map so all pointers to same symbol use same GOT entry.
llvm::DenseMap<const Atom*, const DefinedAtom*> targetToGOT;
// Scan all references in all atoms.
for(const DefinedAtom *atom : mergedFile.defined()) {
for (const DefinedAtom *atom : mergedFile->defined()) {
for (const Reference *ref : *atom) {
// Look at instructions accessing the GOT.
bool canBypassGOT;
@ -102,7 +102,7 @@ void GOTPass::perform(MutableFile &mergedFile) {
// add all created GOT Atoms to master file
for (auto &it : targetToGOT) {
mergedFile.addAtom(*it.second);
mergedFile->addAtom(*it.second);
}
}
}

View File

@ -1,4 +1,4 @@
//===- Passes/LayoutPass.cpp - Layout atoms -------------------------------===//
//===--Passes/LayoutPass.cpp - Layout atoms -------------------------------===//
//
// The LLVM Linker
//
@ -6,7 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "LayoutPass"
@ -534,9 +533,9 @@ void LayoutPass::checkFollowonChain(MutableFile::DefinedAtomRange &range) {
#endif // #ifndef NDEBUG
/// Perform the actual pass
void LayoutPass::perform(MutableFile &mergedFile) {
void LayoutPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
ScopedTask task(getDefaultDomain(), "LayoutPass");
MutableFile::DefinedAtomRange atomRange = mergedFile.definedAtoms();
MutableFile::DefinedAtomRange atomRange = mergedFile->definedAtoms();
// Build follow on tables
buildFollowOnTable(atomRange);

View File

@ -0,0 +1,44 @@
//===--Passes/RoundTripNativePass.cpp - Write Native file/Read it back-----===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "RoundTripNativePass"
#include "lld/Core/Instrumentation.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/ReaderWriter/Simple.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/Support/Path.h"
using namespace lld;
/// Perform the actual pass
void RoundTripNativePass::perform(std::unique_ptr<MutableFile> &mergedFile) {
ScopedTask task(getDefaultDomain(), "RoundTripNativePass");
std::unique_ptr<Writer> nativeWriter = createWriterNative(_context);
SmallString<128> tmpNativeFile;
// Separate the directory from the filename
StringRef outFile = llvm::sys::path::filename(_context.outputPath());
if (llvm::sys::fs::createTemporaryFile(outFile, "native", tmpNativeFile))
return;
// The file that is written would be kept around if there is a problem
// writing to the file or when reading atoms back from the file.
nativeWriter->writeFile(*mergedFile, tmpNativeFile.str());
llvm::OwningPtr<llvm::MemoryBuffer> buff;
if (llvm::MemoryBuffer::getFileOrSTDIN(tmpNativeFile.str(), buff))
return;
std::unique_ptr<MemoryBuffer> mb(buff.take());
_context.getNativeReader().parseFile(mb, _nativeFile);
mergedFile.reset(new FileToMutable(_context, *_nativeFile[0].get()));
llvm::sys::fs::remove(tmpNativeFile.str());
}

View File

@ -0,0 +1,43 @@
//===--Passes/RoundTripYAMLPass.cpp - Write YAML file/Read it back---------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "RoundTripYAMLPass"
#include "lld/Core/Instrumentation.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "lld/ReaderWriter/Simple.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/Support/Path.h"
using namespace lld;
/// Perform the actual pass
void RoundTripYAMLPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
ScopedTask task(getDefaultDomain(), "RoundTripYAMLPass");
std::unique_ptr<Writer> yamlWriter = createWriterYAML(_context);
SmallString<128> tmpYAMLFile;
// Separate the directory from the filename
StringRef outFile = llvm::sys::path::filename(_context.outputPath());
if (llvm::sys::fs::createTemporaryFile(outFile, "yaml", tmpYAMLFile))
return;
// The file that is written would be kept around if there is a problem
// writing to the file or when reading atoms back from the file.
yamlWriter->writeFile(*mergedFile, tmpYAMLFile.str());
llvm::OwningPtr<llvm::MemoryBuffer> buff;
if (llvm::MemoryBuffer::getFileOrSTDIN(tmpYAMLFile.str(), buff))
return;
std::unique_ptr<MemoryBuffer> mb(buff.take());
_context.getYAMLReader().parseFile(mb, _yamlFile);
mergedFile.reset(new FileToMutable(_context, *_yamlFile[0].get()));
llvm::sys::fs::remove(tmpYAMLFile.str());
}

View File

@ -23,13 +23,13 @@
namespace lld {
void StubsPass::perform(MutableFile &mergedFile) {
void StubsPass::perform(std::unique_ptr<MutableFile> &mergedFile) {
// Skip this pass if output format uses text relocations instead of stubs.
if ( ! this->noTextRelocs() )
return;
// Scan all references in all atoms.
for(const DefinedAtom *atom : mergedFile.defined()) {
for (const DefinedAtom *atom : mergedFile->defined()) {
for (const Reference *ref : *atom) {
// Look at call-sites.
if (this->isCallSite(ref->kind()) ) {
@ -61,6 +61,6 @@ void StubsPass::perform(MutableFile &mergedFile) {
}
// Add all created stubs and support Atoms.
this->addStubAtoms(mergedFile);
this->addStubAtoms(*mergedFile);
}
}

View File

@ -12,6 +12,9 @@
#include "lld/Core/Pass.h"
#include "lld/Core/PassManager.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "lld/ReaderWriter/Simple.h"
#include "llvm/ADT/ArrayRef.h"
@ -149,10 +152,10 @@ private:
uint32_t _ordinal;
};
class TestingPassFile : public MutableFile {
class TestingPassFile : public SimpleFile {
public:
TestingPassFile(const LinkingContext &ctx)
: MutableFile(ctx, "Testing pass") {}
: SimpleFile(ctx, "Testing pass") {}
virtual void addAtom(const Atom &atom) {
if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom))
@ -277,7 +280,7 @@ bool CoreLinkingContext::validateImpl(raw_ostream &) {
return true;
}
void CoreLinkingContext::addPasses(PassManager &pm) const {
void CoreLinkingContext::addPasses(PassManager &pm) {
for (StringRef name : _passNames) {
if (name.equals("layout"))
pm.add(std::unique_ptr<Pass>((new LayoutPass())));
@ -288,6 +291,10 @@ void CoreLinkingContext::addPasses(PassManager &pm) const {
else
llvm_unreachable("bad pass name");
}
#ifndef NDEBUG
pm.add(std::unique_ptr<Pass>(new RoundTripYAMLPass(*this)));
pm.add(std::unique_ptr<Pass>(new RoundTripNativePass(*this)));
#endif
}
Writer &CoreLinkingContext::writer() const { return *_writer; }

View File

@ -13,8 +13,8 @@
namespace lld {
namespace elf {
void ArrayOrderPass::perform(MutableFile &f) {
auto definedAtoms = f.definedAtoms();
void ArrayOrderPass::perform(std::unique_ptr<MutableFile> &f) {
auto definedAtoms = f->definedAtoms();
std::stable_sort(definedAtoms.begin(), definedAtoms.end(),
[](const DefinedAtom *left, const DefinedAtom *right) {
if (left->sectionChoice() != DefinedAtom::sectionCustomRequired ||

View File

@ -18,7 +18,7 @@ namespace elf {
class ArrayOrderPass : public Pass {
public:
ArrayOrderPass() : Pass() {}
virtual void perform(MutableFile &mergedFile) LLVM_OVERRIDE;
virtual void perform(std::unique_ptr<MutableFile> &mergedFile) LLVM_OVERRIDE;
};
}
}

View File

@ -16,6 +16,8 @@
#include "lld/Core/Instrumentation.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "lld/ReaderWriter/ReaderLinkerScript.h"
#include "llvm/ADT/Triple.h"
@ -52,10 +54,14 @@ bool ELFLinkingContext::isLittleEndian() const {
return true;
}
void ELFLinkingContext::addPasses(PassManager &pm) const {
void ELFLinkingContext::addPasses(PassManager &pm) {
if (_runLayoutPass)
pm.add(std::unique_ptr<Pass>(new LayoutPass()));
pm.add(std::unique_ptr<Pass>(new elf::ArrayOrderPass()));
#ifndef NDEBUG
pm.add(std::unique_ptr<Pass>(new RoundTripYAMLPass(*this)));
pm.add(std::unique_ptr<Pass>(new RoundTripNativePass(*this)));
#endif
}
uint16_t ELFLinkingContext::getOutputMachine() const {

View File

@ -29,7 +29,7 @@ public:
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
virtual void addPasses(PassManager &) const;
virtual void addPasses(PassManager &);
virtual bool isDynamicRelocation(const DefinedAtom &,
const Reference &r) const {

View File

@ -157,9 +157,9 @@ public:
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
virtual void perform(MutableFile &mf) {
virtual void perform(std::unique_ptr<MutableFile> &mf) {
// Process all references.
for (const auto &atom : mf.defined())
for (const auto &atom : mf->defined())
for (const auto &ref : *atom)
handleReference(*atom, *ref);
@ -167,23 +167,23 @@ public:
uint64_t ordinal = 0;
if (_PLT0) {
_PLT0->setOrdinal(ordinal++);
mf.addAtom(*_PLT0);
mf->addAtom(*_PLT0);
}
for (auto &plt : _pltVector) {
plt->setOrdinal(ordinal++);
mf.addAtom(*plt);
mf->addAtom(*plt);
}
if (_null) {
_null->setOrdinal(ordinal++);
mf.addAtom(*_null);
mf->addAtom(*_null);
}
if (_got0) {
_got0->setOrdinal(ordinal++);
mf.addAtom(*_got0);
mf->addAtom(*_got0);
}
for (auto &got : _gotVector) {
got->setOrdinal(ordinal++);
mf.addAtom(*got);
mf->addAtom(*got);
}
}
@ -293,7 +293,7 @@ public:
};
} // end anonymous namespace
void elf::HexagonLinkingContext::addPasses(PassManager &pm) const {
void elf::HexagonLinkingContext::addPasses(PassManager &pm) {
if (isDynamic())
pm.add(std::unique_ptr<Pass>(new DynamicGOTPLTPass(*this)));
ELFLinkingContext::addPasses(pm);

View File

@ -21,7 +21,7 @@ using namespace lld;
ErrorOr<Reference::Kind>
elf::PPCLinkingContext::relocKindFromString(StringRef str) const {
int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_PPC_NONE)
LLD_CASE(R_PPC_ADDR32).Default(-1);
LLD_CASE(R_PPC_ADDR32) LLD_CASE(R_PPC_REL24).Default(-1);
if (ret == -1)
return make_error_code(YamlReaderError::illegal_value);
@ -39,6 +39,7 @@ elf::PPCLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
switch (kind) {
LLD_CASE(R_PPC_NONE)
LLD_CASE(R_PPC_ADDR32)
LLD_CASE(R_PPC_REL24)
}
return make_error_code(YamlReaderError::illegal_value);

View File

@ -90,8 +90,7 @@ private:
} // end anon namespace
void elf::X86_64LinkingContext::addPasses(PassManager &pm) const {
void elf::X86_64LinkingContext::addPasses(PassManager &pm) {
auto pass = createX86_64RelocationPass(*this);
if (pass)
pm.add(std::move(pass));

View File

@ -33,7 +33,7 @@ public:
: ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
new X86_64TargetHandler(*this))) {}
virtual void addPasses(PassManager &) const;
virtual void addPasses(PassManager &);
virtual uint64_t getBaseAddress() const {
if (_baseAddress == 0)

View File

@ -217,10 +217,10 @@ public:
///
/// After all references are handled, the atoms created during that are all
/// added to mf.
virtual void perform(MutableFile &mf) {
virtual void perform(std::unique_ptr<MutableFile> &mf) {
ScopedTask task(getDefaultDomain(), "X86-64 GOT/PLT Pass");
// Process all references.
for (const auto &atom : mf.defined())
for (const auto &atom : mf->defined())
for (const auto &ref : *atom)
handleReference(*atom, *ref);
@ -228,29 +228,29 @@ public:
uint64_t ordinal = 0;
if (_PLT0) {
_PLT0->setOrdinal(ordinal++);
mf.addAtom(*_PLT0);
mf->addAtom(*_PLT0);
}
for (auto &plt : _pltVector) {
plt->setOrdinal(ordinal++);
mf.addAtom(*plt);
mf->addAtom(*plt);
}
if (_null) {
_null->setOrdinal(ordinal++);
mf.addAtom(*_null);
mf->addAtom(*_null);
}
if (_PLT0) {
_got0->setOrdinal(ordinal++);
_got1->setOrdinal(ordinal++);
mf.addAtom(*_got0);
mf.addAtom(*_got1);
mf->addAtom(*_got0);
mf->addAtom(*_got1);
}
for (auto &got : _gotVector) {
got->setOrdinal(ordinal++);
mf.addAtom(*got);
mf->addAtom(*got);
}
for (auto obj : _objectVector) {
obj->setOrdinal(ordinal++);
mf.addAtom(*obj);
mf->addAtom(*obj);
}
}

View File

@ -16,6 +16,8 @@
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
@ -235,10 +237,14 @@ bool MachOLinkingContext::setOS(OS os, StringRef minOSVersion) {
return parsePackedVersion(minOSVersion, _osMinVersion);
}
void MachOLinkingContext::addPasses(PassManager &pm) const {
void MachOLinkingContext::addPasses(PassManager &pm) {
pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
pm.add(std::unique_ptr<Pass>(new LayoutPass()));
#ifndef NDEBUG
pm.add(std::unique_ptr<Pass>(new RoundTripYAMLPass(*this)));
pm.add(std::unique_ptr<Pass>(new RoundTripNativePass(*this)));
#endif
}
Writer &MachOLinkingContext::writer() const {

View File

@ -60,9 +60,9 @@ class GroupedSectionsPass : public lld::Pass {
public:
GroupedSectionsPass() {}
virtual void perform(MutableFile &mergedFile) {
std::map<StringRef, std::vector<COFFDefinedAtom *>> sectionToHeadAtoms(
filterHeadAtoms(mergedFile));
virtual void perform(std::unique_ptr<MutableFile> &mergedFile) {
std::map<StringRef, std::vector<COFFDefinedAtom *> > sectionToHeadAtoms(
filterHeadAtoms(*mergedFile));
std::vector<std::vector<COFFDefinedAtom *>> groupedAtomsList(
groupBySectionName(sectionToHeadAtoms));
for (auto &groupedAtoms : groupedAtomsList)

View File

@ -252,13 +252,13 @@ class IdataPass : public lld::Pass {
public:
IdataPass(const LinkingContext &ctx) : _dummyFile(ctx) {}
virtual void perform(MutableFile &file) {
if (file.sharedLibrary().size() == 0)
virtual void perform(std::unique_ptr<MutableFile> &file) {
if (file->sharedLibrary().size() == 0)
return;
Context context(file, _dummyFile);
Context context(*file, _dummyFile);
map<StringRef, vector<COFFSharedLibraryAtom *> > sharedAtoms =
groupByLoadName(file);
groupByLoadName(*file);
for (auto i : sharedAtoms) {
StringRef loadName = i.first;
vector<COFFSharedLibraryAtom *> &atoms = i.second;

View File

@ -204,7 +204,7 @@ PECOFFLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
return make_error_code(YamlReaderError::illegal_value);
}
void PECOFFLinkingContext::addPasses(PassManager &pm) const {
void PECOFFLinkingContext::addPasses(PassManager &pm) {
pm.add(std::unique_ptr<Pass>(new pecoff::GroupedSectionsPass()));
pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass(*this)));
pm.add(std::unique_ptr<Pass>(new LayoutPass()));

View File

@ -0,0 +1,9 @@
# This tests the functionality of the RoundTrip Passes and verifies
# that the atoms belong to the native file after the passes finish
RUN: lld -flavor gnu -target x86_64 %p/Inputs/foo.o.x86-64 --noinhibit-exec \
RUN: --output-filetype=yaml -o %t1
RUN: FileCheck %s < %t1
CHECK:path:{{.*}}.native