diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp
new file mode 100644
index 0000000..2318cd8
--- /dev/null
+++ b/lld/lib/ReaderWriter/ELF/Writer.cpp
@@ -0,0 +1,341 @@
+//===- lib/ReaderWriter/ELF/WriterELF.cpp ---------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/ReaderWriter/Writer.h"
+
+#include "DefaultLayout.h"
+#include "ExecutableAtoms.h"
+
+#include "lld/ReaderWriter/ELFTargetInfo.h"
+
+using namespace llvm;
+using namespace llvm::object;
+namespace lld {
+namespace elf {
+template<class ELFT>
+class ExecutableWriter;
+
+//===----------------------------------------------------------------------===//
+//  ExecutableWriter Class
+//===----------------------------------------------------------------------===//
+template<class ELFT>
+class ExecutableWriter : public ELFWriter {
+public:
+  typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
+  typedef Elf_Sym_Impl<ELFT> Elf_Sym;
+
+  ExecutableWriter(const ELFTargetInfo &ti);
+
+private:
+  // build the sections that need to be created
+  void buildChunks(const File &file);
+  virtual error_code writeFile(const File &File, StringRef path);
+  void buildAtomToAddressMap();
+  void buildSymbolTable ();
+  void buildSectionHeaderTable();
+  void assignSectionsWithNoSegments();
+  void addAbsoluteUndefinedSymbols(const File &File);
+  void addDefaultAtoms();
+  void addFiles(InputFiles&);
+  void finalizeDefaultAtomValues();
+
+  uint64_t addressOfAtom(const Atom *atom) {
+    return _atomToAddressMap[atom];
+  }
+
+  KindHandler *kindHandler() { return _referenceKindHandler.get(); }
+
+  void createDefaultSections();
+
+  const ELFTargetInfo &_targetInfo;
+
+  typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
+  std::unique_ptr<KindHandler> _referenceKindHandler;
+  AtomToAddress _atomToAddressMap;
+  llvm::BumpPtrAllocator _chunkAllocate;
+  DefaultLayout<ELFT> *_layout;
+  Header<ELFT> *_Header;
+  ProgramHeader<ELFT> *_programHeader;
+  SymbolTable<ELFT> * _symtab;
+  StringTable<ELFT> *_strtab;
+  StringTable<ELFT> *_shstrtab;
+  SectionHeader<ELFT> *_shdrtab;
+  CRuntimeFile<ELFT> _runtimeFile;
+};
+
+//===----------------------------------------------------------------------===//
+//  ExecutableWriter
+//===----------------------------------------------------------------------===//
+template<class ELFT>
+ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
+  : _targetInfo(ti)
+  , _referenceKindHandler(KindHandler::makeHandler(
+                              ti.getTriple().getArch(), ti.isLittleEndian()))
+  , _runtimeFile(ti) {
+  _layout = new DefaultLayout<ELFT>(ti);
+}
+
+template<class ELFT>
+void ExecutableWriter<ELFT>::buildChunks(const File &file){
+  for (const DefinedAtom *definedAtom : file.defined() ) {
+    _layout->addAtom(definedAtom);
+  }
+  /// Add all the absolute atoms to the layout
+  for (const AbsoluteAtom *absoluteAtom : file.absolute()) {
+    _layout->addAtom(absoluteAtom);
+  }
+}
+
+template<class ELFT>
+void ExecutableWriter<ELFT>::buildSymbolTable () {
+  for (auto sec : _layout->sections())
+    if (auto section = dyn_cast<Section<ELFT>>(sec))
+      for (const auto &atom : section->atoms())
+        _symtab->addSymbol(atom._atom, section->ordinal(), atom._virtualAddr);
+}
+
+template<class ELFT>
+void
+ExecutableWriter<ELFT>::addAbsoluteUndefinedSymbols(const File &file) {
+  // add all the absolute symbols that the layout contains to the output symbol
+  // table
+  for (auto &atom : _layout->absoluteAtoms())
+    _symtab->addSymbol(atom.absoluteAtom(), ELF::SHN_ABS, atom.value());
+  for (const UndefinedAtom *a : file.undefined())
+    _symtab->addSymbol(a, ELF::SHN_UNDEF);
+}
+
+template<class ELFT>
+void ExecutableWriter<ELFT>::buildAtomToAddressMap () {
+  for (auto sec : _layout->sections())
+    if (auto section = dyn_cast<Section<ELFT>>(sec))
+      for (const auto &atom : section->atoms())
+        _atomToAddressMap[atom._atom] = atom._virtualAddr;
+  // build the atomToAddressMap that contains absolute symbols too
+  for (auto &atom : _layout->absoluteAtoms())
+    _atomToAddressMap[atom.absoluteAtom()] = atom.value();
+}
+
+template<class ELFT>
+void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
+  for (auto mergedSec : _layout->mergedSections()) {
+    if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
+      continue;
+    if (mergedSec->hasSegment())
+      _shdrtab->appendSection(mergedSec);
+  }
+}
+
+template<class ELFT>
+void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
+  for (auto mergedSec : _layout->mergedSections()) {
+    if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
+      continue;
+    if (!mergedSec->hasSegment())
+      _shdrtab->appendSection(mergedSec);
+  }
+  _layout->assignOffsetsForMiscSections();
+  for (auto sec : _layout->sections())
+    if (auto section = dyn_cast<Section<ELFT>>(sec))
+      if (!DefaultLayout<ELFT>::hasOutputSegment(section))
+        _shdrtab->updateSection(section);
+}
+
+/// \brief Add absolute symbols by default. These are linker added
+/// absolute symbols
+template<class ELFT>
+void ExecutableWriter<ELFT>::addDefaultAtoms() {
+  _runtimeFile.addUndefinedAtom(_targetInfo.getEntry());
+  _runtimeFile.addAbsoluteAtom("__bss_start");
+  _runtimeFile.addAbsoluteAtom("__bss_end");
+  _runtimeFile.addAbsoluteAtom("_end");
+  _runtimeFile.addAbsoluteAtom("end");
+  _runtimeFile.addAbsoluteAtom("__init_array_start");
+  _runtimeFile.addAbsoluteAtom("__init_array_end");
+  _runtimeFile.addAbsoluteAtom("__rela_iplt_start");
+  _runtimeFile.addAbsoluteAtom("__rela_iplt_end");
+}
+
+/// \brief Hook in lld to add CRuntime file 
+template<class ELFT>
+void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
+  addDefaultAtoms();
+  inputFiles.prependFile(_runtimeFile);
+}
+
+/// Finalize the value of all the absolute symbols that we 
+/// created
+template<class ELFT>
+void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
+  auto bssStartAtomIter = _layout->findAbsoluteAtom("__bss_start");
+  auto bssEndAtomIter = _layout->findAbsoluteAtom("__bss_end");
+  auto underScoreEndAtomIter = _layout->findAbsoluteAtom("_end");
+  auto endAtomIter = _layout->findAbsoluteAtom("end");
+  auto initArrayStartIter = _layout->findAbsoluteAtom("__init_array_start");
+  auto initArrayEndIter = _layout->findAbsoluteAtom("__init_array_end");
+  auto realIpltStartIter = _layout->findAbsoluteAtom("__rela_iplt_start");
+  auto realIpltEndIter = _layout->findAbsoluteAtom("__rela_iplt_end");
+
+  auto startEnd = [&](typename DefaultLayout<ELFT>::AbsoluteAtomIterT start,
+                      typename DefaultLayout<ELFT>::AbsoluteAtomIterT end,
+                      StringRef sec) -> void {
+    auto section = _layout->findOutputSection(sec);
+    if (section) {
+      start->setValue(section->virtualAddr());
+      end->setValue(section->virtualAddr() + section->memSize());
+    } else {
+      start->setValue(0);
+      end->setValue(0);
+    }
+  };
+
+  startEnd(initArrayStartIter, initArrayEndIter, ".init_array");
+  startEnd(realIpltStartIter, realIpltEndIter, ".rela.plt");
+
+  assert(!(bssStartAtomIter == _layout->absoluteAtoms().end() ||
+           bssEndAtomIter == _layout->absoluteAtoms().end() ||
+           underScoreEndAtomIter == _layout->absoluteAtoms().end() ||
+           endAtomIter == _layout->absoluteAtoms().end()) &&
+         "Unable to find the absolute atoms that have been added by lld");
+
+  auto phe = _programHeader->findProgramHeader(
+      llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
+
+  assert(!(phe == _programHeader->end()) &&
+         "Can't find a data segment in the program header!");
+
+  bssStartAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_filesz);
+  bssEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
+  underScoreEndAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
+  endAtomIter->setValue((*phe)->p_vaddr + (*phe)->p_memsz);
+}
+
+template<class ELFT>
+error_code
+ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
+  buildChunks(file);
+  // Create the default sections like the symbol table, string table, and the
+  // section string table
+  createDefaultSections();
+
+  // Set the Layout
+  _layout->assignSectionsToSegments();
+  _layout->assignFileOffsets();
+  _layout->assignVirtualAddress();
+
+  // Finalize the default value of symbols that the linker adds
+  finalizeDefaultAtomValues();
+
+  // Build the Atom To Address map for applying relocations
+  buildAtomToAddressMap();
+
+  // Create symbol table and section string table
+  buildSymbolTable();
+
+  // add other symbols
+  addAbsoluteUndefinedSymbols(file);
+
+  // Finalize the layout by calling the finalize() functions
+  _layout->finalize();
+
+  // build Section Header table
+  buildSectionHeaderTable();
+
+  // assign Offsets and virtual addresses
+  // for sections with no segments
+  assignSectionsWithNoSegments();
+
+  uint64_t totalSize = _shdrtab->fileOffset() + _shdrtab->fileSize();
+
+  OwningPtr<FileOutputBuffer> buffer;
+  error_code ec = FileOutputBuffer::create(path,
+                                           totalSize, buffer,
+                                           FileOutputBuffer::F_executable);
+  if (ec)
+    return ec;
+
+  _Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
+                                                            : ELF::ELFCLASS32);
+  _Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
+                                    ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
+  _Header->e_ident(ELF::EI_VERSION, 1);
+  _Header->e_ident(ELF::EI_OSABI, 0);
+  _Header->e_type(_targetInfo.getOutputType());
+  _Header->e_machine(_targetInfo.getOutputMachine());
+  _Header->e_version(1);
+  _Header->e_entry(0ULL);
+  _Header->e_phoff(_programHeader->fileOffset());
+  _Header->e_shoff(_shdrtab->fileOffset());
+  _Header->e_phentsize(_programHeader->entsize());
+  _Header->e_phnum(_programHeader->numHeaders());
+  _Header->e_shentsize(_shdrtab->entsize());
+  _Header->e_shnum(_shdrtab->numHeaders());
+  _Header->e_shstrndx(_shstrtab->ordinal());
+  uint64_t virtualAddr = 0;
+  _layout->findAtomAddrByName(_targetInfo.getEntry(), virtualAddr);
+  _Header->e_entry(virtualAddr);
+
+  // HACK: We have to write out the header and program header here even though
+  // they are a member of a segment because only sections are written in the
+  // following loop.
+  _Header->write(this, *buffer);
+  _programHeader->write(this, *buffer);
+
+  for (auto section : _layout->sections())
+    section->write(this, *buffer);
+
+  return buffer->commit();
+}
+
+template<class ELFT>
+void ExecutableWriter<ELFT>::createDefaultSections() {
+  _Header = new Header<ELFT>(_targetInfo);
+  _programHeader = new ProgramHeader<ELFT>(_targetInfo);
+  _layout->setHeader(_Header);
+  _layout->setProgramHeader(_programHeader);
+
+  _symtab = new SymbolTable<
+      ELFT>(_targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE);
+  _strtab = new StringTable<
+      ELFT>(_targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE);
+  _shstrtab = new StringTable<ELFT>(
+      _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS);
+  _shdrtab = new SectionHeader<
+      ELFT>(_targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS);
+  _layout->addSection(_symtab);
+  _layout->addSection(_strtab);
+  _layout->addSection(_shstrtab);
+  _shdrtab->setStringSection(_shstrtab);
+  _symtab->setStringSection(_strtab);
+  _layout->addSection(_shdrtab);
+}
+} // namespace elf
+
+std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
+  using llvm::object::ELFType;
+  // Set the default layout to be the static executable layout
+  // We would set the layout to a dynamic executable layout
+  // if we came across any shared libraries in the process
+
+  if (!TI.is64Bits() && TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ExecutableWriter<ELFType<support::little, 4, false>>(TI));
+  else if (TI.is64Bits() && TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ExecutableWriter<ELFType<support::little, 8, true>>(TI));
+  else if (!TI.is64Bits() && !TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ExecutableWriter<ELFType<support::big, 4, false>>(TI));
+  else if (TI.is64Bits() && !TI.isLittleEndian())
+    return std::unique_ptr<Writer>(new
+        elf::ExecutableWriter<ELFType<support::big, 8, true>>(TI));
+
+  llvm_unreachable("Invalid Options!");
+}
+} // namespace lld
