diff --git a/lld/include/lld/Core/LinkingContext.h b/lld/include/lld/Core/LinkingContext.h
index 255e65954863..c617a22d6b26 100644
--- a/lld/include/lld/Core/LinkingContext.h
+++ b/lld/include/lld/Core/LinkingContext.h
@@ -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.
   ///
diff --git a/lld/include/lld/Core/Pass.h b/lld/include/lld/Core/Pass.h
index 147162a66747..6d4b6a5cc268 100644
--- a/lld/include/lld/Core/Pass.h
+++ b/lld/include/lld/Core/Pass.h
@@ -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
diff --git a/lld/include/lld/Core/PassManager.h b/lld/include/lld/Core/PassManager.h
index 98a22512f262..2ed7a84db400 100644
--- a/lld/include/lld/Core/PassManager.h
+++ b/lld/include/lld/Core/PassManager.h
@@ -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.
diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h
index 7ffd3523b507..bb19f14e2507 100644
--- a/lld/include/lld/Core/Resolver.h
+++ b/lld/include/lld/Core/Resolver.h
@@ -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;
 };
diff --git a/lld/include/lld/Passes/LayoutPass.h b/lld/include/lld/Passes/LayoutPass.h
index 39a9b49f2085..bbd277f488f7 100644
--- a/lld/include/lld/Passes/LayoutPass.h
+++ b/lld/include/lld/Passes/LayoutPass.h
@@ -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() {}
 
diff --git a/lld/include/lld/Passes/RoundTripNativePass.h b/lld/include/lld/Passes/RoundTripNativePass.h
new file mode 100644
index 000000000000..0d562ed58e1b
--- /dev/null
+++ b/lld/include/lld/Passes/RoundTripNativePass.h
@@ -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
diff --git a/lld/include/lld/Passes/RoundTripYAMLPass.h b/lld/include/lld/Passes/RoundTripYAMLPass.h
new file mode 100644
index 000000000000..772bc79455eb
--- /dev/null
+++ b/lld/include/lld/Passes/RoundTripYAMLPass.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
diff --git a/lld/include/lld/ReaderWriter/CoreLinkingContext.h b/lld/include/lld/ReaderWriter/CoreLinkingContext.h
index 9f6fcdd05745..3b74d3ab8fb1 100644
--- a/lld/include/lld/ReaderWriter/CoreLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/CoreLinkingContext.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;
 
diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h
index 9a244300ccda..458ded2a0e06 100644
--- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h
@@ -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; }
diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h
index c214ba72af62..6af1242c8786 100644
--- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -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);
diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
index 9fb39e1c1f6e..c251cdcce043 100644
--- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
@@ -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;
diff --git a/lld/include/lld/ReaderWriter/Simple.h b/lld/include/lld/ReaderWriter/Simple.h
index c7d4bef39191..6baa4265a2be 100644
--- a/lld/include/lld/ReaderWriter/Simple.h
+++ b/lld/include/lld/ReaderWriter/Simple.h
@@ -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,
diff --git a/lld/lib/Core/LinkingContext.cpp b/lld/lib/Core/LinkingContext.cpp
index 9ae4f51da004..873d1d61c8be 100644
--- a/lld/lib/Core/LinkingContext.cpp
+++ b/lld/lib/Core/LinkingContext.cpp
@@ -108,6 +108,6 @@ ErrorOr<File &> LinkingContext::nextFile() {
   }
 }
 
-void LinkingContext::addPasses(PassManager &pm) const {}
+void LinkingContext::addPasses(PassManager &pm) {}
 
 } // end namespace lld
diff --git a/lld/lib/Core/PassManager.cpp b/lld/lib/Core/PassManager.cpp
index 238fb0a6b642..715a5fbda11e 100644
--- a/lld/lib/Core/PassManager.cpp
+++ b/lld/lib/Core/PassManager.cpp
@@ -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);
   }
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index 3a34cd3fe3fd..3af0c5cba717 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -480,7 +480,7 @@ bool Resolver::resolve() {
   }
   this->removeCoalescedAwayAtoms();
   this->linkTimeOptimize();
-  this->_result.addAtoms(_atoms);
+  this->_result->addAtoms(_atoms);
   return true;
 }
 
diff --git a/lld/lib/Driver/Driver.cpp b/lld/lib/Driver/Driver.cpp
index 6f0f4ecdde60..1569d69384ba 100644
--- a/lld/lib/Driver/Driver.cpp
+++ b/lld/lib/Driver/Driver.cpp
@@ -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;
diff --git a/lld/lib/Passes/CMakeLists.txt b/lld/lib/Passes/CMakeLists.txt
index 10759023a381..3cec05afec57 100644
--- a/lld/lib/Passes/CMakeLists.txt
+++ b/lld/lib/Passes/CMakeLists.txt
@@ -2,4 +2,8 @@ add_lld_library(lldPasses
   GOTPass.cpp
   StubsPass.cpp
   LayoutPass.cpp
+  RoundTripNativePass.cpp
+  RoundTripYAMLPass.cpp 
   )
+
+target_link_libraries(lldPasses lldReaderWriter)
diff --git a/lld/lib/Passes/GOTPass.cpp b/lld/lib/Passes/GOTPass.cpp
index 1bb6e4cee4ac..b9a6f73e5b13 100644
--- a/lld/lib/Passes/GOTPass.cpp
+++ b/lld/lib/Passes/GOTPass.cpp
@@ -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);
   }
 }
 }
diff --git a/lld/lib/Passes/LayoutPass.cpp b/lld/lib/Passes/LayoutPass.cpp
index b00887d6fd4f..77a484eaf0a2 100644
--- a/lld/lib/Passes/LayoutPass.cpp
+++ b/lld/lib/Passes/LayoutPass.cpp
@@ -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);
diff --git a/lld/lib/Passes/RoundTripNativePass.cpp b/lld/lib/Passes/RoundTripNativePass.cpp
new file mode 100644
index 000000000000..f78ad7bb5cba
--- /dev/null
+++ b/lld/lib/Passes/RoundTripNativePass.cpp
@@ -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());
+}
diff --git a/lld/lib/Passes/RoundTripYAMLPass.cpp b/lld/lib/Passes/RoundTripYAMLPass.cpp
new file mode 100644
index 000000000000..38012cd13087
--- /dev/null
+++ b/lld/lib/Passes/RoundTripYAMLPass.cpp
@@ -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());
+}
diff --git a/lld/lib/Passes/StubsPass.cpp b/lld/lib/Passes/StubsPass.cpp
index ef3870580cb4..b75f2316bcbd 100644
--- a/lld/lib/Passes/StubsPass.cpp
+++ b/lld/lib/Passes/StubsPass.cpp
@@ -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);
 }
 }
diff --git a/lld/lib/ReaderWriter/CoreLinkingContext.cpp b/lld/lib/ReaderWriter/CoreLinkingContext.cpp
index ec8962bbce2c..3b83d297e48e 100644
--- a/lld/lib/ReaderWriter/CoreLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/CoreLinkingContext.cpp
@@ -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; }
diff --git a/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp b/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
index 8a721367b9bb..be9cd4b167d9 100644
--- a/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
@@ -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 ||
diff --git a/lld/lib/ReaderWriter/ELF/ArrayOrderPass.h b/lld/lib/ReaderWriter/ELF/ArrayOrderPass.h
index 8d40c44fc88e..12cce561fbf8 100644
--- a/lld/lib/ReaderWriter/ELF/ArrayOrderPass.h
+++ b/lld/lib/ReaderWriter/ELF/ArrayOrderPass.h
@@ -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;
 };
 }
 }
diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
index 6d6f6a757942..827d73d2abe0 100644
--- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
@@ -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 {
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
index ea3b9c3b5137..90379503056d 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
@@ -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 {
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
index 7c918877fc27..761471cb06a6 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
@@ -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);
diff --git a/lld/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp
index 24c38b1e9d0f..02f6c21cc179 100644
--- a/lld/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.cpp
@@ -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);
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
index 5b3a920547c7..a5b27e656e50 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
@@ -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));
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
index c7ca812d1da1..7877869bf365 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
@@ -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)
diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
index a06b48746ba7..3ce6b0873e3b 100644
--- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp
@@ -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);
     }
   }
 
diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index 69219e5b1684..b79fd39a8bcd 100644
--- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -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 {
diff --git a/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h b/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h
index f8836061a07e..e3186031b87c 100644
--- a/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h
+++ b/lld/lib/ReaderWriter/PECOFF/GroupedSectionsPass.h
@@ -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)
diff --git a/lld/lib/ReaderWriter/PECOFF/IdataPass.h b/lld/lib/ReaderWriter/PECOFF/IdataPass.h
index d13a718cb47b..c3f7e9761558 100644
--- a/lld/lib/ReaderWriter/PECOFF/IdataPass.h
+++ b/lld/lib/ReaderWriter/PECOFF/IdataPass.h
@@ -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;
diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
index 065a2c071662..252c91cc53a5 100644
--- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
@@ -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()));
diff --git a/lld/test/elf/roundtrip.test b/lld/test/elf/roundtrip.test
new file mode 100644
index 000000000000..2bb25db563f5
--- /dev/null
+++ b/lld/test/elf/roundtrip.test
@@ -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
+