forked from OSchip/llvm-project
[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:
parent
3aca58f135
commit
2bc24928d3
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -108,6 +108,6 @@ ErrorOr<File &> LinkingContext::nextFile() {
|
|||
}
|
||||
}
|
||||
|
||||
void LinkingContext::addPasses(PassManager &pm) const {}
|
||||
void LinkingContext::addPasses(PassManager &pm) {}
|
||||
|
||||
} // end namespace lld
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -480,7 +480,7 @@ bool Resolver::resolve() {
|
|||
}
|
||||
this->removeCoalescedAwayAtoms();
|
||||
this->linkTimeOptimize();
|
||||
this->_result.addAtoms(_atoms);
|
||||
this->_result->addAtoms(_atoms);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2,4 +2,8 @@ add_lld_library(lldPasses
|
|||
GOTPass.cpp
|
||||
StubsPass.cpp
|
||||
LayoutPass.cpp
|
||||
RoundTripNativePass.cpp
|
||||
RoundTripYAMLPass.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(lldPasses lldReaderWriter)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -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());
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue