diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
new file mode 100644
index 0000000..35320f5
--- /dev/null
+++ b/compiler/elf_builder.h
@@ -0,0 +1,1069 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_COMPILER_ELF_BUILDER_H_
+#define ART_COMPILER_ELF_BUILDER_H_
+
+#include "buffered_output_stream.h"
+#include "elf_utils.h"
+#include "file_output_stream.h"
+#include "instruction_set.h"
+
+namespace art {
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
+class ElfSectionBuilder {
+ public:
+  ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
+                    const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link, Elf_Word info,
+                    Elf_Word align, Elf_Word entsize) : name_(sec_name), link_(link) {
+    memset(&section_, 0, sizeof(section_));
+    section_.sh_type = type;
+    section_.sh_flags = flags;
+    section_.sh_info = info;
+    section_.sh_addralign = align;
+    section_.sh_entsize = entsize;
+  }
+
+  virtual ~ElfSectionBuilder() {}
+
+  Elf_Shdr section_;
+  Elf_Word section_index_ = 0;
+
+  Elf_Word GetLink() {
+    return (link_) ? link_->section_index_ : 0;
+  }
+
+  const std::string name_;
+
+ protected:
+  const ElfSectionBuilder* link_;
+};
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Dyn, typename Elf_Shdr>
+class ElfDynamicBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+ public:
+  void AddDynamicTag(Elf_Sword tag, Elf_Word d_un) {
+    if (tag == DT_NULL) {
+      return;
+    }
+    dynamics_.push_back({nullptr, tag, d_un});
+  }
+
+  void AddDynamicTag(Elf_Sword tag, Elf_Word d_un,
+                     ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section) {
+    if (tag == DT_NULL) {
+      return;
+    }
+    dynamics_.push_back({section, tag, d_un});
+  }
+
+  ElfDynamicBuilder(const std::string& sec_name,
+                    ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *link)
+  : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC,
+                                                     link, 0, kPageSize, sizeof(Elf_Dyn)) {}
+  ~ElfDynamicBuilder() {}
+
+  Elf_Word GetSize() {
+    // Add 1 for the DT_NULL, 1 for DT_STRSZ, and 1 for DT_SONAME. All of
+    // these must be added when we actually put the file together because
+    // their values are very dependent on state.
+    return dynamics_.size() + 3;
+  }
+
+  // Create the actual dynamic vector. strsz should be the size of the .dynstr
+  // table and soname_off should be the offset of the soname in .dynstr.
+  // Since niether can be found prior to final layout we will wait until here
+  // to add them.
+  std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname) {
+    std::vector<Elf_Dyn> ret;
+    for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
+      if (it->section_) {
+        // We are adding an address relative to a section.
+        ret.push_back(
+            {it->tag_, {it->off_ + it->section_->section_.sh_addr}});
+      } else {
+        ret.push_back({it->tag_, {it->off_}});
+      }
+    }
+    ret.push_back({DT_STRSZ, {strsz}});
+    ret.push_back({DT_SONAME, {soname}});
+    ret.push_back({DT_NULL, {0}});
+    return ret;
+  }
+
+ protected:
+  struct ElfDynamicState {
+    ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
+    Elf_Sword tag_;
+    Elf_Word off_;
+  };
+  std::vector<ElfDynamicState> dynamics_;
+};
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
+class ElfRawSectionBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+ public:
+  ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
+                       const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* link, Elf_Word info,
+                       Elf_Word align, Elf_Word entsize)
+    : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, link, info, align,
+                                                       entsize) {}
+  ~ElfRawSectionBuilder() {}
+  std::vector<uint8_t>* GetBuffer() { return &buf_; }
+  void SetBuffer(std::vector<uint8_t>&& buf) { buf_ = buf; }
+
+ protected:
+  std::vector<uint8_t> buf_;
+};
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
+class ElfOatSectionBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+ public:
+  ElfOatSectionBuilder(const std::string& sec_name, Elf_Word size, Elf_Word offset,
+                       Elf_Word type, Elf_Word flags)
+    : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, flags, nullptr, 0, kPageSize,
+                                                       0), offset_(offset), size_(size) {}
+  ~ElfOatSectionBuilder() {}
+
+  Elf_Word GetOffset() {
+    return offset_;
+  }
+
+  Elf_Word GetSize() {
+    return size_;
+  }
+
+ protected:
+  // Offset of the content within the file.
+  Elf_Word offset_;
+  // Size of the content within the file.
+  Elf_Word size_;
+};
+
+static inline constexpr uint8_t MakeStInfo(uint8_t binding, uint8_t type) {
+  return ((binding) << 4) + ((type) & 0xf);
+}
+
+// from bionic
+static inline unsigned elfhash(const char *_name) {
+  const unsigned char *name = (const unsigned char *) _name;
+  unsigned h = 0, g;
+
+  while (*name) {
+    h = (h << 4) + *name++;
+    g = h & 0xf0000000;
+    h ^= g;
+    h ^= g >> 24;
+  }
+  return h;
+}
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Sym,
+          typename Elf_Shdr>
+class ElfSymtabBuilder : public ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> {
+ public:
+  // Add a symbol with given name to this symtab. The symbol refers to
+  // 'relative_addr' within the given section and has the given attributes.
+  void AddSymbol(const std::string& name,
+                 const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section,
+                 Elf_Addr addr,
+                 bool is_relative,
+                 Elf_Word size,
+                 uint8_t binding,
+                 uint8_t type,
+                 uint8_t other = 0) {
+    CHECK(section);
+    ElfSymtabBuilder::ElfSymbolState state {name, section, addr, size, is_relative,
+                                            MakeStInfo(binding, type), other, 0};
+    symbols_.push_back(state);
+  }
+
+  ElfSymtabBuilder(const std::string& sec_name, Elf_Word type,
+                   const std::string& str_name, Elf_Word str_type, bool alloc)
+  : ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>(sec_name, type, ((alloc) ? SHF_ALLOC : 0U),
+                                                     &strtab_, 0, sizeof(Elf_Word),
+                                                     sizeof(Elf_Sym)), str_name_(str_name),
+                                                     str_type_(str_type),
+                                                     strtab_(str_name,
+                                                             str_type,
+                                                             ((alloc) ? SHF_ALLOC : 0U),
+                                                             nullptr, 0, 1, 1) {}
+  ~ElfSymtabBuilder() {}
+
+  std::vector<Elf_Word> GenerateHashContents() {
+    // Here is how The ELF hash table works.
+    // There are 3 arrays to worry about.
+    // * The symbol table where the symbol information is.
+    // * The bucket array which is an array of indexes into the symtab and chain.
+    // * The chain array which is also an array of indexes into the symtab and chain.
+    //
+    // Lets say the state is something like this.
+    // +--------+       +--------+      +-----------+
+    // | symtab |       | bucket |      |   chain   |
+    // |  null  |       | 1      |      | STN_UNDEF |
+    // | <sym1> |       | 4      |      | 2         |
+    // | <sym2> |       |        |      | 5         |
+    // | <sym3> |       |        |      | STN_UNDEF |
+    // | <sym4> |       |        |      | 3         |
+    // | <sym5> |       |        |      | STN_UNDEF |
+    // +--------+       +--------+      +-----------+
+    //
+    // The lookup process (in python psudocode) is
+    //
+    // def GetSym(name):
+    //     # NB STN_UNDEF == 0
+    //     indx = bucket[elfhash(name) % num_buckets]
+    //     while indx != STN_UNDEF:
+    //         if GetSymbolName(symtab[indx]) == name:
+    //             return symtab[indx]
+    //         indx = chain[indx]
+    //     return SYMBOL_NOT_FOUND
+    //
+    // Between bucket and chain arrays every symtab index must be present exactly
+    // once (except for STN_UNDEF, which must be present 1 + num_bucket times).
+
+    // Select number of buckets.
+    // This is essentially arbitrary.
+    Elf_Word nbuckets;
+    Elf_Word chain_size = GetSize();
+    if (symbols_.size() < 8) {
+      nbuckets = 2;
+    } else if (symbols_.size() < 32) {
+      nbuckets = 4;
+    } else if (symbols_.size() < 256) {
+      nbuckets = 16;
+    } else {
+      // Have about 32 ids per bucket.
+      nbuckets = RoundUp(symbols_.size()/32, 2);
+    }
+    std::vector<Elf_Word> hash;
+    hash.push_back(nbuckets);
+    hash.push_back(chain_size);
+    uint32_t bucket_offset = hash.size();
+    uint32_t chain_offset = bucket_offset + nbuckets;
+    hash.resize(hash.size() + nbuckets + chain_size, 0);
+
+    Elf_Word* buckets = hash.data() + bucket_offset;
+    Elf_Word* chain   = hash.data() + chain_offset;
+
+    // Set up the actual hash table.
+    for (Elf_Word i = 0; i < symbols_.size(); i++) {
+      // Add 1 since we need to have the null symbol that is not in the symbols
+      // list.
+      Elf_Word index = i + 1;
+      Elf_Word hash_val = static_cast<Elf_Word>(elfhash(symbols_[i].name_.c_str())) % nbuckets;
+      if (buckets[hash_val] == 0) {
+        buckets[hash_val] = index;
+      } else {
+        hash_val = buckets[hash_val];
+        CHECK_LT(hash_val, chain_size);
+        while (chain[hash_val] != 0) {
+          hash_val = chain[hash_val];
+          CHECK_LT(hash_val, chain_size);
+        }
+        chain[hash_val] = index;
+        // Check for loops. Works because if this is non-empty then there must be
+        // another cell which already contains the same symbol index as this one,
+        // which means some symbol has more then one name, which isn't allowed.
+        CHECK_EQ(chain[index], static_cast<Elf_Word>(0));
+      }
+    }
+
+    return hash;
+  }
+
+  std::string GenerateStrtab() {
+    std::string tab;
+    tab += '\0';
+    for (auto it = symbols_.begin(); it != symbols_.end(); ++it) {
+      it->name_idx_ = tab.size();
+      tab += it->name_;
+      tab += '\0';
+    }
+    strtab_.section_.sh_size = tab.size();
+    return tab;
+  }
+
+  std::vector<Elf_Sym> GenerateSymtab() {
+    std::vector<Elf_Sym> ret;
+    Elf_Sym undef_sym;
+    memset(&undef_sym, 0, sizeof(undef_sym));
+    undef_sym.st_shndx = SHN_UNDEF;
+    ret.push_back(undef_sym);
+
+    for (auto it = symbols_.cbegin(); it != symbols_.cend(); ++it) {
+      Elf_Sym sym;
+      memset(&sym, 0, sizeof(sym));
+      sym.st_name = it->name_idx_;
+      if (it->is_relative_) {
+        sym.st_value = it->addr_ + it->section_->section_.sh_offset;
+      } else {
+        sym.st_value = it->addr_;
+      }
+      sym.st_size = it->size_;
+      sym.st_other = it->other_;
+      sym.st_shndx = it->section_->section_index_;
+      sym.st_info = it->info_;
+
+      ret.push_back(sym);
+    }
+    return ret;
+  }
+
+  Elf_Word GetSize() {
+    // 1 is for the implicit NULL symbol.
+    return symbols_.size() + 1;
+  }
+
+  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* GetStrTab() {
+    return &strtab_;
+  }
+
+ protected:
+  struct ElfSymbolState {
+    const std::string name_;
+    const ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* section_;
+    Elf_Addr addr_;
+    Elf_Word size_;
+    bool is_relative_;
+    uint8_t info_;
+    uint8_t other_;
+    // Used during Write() to temporarially hold name index in the strtab.
+    Elf_Word name_idx_;
+  };
+
+  // Information for the strsym for dynstr sections.
+  const std::string str_name_;
+  Elf_Word str_type_;
+  // The symbols in the same order they will be in the symbol table.
+  std::vector<ElfSymbolState> symbols_;
+  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> strtab_;
+};
+
+class CodeOutput {
+ public:
+  virtual bool Write(OutputStream* out) = 0;
+  virtual ~CodeOutput() {}
+};
+
+template <typename Elf_Word, typename Elf_Shdr>
+static inline constexpr Elf_Word NextOffset(const Elf_Shdr& cur, const Elf_Shdr& prev) {
+  return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign);
+}
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Dyn,
+          typename Elf_Sym, typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr>
+class ElfBuilder FINAL {
+ public:
+  ElfBuilder(CodeOutput* oat_writer,
+             File* elf_file,
+             InstructionSet isa,
+             Elf_Word rodata_relative_offset,
+             Elf_Word rodata_size,
+             Elf_Word text_relative_offset,
+             Elf_Word text_size,
+             const bool add_symbols,
+             bool debug = false)
+    : oat_writer_(oat_writer),
+      elf_file_(elf_file),
+      add_symbols_(add_symbols),
+      debug_logging_(debug),
+      text_builder_(".text", text_size, text_relative_offset, SHT_PROGBITS,
+                    SHF_ALLOC | SHF_EXECINSTR),
+      rodata_builder_(".rodata", rodata_size, rodata_relative_offset, SHT_PROGBITS, SHF_ALLOC),
+      dynsym_builder_(".dynsym", SHT_DYNSYM, ".dynstr", SHT_STRTAB, true),
+      symtab_builder_(".symtab", SHT_SYMTAB, ".strtab", SHT_STRTAB, false),
+      hash_builder_(".hash", SHT_HASH, SHF_ALLOC, &dynsym_builder_, 0, sizeof(Elf_Word),
+                    sizeof(Elf_Word)),
+      dynamic_builder_(".dynamic", &dynsym_builder_),
+      shstrtab_builder_(".shstrtab", SHT_STRTAB, 0, NULL, 0, 1, 1) {
+    SetupEhdr();
+    SetupDynamic();
+    SetupRequiredSymbols();
+    SetISA(isa);
+  }
+  ~ElfBuilder() {}
+
+  bool Init() {
+    // The basic layout of the elf file. Order may be different in final output.
+    // +-------------------------+
+    // | Elf_Ehdr                |
+    // +-------------------------+
+    // | Elf_Phdr PHDR           |
+    // | Elf_Phdr LOAD R         | .dynsym .dynstr .hash .rodata
+    // | Elf_Phdr LOAD R X       | .text
+    // | Elf_Phdr LOAD RW        | .dynamic
+    // | Elf_Phdr DYNAMIC        | .dynamic
+    // +-------------------------+
+    // | .dynsym                 |
+    // | Elf_Sym  STN_UNDEF      |
+    // | Elf_Sym  oatdata        |
+    // | Elf_Sym  oatexec        |
+    // | Elf_Sym  oatlastword    |
+    // +-------------------------+
+    // | .dynstr                 |
+    // | \0                      |
+    // | oatdata\0               |
+    // | oatexec\0               |
+    // | oatlastword\0           |
+    // | boot.oat\0              |
+    // +-------------------------+
+    // | .hash                   |
+    // | Elf_Word nbucket = b    |
+    // | Elf_Word nchain  = c    |
+    // | Elf_Word bucket[0]      |
+    // |         ...             |
+    // | Elf_Word bucket[b - 1]  |
+    // | Elf_Word chain[0]       |
+    // |         ...             |
+    // | Elf_Word chain[c - 1]   |
+    // +-------------------------+
+    // | .rodata                 |
+    // | oatdata..oatexec-4      |
+    // +-------------------------+
+    // | .text                   |
+    // | oatexec..oatlastword    |
+    // +-------------------------+
+    // | .dynamic                |
+    // | Elf_Dyn DT_SONAME       |
+    // | Elf_Dyn DT_HASH         |
+    // | Elf_Dyn DT_SYMTAB       |
+    // | Elf_Dyn DT_SYMENT       |
+    // | Elf_Dyn DT_STRTAB       |
+    // | Elf_Dyn DT_STRSZ        |
+    // | Elf_Dyn DT_NULL         |
+    // +-------------------------+  (Optional)
+    // | .strtab                 |  (Optional)
+    // | program symbol names    |  (Optional)
+    // +-------------------------+  (Optional)
+    // | .symtab                 |  (Optional)
+    // | program symbols         |  (Optional)
+    // +-------------------------+
+    // | .shstrtab               |
+    // | \0                      |
+    // | .dynamic\0              |
+    // | .dynsym\0               |
+    // | .dynstr\0               |
+    // | .hash\0                 |
+    // | .rodata\0               |
+    // | .text\0                 |
+    // | .shstrtab\0             |
+    // | .symtab\0               |  (Optional)
+    // | .strtab\0               |  (Optional)
+    // | .debug_str\0            |  (Optional)
+    // | .debug_info\0           |  (Optional)
+    // | .eh_frame\0             |  (Optional)
+    // | .debug_line\0           |  (Optional)
+    // | .debug_abbrev\0         |  (Optional)
+    // +-------------------------+  (Optional)
+    // | .debug_info             |  (Optional)
+    // +-------------------------+  (Optional)
+    // | .debug_abbrev           |  (Optional)
+    // +-------------------------+  (Optional)
+    // | .eh_frame               |  (Optional)
+    // +-------------------------+  (Optional)
+    // | .debug_line             |  (Optional)
+    // +-------------------------+  (Optional)
+    // | .debug_str              |  (Optional)
+    // +-------------------------+  (Optional)
+    // | Elf_Shdr NULL           |
+    // | Elf_Shdr .dynsym        |
+    // | Elf_Shdr .dynstr        |
+    // | Elf_Shdr .hash          |
+    // | Elf_Shdr .text          |
+    // | Elf_Shdr .rodata        |
+    // | Elf_Shdr .dynamic       |
+    // | Elf_Shdr .shstrtab      |
+    // | Elf_Shdr .debug_info    |  (Optional)
+    // | Elf_Shdr .debug_abbrev  |  (Optional)
+    // | Elf_Shdr .eh_frame      |  (Optional)
+    // | Elf_Shdr .debug_line    |  (Optional)
+    // | Elf_Shdr .debug_str     |  (Optional)
+    // +-------------------------+
+
+    if (fatal_error_) {
+      return false;
+    }
+    // Step 1. Figure out all the offsets.
+
+    if (debug_logging_) {
+      LOG(INFO) << "phdr_offset=" << PHDR_OFFSET << std::hex << " " << PHDR_OFFSET;
+      LOG(INFO) << "phdr_size=" << PHDR_SIZE << std::hex << " " << PHDR_SIZE;
+    }
+
+    memset(&program_headers_, 0, sizeof(program_headers_));
+    program_headers_[PH_PHDR].p_type    = PT_PHDR;
+    program_headers_[PH_PHDR].p_offset  = PHDR_OFFSET;
+    program_headers_[PH_PHDR].p_vaddr   = PHDR_OFFSET;
+    program_headers_[PH_PHDR].p_paddr   = PHDR_OFFSET;
+    program_headers_[PH_PHDR].p_filesz  = sizeof(program_headers_);
+    program_headers_[PH_PHDR].p_memsz   = sizeof(program_headers_);
+    program_headers_[PH_PHDR].p_flags   = PF_R;
+    program_headers_[PH_PHDR].p_align   = sizeof(Elf_Word);
+
+    program_headers_[PH_LOAD_R__].p_type    = PT_LOAD;
+    program_headers_[PH_LOAD_R__].p_offset  = 0;
+    program_headers_[PH_LOAD_R__].p_vaddr   = 0;
+    program_headers_[PH_LOAD_R__].p_paddr   = 0;
+    program_headers_[PH_LOAD_R__].p_flags   = PF_R;
+
+    program_headers_[PH_LOAD_R_X].p_type    = PT_LOAD;
+    program_headers_[PH_LOAD_R_X].p_flags   = PF_R | PF_X;
+
+    program_headers_[PH_LOAD_RW_].p_type    = PT_LOAD;
+    program_headers_[PH_LOAD_RW_].p_flags   = PF_R | PF_W;
+
+    program_headers_[PH_DYNAMIC].p_type    = PT_DYNAMIC;
+    program_headers_[PH_DYNAMIC].p_flags   = PF_R | PF_W;
+
+    // Get the dynstr string.
+    dynstr_ = dynsym_builder_.GenerateStrtab();
+
+    // Add the SONAME to the dynstr.
+    dynstr_soname_offset_ = dynstr_.size();
+    std::string file_name(elf_file_->GetPath());
+    size_t directory_separator_pos = file_name.rfind('/');
+    if (directory_separator_pos != std::string::npos) {
+      file_name = file_name.substr(directory_separator_pos + 1);
+    }
+    dynstr_ += file_name;
+    dynstr_ += '\0';
+    if (debug_logging_) {
+      LOG(INFO) << "dynstr size (bytes)   =" << dynstr_.size()
+                << std::hex << " " << dynstr_.size();
+      LOG(INFO) << "dynsym size (elements)=" << dynsym_builder_.GetSize()
+                << std::hex << " " << dynsym_builder_.GetSize();
+    }
+
+    // Get the section header string table.
+    shstrtab_ += '\0';
+
+    // Setup sym_undef
+    memset(&null_hdr_, 0, sizeof(null_hdr_));
+    null_hdr_.sh_type = SHT_NULL;
+    null_hdr_.sh_link = SHN_UNDEF;
+    section_ptrs_.push_back(&null_hdr_);
+
+    section_index_ = 1;
+
+    // setup .dynsym
+    section_ptrs_.push_back(&dynsym_builder_.section_);
+    AssignSectionStr(&dynsym_builder_, &shstrtab_);
+    dynsym_builder_.section_index_ = section_index_++;
+
+    // Setup .dynstr
+    section_ptrs_.push_back(&dynsym_builder_.GetStrTab()->section_);
+    AssignSectionStr(dynsym_builder_.GetStrTab(), &shstrtab_);
+    dynsym_builder_.GetStrTab()->section_index_ = section_index_++;
+
+    // Setup .hash
+    section_ptrs_.push_back(&hash_builder_.section_);
+    AssignSectionStr(&hash_builder_, &shstrtab_);
+    hash_builder_.section_index_ = section_index_++;
+
+    // Setup .rodata
+    section_ptrs_.push_back(&rodata_builder_.section_);
+    AssignSectionStr(&rodata_builder_, &shstrtab_);
+    rodata_builder_.section_index_ = section_index_++;
+
+    // Setup .text
+    section_ptrs_.push_back(&text_builder_.section_);
+    AssignSectionStr(&text_builder_, &shstrtab_);
+    text_builder_.section_index_ = section_index_++;
+
+    // Setup .dynamic
+    section_ptrs_.push_back(&dynamic_builder_.section_);
+    AssignSectionStr(&dynamic_builder_, &shstrtab_);
+    dynamic_builder_.section_index_ = section_index_++;
+
+    // Fill in the hash section.
+    hash_ = dynsym_builder_.GenerateHashContents();
+
+    if (debug_logging_) {
+      LOG(INFO) << ".hash size (bytes)=" << hash_.size() * sizeof(Elf_Word)
+                << std::hex << " " << hash_.size() * sizeof(Elf_Word);
+    }
+
+    Elf_Word base_offset = sizeof(Elf_Ehdr) + sizeof(program_headers_);
+
+    // Get the layout in the sections.
+    //
+    // Get the layout of the dynsym section.
+    dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign);
+    dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset;
+    dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
+    dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();
+
+    // Get the layout of the dynstr section.
+    dynsym_builder_.GetStrTab()->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                                 (dynsym_builder_.GetStrTab()->section_,
+                                                  dynsym_builder_.section_);
+    dynsym_builder_.GetStrTab()->section_.sh_addr = dynsym_builder_.GetStrTab()->section_.sh_offset;
+    dynsym_builder_.GetStrTab()->section_.sh_size = dynstr_.size();
+    dynsym_builder_.GetStrTab()->section_.sh_link = dynsym_builder_.GetStrTab()->GetLink();
+
+    // Get the layout of the hash section
+    hash_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                       (hash_builder_.section_,
+                                        dynsym_builder_.GetStrTab()->section_);
+    hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset;
+    hash_builder_.section_.sh_size = hash_.size() * sizeof(Elf_Word);
+    hash_builder_.section_.sh_link = hash_builder_.GetLink();
+
+    // Get the layout of the rodata section.
+    rodata_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                         (rodata_builder_.section_,
+                                          hash_builder_.section_);
+    rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset;
+    rodata_builder_.section_.sh_size = rodata_builder_.GetSize();
+    rodata_builder_.section_.sh_link = rodata_builder_.GetLink();
+
+    // Get the layout of the text section.
+    text_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                       (text_builder_.section_, rodata_builder_.section_);
+    text_builder_.section_.sh_addr = text_builder_.section_.sh_offset;
+    text_builder_.section_.sh_size = text_builder_.GetSize();
+    text_builder_.section_.sh_link = text_builder_.GetLink();
+    CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize);
+
+    // Get the layout of the dynamic section.
+    dynamic_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                          (dynamic_builder_.section_,
+                                           text_builder_.section_);
+    dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset;
+    dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
+    dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();
+
+    if (debug_logging_) {
+      LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset
+                << " dynsym size=" << dynsym_builder_.section_.sh_size;
+      LOG(INFO) << "dynstr off=" << dynsym_builder_.GetStrTab()->section_.sh_offset
+                << " dynstr size=" << dynsym_builder_.GetStrTab()->section_.sh_size;
+      LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset
+                << " hash size=" << hash_builder_.section_.sh_size;
+      LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset
+                << " rodata size=" << rodata_builder_.section_.sh_size;
+      LOG(INFO) << "text off=" << text_builder_.section_.sh_offset
+                << " text size=" << text_builder_.section_.sh_size;
+      LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset
+                << " dynamic size=" << dynamic_builder_.section_.sh_size;
+    }
+
+    return true;
+  }
+
+  bool Write() {
+    std::vector<ElfFilePiece> pieces;
+    Elf_Shdr prev = dynamic_builder_.section_;
+    std::string strtab;
+
+    if (IncludingDebugSymbols()) {
+      // Setup .symtab
+      section_ptrs_.push_back(&symtab_builder_.section_);
+      AssignSectionStr(&symtab_builder_, &shstrtab_);
+      symtab_builder_.section_index_ = section_index_++;
+
+      // Setup .strtab
+      section_ptrs_.push_back(&symtab_builder_.GetStrTab()->section_);
+      AssignSectionStr(symtab_builder_.GetStrTab(), &shstrtab_);
+      symtab_builder_.GetStrTab()->section_index_ = section_index_++;
+
+      strtab = symtab_builder_.GenerateStrtab();
+      if (debug_logging_) {
+        LOG(INFO) << "strtab size (bytes)    =" << strtab.size()
+                  << std::hex << " " << strtab.size();
+        LOG(INFO) << "symtab size (elements) =" << symtab_builder_.GetSize()
+                  << std::hex << " " << symtab_builder_.GetSize();
+      }
+    }
+
+    // Setup all the other sections.
+    for (ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *builder = other_builders_.data(),
+         *end = builder + other_builders_.size();
+         builder != end; ++builder) {
+      section_ptrs_.push_back(&builder->section_);
+      AssignSectionStr(builder, &shstrtab_);
+      builder->section_index_ = section_index_++;
+    }
+
+    // Setup shstrtab
+    section_ptrs_.push_back(&shstrtab_builder_.section_);
+    AssignSectionStr(&shstrtab_builder_, &shstrtab_);
+    shstrtab_builder_.section_index_ = section_index_++;
+
+    if (debug_logging_) {
+      LOG(INFO) << ".shstrtab size    (bytes)   =" << shstrtab_.size()
+                << std::hex << " " << shstrtab_.size();
+      LOG(INFO) << "section list size (elements)=" << section_ptrs_.size()
+                << std::hex << " " << section_ptrs_.size();
+    }
+
+    if (IncludingDebugSymbols()) {
+      // Get the layout of the symtab section.
+      symtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                           (symtab_builder_.section_,
+                                            dynamic_builder_.section_);
+      symtab_builder_.section_.sh_addr = 0;
+      // Add to leave space for the null symbol.
+      symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
+      symtab_builder_.section_.sh_link = symtab_builder_.GetLink();
+
+      // Get the layout of the dynstr section.
+      symtab_builder_.GetStrTab()->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                                   (symtab_builder_.GetStrTab()->section_,
+                                                    symtab_builder_.section_);
+      symtab_builder_.GetStrTab()->section_.sh_addr = 0;
+      symtab_builder_.GetStrTab()->section_.sh_size = strtab.size();
+      symtab_builder_.GetStrTab()->section_.sh_link = symtab_builder_.GetStrTab()->GetLink();
+
+      prev = symtab_builder_.GetStrTab()->section_;
+      if (debug_logging_) {
+        LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset
+                  << " symtab size=" << symtab_builder_.section_.sh_size;
+        LOG(INFO) << "strtab off=" << symtab_builder_.GetStrTab()->section_.sh_offset
+                  << " strtab size=" << symtab_builder_.GetStrTab()->section_.sh_size;
+      }
+    }
+
+    // Get the layout of the extra sections. (This will deal with the debug
+    // sections if they are there)
+    for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
+      it->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>(it->section_, prev);
+      it->section_.sh_addr = 0;
+      it->section_.sh_size = it->GetBuffer()->size();
+      it->section_.sh_link = it->GetLink();
+      pieces.push_back(ElfFilePiece(it->name_, it->section_.sh_offset,
+                                    it->GetBuffer()->data(), it->GetBuffer()->size()));
+      prev = it->section_;
+      if (debug_logging_) {
+        LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
+                  << " size=" << it->section_.sh_size;
+      }
+    }
+
+    // Get the layout of the shstrtab section
+    shstrtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
+                                           (shstrtab_builder_.section_, prev);
+    shstrtab_builder_.section_.sh_addr = 0;
+    shstrtab_builder_.section_.sh_size = shstrtab_.size();
+    shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink();
+    if (debug_logging_) {
+        LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset
+                  << " shstrtab size=" << shstrtab_builder_.section_.sh_size;
+    }
+
+    // The section list comes after come after.
+    Elf_Word sections_offset = RoundUp(
+        shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
+        sizeof(Elf_Word));
+
+    // Setup the actual symbol arrays.
+    std::vector<Elf_Sym> dynsym = dynsym_builder_.GenerateSymtab();
+    CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.section_.sh_size);
+    std::vector<Elf_Sym> symtab;
+    if (IncludingDebugSymbols()) {
+      symtab = symtab_builder_.GenerateSymtab();
+      CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.section_.sh_size);
+    }
+
+    // Setup the dynamic section.
+    // This will add the 2 values we cannot know until now time, namely the size
+    // and the soname_offset.
+    std::vector<Elf_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr_.size(),
+                                                                  dynstr_soname_offset_);
+    CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.section_.sh_size);
+
+    // Finish setup of the program headers now that we know the layout of the
+    // whole file.
+    Elf_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size;
+    program_headers_[PH_LOAD_R__].p_filesz = load_r_size;
+    program_headers_[PH_LOAD_R__].p_memsz =  load_r_size;
+    program_headers_[PH_LOAD_R__].p_align =  rodata_builder_.section_.sh_addralign;
+
+    Elf_Word load_rx_size = text_builder_.section_.sh_size;
+    program_headers_[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset;
+    program_headers_[PH_LOAD_R_X].p_vaddr  = text_builder_.section_.sh_offset;
+    program_headers_[PH_LOAD_R_X].p_paddr  = text_builder_.section_.sh_offset;
+    program_headers_[PH_LOAD_R_X].p_filesz = load_rx_size;
+    program_headers_[PH_LOAD_R_X].p_memsz  = load_rx_size;
+    program_headers_[PH_LOAD_R_X].p_align  = text_builder_.section_.sh_addralign;
+
+    program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset;
+    program_headers_[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.section_.sh_offset;
+    program_headers_[PH_LOAD_RW_].p_paddr  = dynamic_builder_.section_.sh_offset;
+    program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size;
+    program_headers_[PH_LOAD_RW_].p_memsz  = dynamic_builder_.section_.sh_size;
+    program_headers_[PH_LOAD_RW_].p_align  = dynamic_builder_.section_.sh_addralign;
+
+    program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset;
+    program_headers_[PH_DYNAMIC].p_vaddr  = dynamic_builder_.section_.sh_offset;
+    program_headers_[PH_DYNAMIC].p_paddr  = dynamic_builder_.section_.sh_offset;
+    program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size;
+    program_headers_[PH_DYNAMIC].p_memsz  = dynamic_builder_.section_.sh_size;
+    program_headers_[PH_DYNAMIC].p_align  = dynamic_builder_.section_.sh_addralign;
+
+    // Finish setup of the Ehdr values.
+    elf_header_.e_phoff = PHDR_OFFSET;
+    elf_header_.e_shoff = sections_offset;
+    elf_header_.e_phnum = PH_NUM;
+    elf_header_.e_shnum = section_ptrs_.size();
+    elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
+
+    // Add the rest of the pieces to the list.
+    pieces.push_back(ElfFilePiece("Elf Header", 0, &elf_header_, sizeof(elf_header_)));
+    pieces.push_back(ElfFilePiece("Program headers", PHDR_OFFSET,
+                                  &program_headers_, sizeof(program_headers_)));
+    pieces.push_back(ElfFilePiece(".dynamic", dynamic_builder_.section_.sh_offset,
+                                  dynamic.data(), dynamic_builder_.section_.sh_size));
+    pieces.push_back(ElfFilePiece(".dynsym", dynsym_builder_.section_.sh_offset,
+                                  dynsym.data(), dynsym.size() * sizeof(Elf_Sym)));
+    pieces.push_back(ElfFilePiece(".dynstr", dynsym_builder_.GetStrTab()->section_.sh_offset,
+                                  dynstr_.c_str(), dynstr_.size()));
+    pieces.push_back(ElfFilePiece(".hash", hash_builder_.section_.sh_offset,
+                                  hash_.data(), hash_.size() * sizeof(Elf_Word)));
+    pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset,
+                                  nullptr, rodata_builder_.section_.sh_size));
+    pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset,
+                                  nullptr, text_builder_.section_.sh_size));
+    if (IncludingDebugSymbols()) {
+      pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset,
+                                    symtab.data(), symtab.size() * sizeof(Elf_Sym)));
+      pieces.push_back(ElfFilePiece(".strtab", symtab_builder_.GetStrTab()->section_.sh_offset,
+                                    strtab.c_str(), strtab.size()));
+    }
+    pieces.push_back(ElfFilePiece(".shstrtab", shstrtab_builder_.section_.sh_offset,
+                                  &shstrtab_[0], shstrtab_.size()));
+    for (uint32_t i = 0; i < section_ptrs_.size(); ++i) {
+      // Just add all the sections in induvidually since they are all over the
+      // place on the heap/stack.
+      Elf_Word cur_off = sections_offset + i * sizeof(Elf_Shdr);
+      pieces.push_back(ElfFilePiece("section table piece", cur_off,
+                                    section_ptrs_[i], sizeof(Elf_Shdr)));
+    }
+
+    if (!WriteOutFile(pieces)) {
+      LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();
+      return false;
+    }
+    // write out the actual oat file data.
+    Elf_Word oat_data_offset = rodata_builder_.section_.sh_offset;
+    if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) {
+      PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset
+                  << " for " << elf_file_->GetPath();
+      return false;
+    }
+    std::unique_ptr<BufferedOutputStream> output_stream(
+        new BufferedOutputStream(new FileOutputStream(elf_file_)));
+    if (!oat_writer_->Write(output_stream.get())) {
+      PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath();
+      return false;
+    }
+
+    return true;
+  }
+
+  // Adds the given raw section to the builder. This will copy it. The caller
+  // is responsible for deallocating their copy.
+  void RegisterRawSection(ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> bld) {
+    other_builders_.push_back(bld);
+  }
+
+ private:
+  CodeOutput* oat_writer_;
+  File* elf_file_;
+  const bool add_symbols_;
+  const bool debug_logging_;
+
+  bool fatal_error_ = false;
+
+  // What phdr is.
+  static const uint32_t PHDR_OFFSET = sizeof(Elf_Ehdr);
+  enum : uint8_t {
+    PH_PHDR     = 0,
+        PH_LOAD_R__ = 1,
+        PH_LOAD_R_X = 2,
+        PH_LOAD_RW_ = 3,
+        PH_DYNAMIC  = 4,
+        PH_NUM      = 5,
+  };
+  static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM;
+  Elf_Phdr program_headers_[PH_NUM];
+
+  Elf_Ehdr elf_header_;
+
+  Elf_Shdr null_hdr_;
+  std::string shstrtab_;
+  uint32_t section_index_;
+  std::string dynstr_;
+  uint32_t dynstr_soname_offset_;
+  std::vector<Elf_Shdr*> section_ptrs_;
+  std::vector<Elf_Word> hash_;
+
+ public:
+  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> text_builder_;
+  ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> rodata_builder_;
+  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> dynsym_builder_;
+  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr> symtab_builder_;
+  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> hash_builder_;
+  ElfDynamicBuilder<Elf_Word, Elf_Sword, Elf_Dyn, Elf_Shdr> dynamic_builder_;
+  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> shstrtab_builder_;
+  std::vector<ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>> other_builders_;
+
+ private:
+  void SetISA(InstructionSet isa) {
+    switch (isa) {
+      case kArm:
+        // Fall through.
+      case kThumb2: {
+        elf_header_.e_machine = EM_ARM;
+        elf_header_.e_flags = EF_ARM_EABI_VER5;
+        break;
+      }
+      case kArm64: {
+        elf_header_.e_machine = EM_AARCH64;
+        elf_header_.e_flags = 0;
+        break;
+      }
+      case kX86: {
+        elf_header_.e_machine = EM_386;
+        elf_header_.e_flags = 0;
+        break;
+      }
+      case kX86_64: {
+        elf_header_.e_machine = EM_X86_64;
+        elf_header_.e_flags = 0;
+        break;
+      }
+      case kMips: {
+        elf_header_.e_machine = EM_MIPS;
+        elf_header_.e_flags = (EF_MIPS_NOREORDER |
+                               EF_MIPS_PIC       |
+                               EF_MIPS_CPIC      |
+                               EF_MIPS_ABI_O32   |
+                               EF_MIPS_ARCH_32R2);
+        break;
+      }
+      default: {
+        fatal_error_ = true;
+        LOG(FATAL) << "Unknown instruction set: " << isa;
+        break;
+      }
+    }
+  }
+
+  void SetupEhdr() {
+    memset(&elf_header_, 0, sizeof(elf_header_));
+    elf_header_.e_ident[EI_MAG0]       = ELFMAG0;
+    elf_header_.e_ident[EI_MAG1]       = ELFMAG1;
+    elf_header_.e_ident[EI_MAG2]       = ELFMAG2;
+    elf_header_.e_ident[EI_MAG3]       = ELFMAG3;
+    elf_header_.e_ident[EI_CLASS]      = ELFCLASS32;
+    elf_header_.e_ident[EI_DATA]       = ELFDATA2LSB;
+    elf_header_.e_ident[EI_VERSION]    = EV_CURRENT;
+    elf_header_.e_ident[EI_OSABI]      = ELFOSABI_LINUX;
+    elf_header_.e_ident[EI_ABIVERSION] = 0;
+    elf_header_.e_type = ET_DYN;
+    elf_header_.e_version = 1;
+    elf_header_.e_entry = 0;
+    elf_header_.e_ehsize = sizeof(Elf_Ehdr);
+    elf_header_.e_phentsize = sizeof(Elf_Phdr);
+    elf_header_.e_shentsize = sizeof(Elf_Shdr);
+    elf_header_.e_phoff = sizeof(Elf_Ehdr);
+  }
+
+  // Sets up a bunch of the required Dynamic Section entries.
+  // Namely it will initialize all the mandatory ones that it can.
+  // Specifically:
+  // DT_HASH
+  // DT_STRTAB
+  // DT_SYMTAB
+  // DT_SYMENT
+  //
+  // Some such as DT_SONAME, DT_STRSZ and DT_NULL will be put in later.
+  void SetupDynamic() {
+    dynamic_builder_.AddDynamicTag(DT_HASH, 0, &hash_builder_);
+    dynamic_builder_.AddDynamicTag(DT_STRTAB, 0, dynsym_builder_.GetStrTab());
+    dynamic_builder_.AddDynamicTag(DT_SYMTAB, 0, &dynsym_builder_);
+    dynamic_builder_.AddDynamicTag(DT_SYMENT, sizeof(Elf_Sym));
+  }
+
+  // Sets up the basic dynamic symbols that are needed, namely all those we
+  // can know already.
+  //
+  // Specifically adds:
+  // oatdata
+  // oatexec
+  // oatlastword
+  void SetupRequiredSymbols() {
+    dynsym_builder_.AddSymbol("oatdata", &rodata_builder_, 0, true,
+                              rodata_builder_.GetSize(), STB_GLOBAL, STT_OBJECT);
+    dynsym_builder_.AddSymbol("oatexec", &text_builder_, 0, true,
+                              text_builder_.GetSize(), STB_GLOBAL, STT_OBJECT);
+    dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.GetSize() - 4,
+                              true, 4, STB_GLOBAL, STT_OBJECT);
+  }
+
+  void AssignSectionStr(ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> *builder,
+                        std::string* strtab) {
+    builder->section_.sh_name = strtab->size();
+    *strtab += builder->name_;
+    *strtab += '\0';
+    if (debug_logging_) {
+      LOG(INFO) << "adding section name \"" << builder->name_ << "\" "
+                << "to shstrtab at offset " << builder->section_.sh_name;
+    }
+  }
+
+  struct ElfFilePiece {
+    ElfFilePiece(const std::string& name, Elf_Word offset, const void* data, Elf_Word size)
+    : dbg_name_(name), offset_(offset), data_(data), size_(size) {}
+    ~ElfFilePiece() {}
+
+    const std::string& dbg_name_;
+    Elf_Word offset_;
+    const void *data_;
+    Elf_Word size_;
+    static bool Compare(ElfFilePiece a, ElfFilePiece b) {
+      return a.offset_ < b.offset_;
+    }
+  };
+
+  // Write each of the pieces out to the file.
+  bool WriteOutFile(const std::vector<ElfFilePiece>& pieces) {
+    // TODO It would be nice if this checked for overlap.
+    for (auto it = pieces.begin(); it != pieces.end(); ++it) {
+      if (it->data_) {
+        if (static_cast<off_t>(it->offset_) != lseek(elf_file_->Fd(), it->offset_, SEEK_SET)) {
+          PLOG(ERROR) << "Failed to seek to " << it->dbg_name_ << " offset location "
+                      << it->offset_ << " for " << elf_file_->GetPath();
+          return false;
+        }
+        if (!elf_file_->WriteFully(it->data_, it->size_)) {
+          PLOG(ERROR) << "Failed to write " << it->dbg_name_ << " for " << elf_file_->GetPath();
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; }
+};
+
+}  // namespace art
+
+#endif  // ART_COMPILER_ELF_BUILDER_H_
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 4c69fc8..dbd3a37 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -23,6 +23,7 @@
 #include "buffered_output_stream.h"
 #include "driver/compiler_driver.h"
 #include "dwarf.h"
+#include "elf_builder.h"
 #include "elf_file.h"
 #include "elf_utils.h"
 #include "file_output_stream.h"
@@ -34,15 +35,6 @@
 
 namespace art {
 
-template <typename Elf_Word, typename Elf_Shdr>
-static constexpr Elf_Word NextOffset(const Elf_Shdr& cur, const Elf_Shdr& prev) {
-  return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign);
-}
-
-static uint8_t MakeStInfo(uint8_t binding, uint8_t type) {
-  return ((binding) << 4) + ((type) & 0xf);
-}
-
 static void PushByte(std::vector<uint8_t>* buf, int data) {
   buf->push_back(data & 0xff);
 }
@@ -83,826 +75,6 @@
           typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
           typename Elf_Phdr, typename Elf_Shdr>
 bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::Init() {
-  // The basic layout of the elf file. Order may be different in final output.
-  // +-------------------------+
-  // | Elf_Ehdr                |
-  // +-------------------------+
-  // | Elf_Phdr PHDR           |
-  // | Elf_Phdr LOAD R         | .dynsym .dynstr .hash .rodata
-  // | Elf_Phdr LOAD R X       | .text
-  // | Elf_Phdr LOAD RW        | .dynamic
-  // | Elf_Phdr DYNAMIC        | .dynamic
-  // +-------------------------+
-  // | .dynsym                 |
-  // | Elf_Sym  STN_UNDEF      |
-  // | Elf_Sym  oatdata        |
-  // | Elf_Sym  oatexec        |
-  // | Elf_Sym  oatlastword    |
-  // +-------------------------+
-  // | .dynstr                 |
-  // | \0                      |
-  // | oatdata\0               |
-  // | oatexec\0               |
-  // | oatlastword\0           |
-  // | boot.oat\0              |
-  // +-------------------------+
-  // | .hash                   |
-  // | Elf_Word nbucket = b    |
-  // | Elf_Word nchain  = c    |
-  // | Elf_Word bucket[0]      |
-  // |         ...             |
-  // | Elf_Word bucket[b - 1]  |
-  // | Elf_Word chain[0]       |
-  // |         ...             |
-  // | Elf_Word chain[c - 1]   |
-  // +-------------------------+
-  // | .rodata                 |
-  // | oatdata..oatexec-4      |
-  // +-------------------------+
-  // | .text                   |
-  // | oatexec..oatlastword    |
-  // +-------------------------+
-  // | .dynamic                |
-  // | Elf_Dyn DT_SONAME       |
-  // | Elf_Dyn DT_HASH         |
-  // | Elf_Dyn DT_SYMTAB       |
-  // | Elf_Dyn DT_SYMENT       |
-  // | Elf_Dyn DT_STRTAB       |
-  // | Elf_Dyn DT_STRSZ        |
-  // | Elf_Dyn DT_NULL         |
-  // +-------------------------+  (Optional)
-  // | .strtab                 |  (Optional)
-  // | program symbol names    |  (Optional)
-  // +-------------------------+  (Optional)
-  // | .symtab                 |  (Optional)
-  // | program symbols         |  (Optional)
-  // +-------------------------+
-  // | .shstrtab               |
-  // | \0                      |
-  // | .dynamic\0              |
-  // | .dynsym\0               |
-  // | .dynstr\0               |
-  // | .hash\0                 |
-  // | .rodata\0               |
-  // | .text\0                 |
-  // | .shstrtab\0             |
-  // | .symtab\0               |  (Optional)
-  // | .strtab\0               |  (Optional)
-  // | .debug_str\0            |  (Optional)
-  // | .debug_info\0           |  (Optional)
-  // | .eh_frame\0             |  (Optional)
-  // | .debug_line\0           |  (Optional)
-  // | .debug_abbrev\0         |  (Optional)
-  // +-------------------------+  (Optional)
-  // | .debug_info             |  (Optional)
-  // +-------------------------+  (Optional)
-  // | .debug_abbrev           |  (Optional)
-  // +-------------------------+  (Optional)
-  // | .eh_frame               |  (Optional)
-  // +-------------------------+  (Optional)
-  // | .debug_line             |  (Optional)
-  // +-------------------------+  (Optional)
-  // | .debug_str              |  (Optional)
-  // +-------------------------+  (Optional)
-  // | Elf_Shdr NULL           |
-  // | Elf_Shdr .dynsym        |
-  // | Elf_Shdr .dynstr        |
-  // | Elf_Shdr .hash          |
-  // | Elf_Shdr .text          |
-  // | Elf_Shdr .rodata        |
-  // | Elf_Shdr .dynamic       |
-  // | Elf_Shdr .shstrtab      |
-  // | Elf_Shdr .debug_info    |  (Optional)
-  // | Elf_Shdr .debug_abbrev  |  (Optional)
-  // | Elf_Shdr .eh_frame      |  (Optional)
-  // | Elf_Shdr .debug_line    |  (Optional)
-  // | Elf_Shdr .debug_str     |  (Optional)
-  // +-------------------------+
-
-  if (fatal_error_) {
-    return false;
-  }
-  // Step 1. Figure out all the offsets.
-
-  if (debug_logging_) {
-    LOG(INFO) << "phdr_offset=" << PHDR_OFFSET << std::hex << " " << PHDR_OFFSET;
-    LOG(INFO) << "phdr_size=" << PHDR_SIZE << std::hex << " " << PHDR_SIZE;
-  }
-
-  memset(&program_headers_, 0, sizeof(program_headers_));
-  program_headers_[PH_PHDR].p_type    = PT_PHDR;
-  program_headers_[PH_PHDR].p_offset  = PHDR_OFFSET;
-  program_headers_[PH_PHDR].p_vaddr   = PHDR_OFFSET;
-  program_headers_[PH_PHDR].p_paddr   = PHDR_OFFSET;
-  program_headers_[PH_PHDR].p_filesz  = sizeof(program_headers_);
-  program_headers_[PH_PHDR].p_memsz   = sizeof(program_headers_);
-  program_headers_[PH_PHDR].p_flags   = PF_R;
-  program_headers_[PH_PHDR].p_align   = sizeof(Elf_Word);
-
-  program_headers_[PH_LOAD_R__].p_type    = PT_LOAD;
-  program_headers_[PH_LOAD_R__].p_offset  = 0;
-  program_headers_[PH_LOAD_R__].p_vaddr   = 0;
-  program_headers_[PH_LOAD_R__].p_paddr   = 0;
-  program_headers_[PH_LOAD_R__].p_flags   = PF_R;
-
-  program_headers_[PH_LOAD_R_X].p_type    = PT_LOAD;
-  program_headers_[PH_LOAD_R_X].p_flags   = PF_R | PF_X;
-
-  program_headers_[PH_LOAD_RW_].p_type    = PT_LOAD;
-  program_headers_[PH_LOAD_RW_].p_flags   = PF_R | PF_W;
-
-  program_headers_[PH_DYNAMIC].p_type    = PT_DYNAMIC;
-  program_headers_[PH_DYNAMIC].p_flags   = PF_R | PF_W;
-
-  // Get the dynstr string.
-  dynstr_ = dynsym_builder_.GenerateStrtab();
-
-  // Add the SONAME to the dynstr.
-  dynstr_soname_offset_ = dynstr_.size();
-  std::string file_name(elf_file_->GetPath());
-  size_t directory_separator_pos = file_name.rfind('/');
-  if (directory_separator_pos != std::string::npos) {
-    file_name = file_name.substr(directory_separator_pos + 1);
-  }
-  dynstr_ += file_name;
-  dynstr_ += '\0';
-  if (debug_logging_) {
-    LOG(INFO) << "dynstr size (bytes)   =" << dynstr_.size()
-              << std::hex << " " << dynstr_.size();
-    LOG(INFO) << "dynsym size (elements)=" << dynsym_builder_.GetSize()
-              << std::hex << " " << dynsym_builder_.GetSize();
-  }
-
-  // Get the section header string table.
-  shstrtab_ += '\0';
-
-  // Setup sym_undef
-  memset(&null_hdr_, 0, sizeof(null_hdr_));
-  null_hdr_.sh_type = SHT_NULL;
-  null_hdr_.sh_link = SHN_UNDEF;
-  section_ptrs_.push_back(&null_hdr_);
-
-  section_index_ = 1;
-
-  // setup .dynsym
-  section_ptrs_.push_back(&dynsym_builder_.section_);
-  AssignSectionStr(&dynsym_builder_, &shstrtab_);
-  dynsym_builder_.section_index_ = section_index_++;
-
-  // Setup .dynstr
-  section_ptrs_.push_back(&dynsym_builder_.strtab_.section_);
-  AssignSectionStr(&dynsym_builder_.strtab_, &shstrtab_);
-  dynsym_builder_.strtab_.section_index_ = section_index_++;
-
-  // Setup .hash
-  section_ptrs_.push_back(&hash_builder_.section_);
-  AssignSectionStr(&hash_builder_, &shstrtab_);
-  hash_builder_.section_index_ = section_index_++;
-
-  // Setup .rodata
-  section_ptrs_.push_back(&rodata_builder_.section_);
-  AssignSectionStr(&rodata_builder_, &shstrtab_);
-  rodata_builder_.section_index_ = section_index_++;
-
-  // Setup .text
-  section_ptrs_.push_back(&text_builder_.section_);
-  AssignSectionStr(&text_builder_, &shstrtab_);
-  text_builder_.section_index_ = section_index_++;
-
-  // Setup .dynamic
-  section_ptrs_.push_back(&dynamic_builder_.section_);
-  AssignSectionStr(&dynamic_builder_, &shstrtab_);
-  dynamic_builder_.section_index_ = section_index_++;
-
-  // Fill in the hash section.
-  hash_ = dynsym_builder_.GenerateHashContents();
-
-  if (debug_logging_) {
-    LOG(INFO) << ".hash size (bytes)=" << hash_.size() * sizeof(Elf_Word)
-              << std::hex << " " << hash_.size() * sizeof(Elf_Word);
-  }
-
-  Elf_Word base_offset = sizeof(Elf_Ehdr) + sizeof(program_headers_);
-
-  // Get the layout in the sections.
-  //
-  // Get the layout of the dynsym section.
-  dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign);
-  dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset;
-  dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
-  dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();
-
-  // Get the layout of the dynstr section.
-  dynsym_builder_.strtab_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                               (dynsym_builder_.strtab_.section_,
-                                                dynsym_builder_.section_);
-  dynsym_builder_.strtab_.section_.sh_addr = dynsym_builder_.strtab_.section_.sh_offset;
-  dynsym_builder_.strtab_.section_.sh_size = dynstr_.size();
-  dynsym_builder_.strtab_.section_.sh_link = dynsym_builder_.strtab_.GetLink();
-
-  // Get the layout of the hash section
-  hash_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                     (hash_builder_.section_,
-                                      dynsym_builder_.strtab_.section_);
-  hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset;
-  hash_builder_.section_.sh_size = hash_.size() * sizeof(Elf_Word);
-  hash_builder_.section_.sh_link = hash_builder_.GetLink();
-
-  // Get the layout of the rodata section.
-  rodata_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                       (rodata_builder_.section_,
-                                        hash_builder_.section_);
-  rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset;
-  rodata_builder_.section_.sh_size = rodata_builder_.size_;
-  rodata_builder_.section_.sh_link = rodata_builder_.GetLink();
-
-  // Get the layout of the text section.
-  text_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                     (text_builder_.section_, rodata_builder_.section_);
-  text_builder_.section_.sh_addr = text_builder_.section_.sh_offset;
-  text_builder_.section_.sh_size = text_builder_.size_;
-  text_builder_.section_.sh_link = text_builder_.GetLink();
-  CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize);
-
-  // Get the layout of the dynamic section.
-  dynamic_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                        (dynamic_builder_.section_,
-                                         text_builder_.section_);
-  dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset;
-  dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
-  dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();
-
-  if (debug_logging_) {
-    LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset
-              << " dynsym size=" << dynsym_builder_.section_.sh_size;
-    LOG(INFO) << "dynstr off=" << dynsym_builder_.strtab_.section_.sh_offset
-              << " dynstr size=" << dynsym_builder_.strtab_.section_.sh_size;
-    LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset
-              << " hash size=" << hash_builder_.section_.sh_size;
-    LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset
-              << " rodata size=" << rodata_builder_.section_.sh_size;
-    LOG(INFO) << "text off=" << text_builder_.section_.sh_offset
-              << " text size=" << text_builder_.section_.sh_size;
-    LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset
-              << " dynamic size=" << dynamic_builder_.section_.sh_size;
-  }
-
-  return true;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::Write() {
-  std::vector<ElfFilePiece> pieces;
-  Elf_Shdr prev = dynamic_builder_.section_;
-  std::string strtab;
-
-  if (IncludingDebugSymbols()) {
-    // Setup .symtab
-    section_ptrs_.push_back(&symtab_builder_.section_);
-    AssignSectionStr(&symtab_builder_, &shstrtab_);
-    symtab_builder_.section_index_ = section_index_++;
-
-    // Setup .strtab
-    section_ptrs_.push_back(&symtab_builder_.strtab_.section_);
-    AssignSectionStr(&symtab_builder_.strtab_, &shstrtab_);
-    symtab_builder_.strtab_.section_index_ = section_index_++;
-
-    strtab = symtab_builder_.GenerateStrtab();
-    if (debug_logging_) {
-      LOG(INFO) << "strtab size (bytes)    =" << strtab.size()
-                << std::hex << " " << strtab.size();
-      LOG(INFO) << "symtab size (elements) =" << symtab_builder_.GetSize()
-                << std::hex << " " << symtab_builder_.GetSize();
-    }
-  }
-
-  // Setup all the other sections.
-  for (ElfRawSectionBuilder *builder = other_builders_.data(),
-                            *end = builder + other_builders_.size();
-       builder != end; ++builder) {
-    section_ptrs_.push_back(&builder->section_);
-    AssignSectionStr(builder, &shstrtab_);
-    builder->section_index_ = section_index_++;
-  }
-
-  // Setup shstrtab
-  section_ptrs_.push_back(&shstrtab_builder_.section_);
-  AssignSectionStr(&shstrtab_builder_, &shstrtab_);
-  shstrtab_builder_.section_index_ = section_index_++;
-
-  if (debug_logging_) {
-    LOG(INFO) << ".shstrtab size    (bytes)   =" << shstrtab_.size()
-              << std::hex << " " << shstrtab_.size();
-    LOG(INFO) << "section list size (elements)=" << section_ptrs_.size()
-              << std::hex << " " << section_ptrs_.size();
-  }
-
-  if (IncludingDebugSymbols()) {
-    // Get the layout of the symtab section.
-    symtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                         (symtab_builder_.section_,
-                                          dynamic_builder_.section_);
-    symtab_builder_.section_.sh_addr = 0;
-    // Add to leave space for the null symbol.
-    symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
-    symtab_builder_.section_.sh_link = symtab_builder_.GetLink();
-
-    // Get the layout of the dynstr section.
-    symtab_builder_.strtab_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                                 (symtab_builder_.strtab_.section_,
-                                                  symtab_builder_.section_);
-    symtab_builder_.strtab_.section_.sh_addr = 0;
-    symtab_builder_.strtab_.section_.sh_size = strtab.size();
-    symtab_builder_.strtab_.section_.sh_link = symtab_builder_.strtab_.GetLink();
-
-    prev = symtab_builder_.strtab_.section_;
-    if (debug_logging_) {
-      LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset
-                << " symtab size=" << symtab_builder_.section_.sh_size;
-      LOG(INFO) << "strtab off=" << symtab_builder_.strtab_.section_.sh_offset
-                << " strtab size=" << symtab_builder_.strtab_.section_.sh_size;
-    }
-  }
-
-  // Get the layout of the extra sections. (This will deal with the debug
-  // sections if they are there)
-  for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
-    it->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>(it->section_, prev);
-    it->section_.sh_addr = 0;
-    it->section_.sh_size = it->GetBuffer()->size();
-    it->section_.sh_link = it->GetLink();
-    pieces.push_back(ElfFilePiece(it->name_, it->section_.sh_offset,
-                                  it->GetBuffer()->data(), it->GetBuffer()->size()));
-    prev = it->section_;
-    if (debug_logging_) {
-      LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
-                << " " << it->name_ << " size=" << it->section_.sh_size;
-    }
-  }
-
-  // Get the layout of the shstrtab section
-  shstrtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>
-                                         (shstrtab_builder_.section_, prev);
-  shstrtab_builder_.section_.sh_addr = 0;
-  shstrtab_builder_.section_.sh_size = shstrtab_.size();
-  shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink();
-  if (debug_logging_) {
-      LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset
-                << " shstrtab size=" << shstrtab_builder_.section_.sh_size;
-  }
-
-  // The section list comes after come after.
-  Elf_Word sections_offset = RoundUp(
-      shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
-      sizeof(Elf_Word));
-
-  // Setup the actual symbol arrays.
-  std::vector<Elf_Sym> dynsym = dynsym_builder_.GenerateSymtab();
-  CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.section_.sh_size);
-  std::vector<Elf_Sym> symtab;
-  if (IncludingDebugSymbols()) {
-    symtab = symtab_builder_.GenerateSymtab();
-    CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.section_.sh_size);
-  }
-
-  // Setup the dynamic section.
-  // This will add the 2 values we cannot know until now time, namely the size
-  // and the soname_offset.
-  std::vector<Elf_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr_.size(),
-                                                                dynstr_soname_offset_);
-  CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.section_.sh_size);
-
-  // Finish setup of the program headers now that we know the layout of the
-  // whole file.
-  Elf_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size;
-  program_headers_[PH_LOAD_R__].p_filesz = load_r_size;
-  program_headers_[PH_LOAD_R__].p_memsz =  load_r_size;
-  program_headers_[PH_LOAD_R__].p_align =  rodata_builder_.section_.sh_addralign;
-
-  Elf_Word load_rx_size = text_builder_.section_.sh_size;
-  program_headers_[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset;
-  program_headers_[PH_LOAD_R_X].p_vaddr  = text_builder_.section_.sh_offset;
-  program_headers_[PH_LOAD_R_X].p_paddr  = text_builder_.section_.sh_offset;
-  program_headers_[PH_LOAD_R_X].p_filesz = load_rx_size;
-  program_headers_[PH_LOAD_R_X].p_memsz  = load_rx_size;
-  program_headers_[PH_LOAD_R_X].p_align  = text_builder_.section_.sh_addralign;
-
-  program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset;
-  program_headers_[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.section_.sh_offset;
-  program_headers_[PH_LOAD_RW_].p_paddr  = dynamic_builder_.section_.sh_offset;
-  program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size;
-  program_headers_[PH_LOAD_RW_].p_memsz  = dynamic_builder_.section_.sh_size;
-  program_headers_[PH_LOAD_RW_].p_align  = dynamic_builder_.section_.sh_addralign;
-
-  program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset;
-  program_headers_[PH_DYNAMIC].p_vaddr  = dynamic_builder_.section_.sh_offset;
-  program_headers_[PH_DYNAMIC].p_paddr  = dynamic_builder_.section_.sh_offset;
-  program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size;
-  program_headers_[PH_DYNAMIC].p_memsz  = dynamic_builder_.section_.sh_size;
-  program_headers_[PH_DYNAMIC].p_align  = dynamic_builder_.section_.sh_addralign;
-
-  // Finish setup of the Ehdr values.
-  elf_header_.e_phoff = PHDR_OFFSET;
-  elf_header_.e_shoff = sections_offset;
-  elf_header_.e_phnum = PH_NUM;
-  elf_header_.e_shnum = section_ptrs_.size();
-  elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
-
-  // Add the rest of the pieces to the list.
-  pieces.push_back(ElfFilePiece("Elf Header", 0, &elf_header_, sizeof(elf_header_)));
-  pieces.push_back(ElfFilePiece("Program headers", PHDR_OFFSET,
-                                &program_headers_, sizeof(program_headers_)));
-  pieces.push_back(ElfFilePiece(".dynamic", dynamic_builder_.section_.sh_offset,
-                                dynamic.data(), dynamic_builder_.section_.sh_size));
-  pieces.push_back(ElfFilePiece(".dynsym", dynsym_builder_.section_.sh_offset,
-                                dynsym.data(), dynsym.size() * sizeof(Elf_Sym)));
-  pieces.push_back(ElfFilePiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset,
-                                dynstr_.c_str(), dynstr_.size()));
-  pieces.push_back(ElfFilePiece(".hash", hash_builder_.section_.sh_offset,
-                                hash_.data(), hash_.size() * sizeof(Elf_Word)));
-  pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset,
-                                nullptr, rodata_builder_.section_.sh_size));
-  pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset,
-                                nullptr, text_builder_.section_.sh_size));
-  if (IncludingDebugSymbols()) {
-    pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset,
-                                  symtab.data(), symtab.size() * sizeof(Elf_Sym)));
-    pieces.push_back(ElfFilePiece(".strtab", symtab_builder_.strtab_.section_.sh_offset,
-                                  strtab.c_str(), strtab.size()));
-  }
-  pieces.push_back(ElfFilePiece(".shstrtab", shstrtab_builder_.section_.sh_offset,
-                                &shstrtab_[0], shstrtab_.size()));
-  for (uint32_t i = 0; i < section_ptrs_.size(); ++i) {
-    // Just add all the sections in induvidually since they are all over the
-    // place on the heap/stack.
-    Elf_Word cur_off = sections_offset + i * sizeof(Elf_Shdr);
-    pieces.push_back(ElfFilePiece("section table piece", cur_off,
-                                  section_ptrs_[i], sizeof(Elf_Shdr)));
-  }
-
-  if (!WriteOutFile(pieces)) {
-    LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();
-    return false;
-  }
-  // write out the actual oat file data.
-  Elf_Word oat_data_offset = rodata_builder_.section_.sh_offset;
-  if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) {
-    PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset
-                << " for " << elf_file_->GetPath();
-    return false;
-  }
-  std::unique_ptr<BufferedOutputStream> output_stream(
-      new BufferedOutputStream(new FileOutputStream(elf_file_)));
-  if (!oat_writer_->Write(output_stream.get())) {
-    PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath();
-    return false;
-  }
-
-  return true;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::WriteOutFile(const std::vector<ElfFilePiece>& pieces) {
-  // TODO It would be nice if this checked for overlap.
-  for (auto it = pieces.begin(); it != pieces.end(); ++it) {
-    if (it->data_) {
-      if (static_cast<off_t>(it->offset_) != lseek(elf_file_->Fd(), it->offset_, SEEK_SET)) {
-        PLOG(ERROR) << "Failed to seek to " << it->dbg_name_ << " offset location "
-                    << it->offset_ << " for " << elf_file_->GetPath();
-        return false;
-      }
-      if (!elf_file_->WriteFully(it->data_, it->size_)) {
-        PLOG(ERROR) << "Failed to write " << it->dbg_name_ << " for " << elf_file_->GetPath();
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetupDynamic() {
-  dynamic_builder_.AddDynamicTag(DT_HASH, 0, &hash_builder_);
-  dynamic_builder_.AddDynamicTag(DT_STRTAB, 0, &dynsym_builder_.strtab_);
-  dynamic_builder_.AddDynamicTag(DT_SYMTAB, 0, &dynsym_builder_);
-  dynamic_builder_.AddDynamicTag(DT_SYMENT, sizeof(Elf_Sym));
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetupRequiredSymbols() {
-  dynsym_builder_.AddSymbol("oatdata", &rodata_builder_, 0, true,
-                            rodata_builder_.size_, STB_GLOBAL, STT_OBJECT);
-  dynsym_builder_.AddSymbol("oatexec", &text_builder_, 0, true,
-                            text_builder_.size_, STB_GLOBAL, STT_OBJECT);
-  dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.size_ - 4,
-                            true, 4, STB_GLOBAL, STT_OBJECT);
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfDynamicBuilder::AddDynamicTag(Elf_Sword tag, Elf_Word d_un) {
-  if (tag == DT_NULL) {
-    return;
-  }
-  dynamics_.push_back({nullptr, tag, d_un});
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfDynamicBuilder::AddDynamicTag(Elf_Sword tag, Elf_Word d_un,
-                                                      ElfSectionBuilder* section) {
-  if (tag == DT_NULL) {
-    return;
-  }
-  dynamics_.push_back({section, tag, d_un});
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-std::vector<Elf_Dyn> ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfDynamicBuilder::GetDynamics(Elf_Word strsz,
-                                                                    Elf_Word soname) {
-  std::vector<Elf_Dyn> ret;
-  for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
-    if (it->section_) {
-      // We are adding an address relative to a section.
-      ret.push_back(
-          {it->tag_, {it->off_ + it->section_->section_.sh_addr}});
-    } else {
-      ret.push_back({it->tag_, {it->off_}});
-    }
-  }
-  ret.push_back({DT_STRSZ, {strsz}});
-  ret.push_back({DT_SONAME, {soname}});
-  ret.push_back({DT_NULL, {0}});
-  return ret;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-std::vector<Elf_Sym> ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::GenerateSymtab() {
-  std::vector<Elf_Sym> ret;
-  Elf_Sym undef_sym;
-  memset(&undef_sym, 0, sizeof(undef_sym));
-  undef_sym.st_shndx = SHN_UNDEF;
-  ret.push_back(undef_sym);
-
-  for (auto it = symbols_.cbegin(); it != symbols_.cend(); ++it) {
-    Elf_Sym sym;
-    memset(&sym, 0, sizeof(sym));
-    sym.st_name = it->name_idx_;
-    if (it->is_relative_) {
-      sym.st_value = it->addr_ + it->section_->section_.sh_offset;
-    } else {
-      sym.st_value = it->addr_;
-    }
-    sym.st_size = it->size_;
-    sym.st_other = it->other_;
-    sym.st_shndx = it->section_->section_index_;
-    sym.st_info = it->info_;
-
-    ret.push_back(sym);
-  }
-  return ret;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-std::string ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::GenerateStrtab() {
-  std::string tab;
-  tab += '\0';
-  for (auto it = symbols_.begin(); it != symbols_.end(); ++it) {
-    it->name_idx_ = tab.size();
-    tab += it->name_;
-    tab += '\0';
-  }
-  strtab_.section_.sh_size = tab.size();
-  return tab;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::AssignSectionStr(
-    ElfSectionBuilder* builder, std::string* strtab) {
-  builder->section_.sh_name = strtab->size();
-  *strtab += builder->name_;
-  *strtab += '\0';
-  if (debug_logging_) {
-    LOG(INFO) << "adding section name \"" << builder->name_ << "\" "
-              << "to shstrtab at offset " << builder->section_.sh_name;
-  }
-}
-
-// from bionic
-static unsigned elfhash(const char *_name) {
-  const unsigned char *name = (const unsigned char *) _name;
-  unsigned h = 0, g;
-
-  while (*name) {
-    h = (h << 4) + *name++;
-    g = h & 0xf0000000;
-    h ^= g;
-    h ^= g >> 24;
-  }
-  return h;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-std::vector<Elf_Word> ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::GenerateHashContents() {
-  // Here is how The ELF hash table works.
-  // There are 3 arrays to worry about.
-  // * The symbol table where the symbol information is.
-  // * The bucket array which is an array of indexes into the symtab and chain.
-  // * The chain array which is also an array of indexes into the symtab and chain.
-  //
-  // Lets say the state is something like this.
-  // +--------+       +--------+      +-----------+
-  // | symtab |       | bucket |      |   chain   |
-  // |  null  |       | 1      |      | STN_UNDEF |
-  // | <sym1> |       | 4      |      | 2         |
-  // | <sym2> |       |        |      | 5         |
-  // | <sym3> |       |        |      | STN_UNDEF |
-  // | <sym4> |       |        |      | 3         |
-  // | <sym5> |       |        |      | STN_UNDEF |
-  // +--------+       +--------+      +-----------+
-  //
-  // The lookup process (in python psudocode) is
-  //
-  // def GetSym(name):
-  //     # NB STN_UNDEF == 0
-  //     indx = bucket[elfhash(name) % num_buckets]
-  //     while indx != STN_UNDEF:
-  //         if GetSymbolName(symtab[indx]) == name:
-  //             return symtab[indx]
-  //         indx = chain[indx]
-  //     return SYMBOL_NOT_FOUND
-  //
-  // Between bucket and chain arrays every symtab index must be present exactly
-  // once (except for STN_UNDEF, which must be present 1 + num_bucket times).
-
-  // Select number of buckets.
-  // This is essentially arbitrary.
-  Elf_Word nbuckets;
-  Elf_Word chain_size = GetSize();
-  if (symbols_.size() < 8) {
-    nbuckets = 2;
-  } else if (symbols_.size() < 32) {
-    nbuckets = 4;
-  } else if (symbols_.size() < 256) {
-    nbuckets = 16;
-  } else {
-    // Have about 32 ids per bucket.
-    nbuckets = RoundUp(symbols_.size()/32, 2);
-  }
-  std::vector<Elf_Word> hash;
-  hash.push_back(nbuckets);
-  hash.push_back(chain_size);
-  uint32_t bucket_offset = hash.size();
-  uint32_t chain_offset = bucket_offset + nbuckets;
-  hash.resize(hash.size() + nbuckets + chain_size, 0);
-
-  Elf_Word* buckets = hash.data() + bucket_offset;
-  Elf_Word* chain   = hash.data() + chain_offset;
-
-  // Set up the actual hash table.
-  for (Elf_Word i = 0; i < symbols_.size(); i++) {
-    // Add 1 since we need to have the null symbol that is not in the symbols
-    // list.
-    Elf_Word index = i + 1;
-    Elf_Word hash_val = static_cast<Elf_Word>(elfhash(symbols_[i].name_.c_str())) % nbuckets;
-    if (buckets[hash_val] == 0) {
-      buckets[hash_val] = index;
-    } else {
-      hash_val = buckets[hash_val];
-      CHECK_LT(hash_val, chain_size);
-      while (chain[hash_val] != 0) {
-        hash_val = chain[hash_val];
-        CHECK_LT(hash_val, chain_size);
-      }
-      chain[hash_val] = index;
-      // Check for loops. Works because if this is non-empty then there must be
-      // another cell which already contains the same symbol index as this one,
-      // which means some symbol has more then one name, which isn't allowed.
-      CHECK_EQ(chain[index], static_cast<Elf_Word>(0));
-    }
-  }
-
-  return hash;
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetupEhdr() {
-  memset(&elf_header_, 0, sizeof(elf_header_));
-  elf_header_.e_ident[EI_MAG0]       = ELFMAG0;
-  elf_header_.e_ident[EI_MAG1]       = ELFMAG1;
-  elf_header_.e_ident[EI_MAG2]       = ELFMAG2;
-  elf_header_.e_ident[EI_MAG3]       = ELFMAG3;
-  elf_header_.e_ident[EI_CLASS]      = ELFCLASS32;
-  elf_header_.e_ident[EI_DATA]       = ELFDATA2LSB;
-  elf_header_.e_ident[EI_VERSION]    = EV_CURRENT;
-  elf_header_.e_ident[EI_OSABI]      = ELFOSABI_LINUX;
-  elf_header_.e_ident[EI_ABIVERSION] = 0;
-  elf_header_.e_type = ET_DYN;
-  elf_header_.e_version = 1;
-  elf_header_.e_entry = 0;
-  elf_header_.e_ehsize = sizeof(Elf_Ehdr);
-  elf_header_.e_phentsize = sizeof(Elf_Phdr);
-  elf_header_.e_shentsize = sizeof(Elf_Shdr);
-  elf_header_.e_phoff = sizeof(Elf_Ehdr);
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetISA(InstructionSet isa) {
-  switch (isa) {
-    case kArm:
-      // Fall through.
-    case kThumb2: {
-      elf_header_.e_machine = EM_ARM;
-      elf_header_.e_flags = EF_ARM_EABI_VER5;
-      break;
-    }
-    case kArm64: {
-      elf_header_.e_machine = EM_AARCH64;
-      elf_header_.e_flags = 0;
-      break;
-    }
-    case kX86: {
-      elf_header_.e_machine = EM_386;
-      elf_header_.e_flags = 0;
-      break;
-    }
-    case kX86_64: {
-      elf_header_.e_machine = EM_X86_64;
-      elf_header_.e_flags = 0;
-      break;
-    }
-    case kMips: {
-      elf_header_.e_machine = EM_MIPS;
-      elf_header_.e_flags = (EF_MIPS_NOREORDER |
-                             EF_MIPS_PIC       |
-                             EF_MIPS_CPIC      |
-                             EF_MIPS_ABI_O32   |
-                             EF_MIPS_ARCH_32R2);
-      break;
-    }
-    default: {
-      fatal_error_ = true;
-      LOG(FATAL) << "Unknown instruction set: " << isa;
-      break;
-    }
-  }
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::AddSymbol(
-    const std::string& name, const ElfSectionBuilder* section, Elf_Addr addr,
-    bool is_relative, Elf_Word size, uint8_t binding, uint8_t type, uint8_t other) {
-  CHECK(section);
-  ElfSymtabBuilder::ElfSymbolState state {name, section, addr, size, is_relative,
-                                          MakeStInfo(binding, type), other, 0};
-  symbols_.push_back(state);
-}
-
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
   Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
                             OatWriter* oat_writer,
                             const std::vector<const DexFile*>& dex_files,
@@ -913,17 +85,14 @@
   return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
 // Add patch information to this section. Each patch is a Elf_Word that
 // identifies an offset from the start of the text section
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug) {
+static void ReservePatchSpace(const CompilerDriver* compiler_driver, std::vector<uint8_t>* buffer,
+                              bool debug) {
   size_t size =
-      compiler_driver_->GetCodeToPatch().size() +
-      compiler_driver_->GetMethodsToPatch().size() +
-      compiler_driver_->GetClassesToPatch().size();
+      compiler_driver->GetCodeToPatch().size() +
+      compiler_driver->GetMethodsToPatch().size() +
+      compiler_driver->GetClassesToPatch().size();
   if (size == 0) {
     if (debug) {
       LOG(INFO) << "No patches to record";
@@ -1046,6 +215,25 @@
   }
 }
 
+class OatWriterWrapper : public CodeOutput {
+ public:
+  explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
+
+  bool Write(OutputStream* out) OVERRIDE {
+    return oat_writer_->Write(out);
+  }
+ private:
+  OatWriter* oat_writer_;
+};
+
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
+          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
+          typename Elf_Phdr, typename Elf_Shdr>
+static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
+                              ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
+                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
+                              OatWriter* oat_writer);
+
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
           typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
           typename Elf_Phdr, typename Elf_Shdr>
@@ -1059,145 +247,40 @@
   Elf_Word oat_data_size = oat_header.GetExecutableOffset();
   uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
 
-  std::unique_ptr<ElfBuilder> builder(new ElfBuilder(
-      oat_writer,
-      elf_file_,
-      compiler_driver_->GetInstructionSet(),
-      0,
-      oat_data_size,
-      oat_data_size,
-      oat_exec_size,
-      compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
-      debug));
+  OatWriterWrapper wrapper(oat_writer);
+
+  std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
+                             Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
+      new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
+                     Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
+          &wrapper,
+          elf_file_,
+          compiler_driver_->GetInstructionSet(),
+          0,
+          oat_data_size,
+          oat_data_size,
+          oat_exec_size,
+          compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
+          debug));
 
   if (!builder->Init()) {
     return false;
   }
 
   if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
-    WriteDebugSymbols(builder.get(), oat_writer);
+    WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
   }
 
   if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
-    ElfRawSectionBuilder oat_patches(".oat_patches", SHT_OAT_PATCH, 0, NULL, 0,
-                                     sizeof(uintptr_t), sizeof(uintptr_t));
-    ReservePatchSpace(oat_patches.GetBuffer(), debug);
+    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
+        ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
+    ReservePatchSpace(compiler_driver_, oat_patches.GetBuffer(), debug);
     builder->RegisterRawSection(oat_patches);
   }
 
   return builder->Write();
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::WriteDebugSymbols(ElfBuilder* builder, OatWriter* oat_writer) {
-  std::unique_ptr<std::vector<uint8_t>> cfi_info(
-      ConstructCIEFrame(compiler_driver_->GetInstructionSet()));
-
-  Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr;
-
-  // Iterate over the compiled methods.
-  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
-  ElfSymtabBuilder* symtab = &builder->symtab_builder_;
-  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
-    symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true,
-                      it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
-
-    // Include CFI for compiled method, if possible.
-    if (cfi_info.get() != nullptr) {
-      DCHECK(it->compiled_method_ != nullptr);
-
-      // Copy in the FDE, if present
-      const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
-      if (fde != nullptr) {
-        // Copy the information into cfi_info and then fix the address in the new copy.
-        int cur_offset = cfi_info->size();
-        cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
-
-        bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
-
-        // Set the 'CIE_pointer' field.
-        uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
-        uint64_t offset_to_update = CIE_pointer;
-        if (is_64bit) {
-          (*cfi_info)[offset_to_update+0] = CIE_pointer;
-          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
-          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
-          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
-          (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
-          (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
-          (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
-          (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
-        } else {
-          (*cfi_info)[offset_to_update+0] = CIE_pointer;
-          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
-          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
-          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
-        }
-
-        // Set the 'initial_location' field.
-        offset_to_update += is_64bit ? 8 : 4;
-        if (is_64bit) {
-          const uint64_t quick_code_start = it->low_pc_ + text_section_address;
-          (*cfi_info)[offset_to_update+0] = quick_code_start;
-          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
-          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
-          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
-          (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
-          (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
-          (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
-          (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
-        } else {
-          const uint32_t quick_code_start = it->low_pc_ + text_section_address;
-          (*cfi_info)[offset_to_update+0] = quick_code_start;
-          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
-          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
-          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
-        }
-      }
-    }
-  }
-
-  bool hasCFI = (cfi_info.get() != nullptr);
-  bool hasLineInfo = false;
-  for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
-    if (dbg_info.dbgstream_ != nullptr &&
-        !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
-      hasLineInfo = true;
-      break;
-    }
-  }
-
-  if (hasLineInfo || hasCFI) {
-    ElfRawSectionBuilder debug_info(".debug_info",     SHT_PROGBITS, 0, nullptr, 0, 1, 0);
-    ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
-    ElfRawSectionBuilder debug_str(".debug_str",       SHT_PROGBITS, 0, nullptr, 0, 1, 0);
-    ElfRawSectionBuilder debug_line(".debug_line",     SHT_PROGBITS, 0, nullptr, 0, 1, 0);
-
-    FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
-                         debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
-                         hasLineInfo ? debug_line.GetBuffer() : nullptr,
-                         text_section_address);
-
-    builder->RegisterRawSection(debug_info);
-    builder->RegisterRawSection(debug_abbrev);
-
-    if (hasCFI) {
-      ElfRawSectionBuilder eh_frame(".eh_frame",  SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0);
-      eh_frame.SetBuffer(std::move(*cfi_info.get()));
-      builder->RegisterRawSection(eh_frame);
-    }
-
-    if (hasLineInfo) {
-      builder->RegisterRawSection(debug_line);
-    }
-
-    builder->RegisterRawSection(debug_str);
-  }
-}
-
 class LineTableGenerator FINAL : public Leb128Encoder {
  public:
   LineTableGenerator(int line_base, int line_range, int opcode_base,
@@ -1353,16 +436,19 @@
   }
 }
 
-template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
-          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
-          typename Elf_Phdr, typename Elf_Shdr>
-void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
-  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::FillInCFIInformation(OatWriter* oat_writer,
-                                          std::vector<uint8_t>* dbg_info,
-                                          std::vector<uint8_t>* dbg_abbrev,
-                                          std::vector<uint8_t>* dbg_str,
-                                          std::vector<uint8_t>* dbg_line,
-                                          uint32_t text_section_offset) {
+/*
+ * @brief Generate the DWARF debug_info and debug_abbrev sections
+ * @param oat_writer The Oat file Writer.
+ * @param dbg_info Compilation unit information.
+ * @param dbg_abbrev Abbreviations used to generate dbg_info.
+ * @param dbg_str Debug strings.
+ */
+static void FillInCFIInformation(OatWriter* oat_writer,
+                                 std::vector<uint8_t>* dbg_info,
+                                 std::vector<uint8_t>* dbg_abbrev,
+                                 std::vector<uint8_t>* dbg_str,
+                                 std::vector<uint8_t>* dbg_line,
+                                 uint32_t text_section_offset) {
   const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
 
   uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
@@ -1591,6 +677,130 @@
   UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
 }
 
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
+          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
+          typename Elf_Phdr, typename Elf_Shdr>
+static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
+                              ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
+                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
+                              OatWriter* oat_writer) {
+  std::unique_ptr<std::vector<uint8_t>> cfi_info(
+      ConstructCIEFrame(compiler_driver->GetInstructionSet()));
+
+  Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr;
+
+  // Iterate over the compiled methods.
+  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
+  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr,
+                   Elf_Sym, Elf_Shdr>* symtab = &builder->symtab_builder_;
+  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
+    symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true,
+                      it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
+
+    // Include CFI for compiled method, if possible.
+    if (cfi_info.get() != nullptr) {
+      DCHECK(it->compiled_method_ != nullptr);
+
+      // Copy in the FDE, if present
+      const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
+      if (fde != nullptr) {
+        // Copy the information into cfi_info and then fix the address in the new copy.
+        int cur_offset = cfi_info->size();
+        cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
+
+        bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
+
+        // Set the 'CIE_pointer' field.
+        uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
+        uint64_t offset_to_update = CIE_pointer;
+        if (is_64bit) {
+          (*cfi_info)[offset_to_update+0] = CIE_pointer;
+          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
+          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
+          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
+          (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
+          (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
+          (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
+          (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
+        } else {
+          (*cfi_info)[offset_to_update+0] = CIE_pointer;
+          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
+          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
+          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
+        }
+
+        // Set the 'initial_location' field.
+        offset_to_update += is_64bit ? 8 : 4;
+        if (is_64bit) {
+          const uint64_t quick_code_start = it->low_pc_ + text_section_address;
+          (*cfi_info)[offset_to_update+0] = quick_code_start;
+          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
+          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
+          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
+          (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
+          (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
+          (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
+          (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
+        } else {
+          const uint32_t quick_code_start = it->low_pc_ + text_section_address;
+          (*cfi_info)[offset_to_update+0] = quick_code_start;
+          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
+          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
+          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
+        }
+      }
+    }
+  }
+
+  bool hasCFI = (cfi_info.get() != nullptr);
+  bool hasLineInfo = false;
+  for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
+    if (dbg_info.dbgstream_ != nullptr &&
+        !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
+      hasLineInfo = true;
+      break;
+    }
+  }
+
+  if (hasLineInfo || hasCFI) {
+    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
+                                                                   SHT_PROGBITS,
+                                                                   0, nullptr, 0, 1, 0);
+    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
+                                                                     SHT_PROGBITS,
+                                                                     0, nullptr, 0, 1, 0);
+    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
+                                                                  SHT_PROGBITS,
+                                                                  0, nullptr, 0, 1, 0);
+    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
+                                                                   SHT_PROGBITS,
+                                                                   0, nullptr, 0, 1, 0);
+
+    FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
+                         debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
+                         hasLineInfo ? debug_line.GetBuffer() : nullptr,
+                         text_section_address);
+
+    builder->RegisterRawSection(debug_info);
+    builder->RegisterRawSection(debug_abbrev);
+
+    if (hasCFI) {
+      ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
+                                                                   SHT_PROGBITS,
+                                                                   SHF_ALLOC,
+                                                                   nullptr, 0, 4, 0);
+      eh_frame.SetBuffer(std::move(*cfi_info.get()));
+      builder->RegisterRawSection(eh_frame);
+    }
+
+    if (hasLineInfo) {
+      builder->RegisterRawSection(debug_line);
+    }
+
+    builder->RegisterRawSection(debug_str);
+  }
+}
+
 // Explicit instantiations
 template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
                               Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index 890528e..4990ed0 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -19,7 +19,6 @@
 
 #include "elf_utils.h"
 #include "elf_writer.h"
-#include "instruction_set.h"
 
 namespace art {
 
@@ -50,300 +49,6 @@
     : ElfWriter(driver, elf_file) {}
   ~ElfWriterQuick() {}
 
-  class ElfBuilder;
-  void WriteDebugSymbols(ElfBuilder* builder, OatWriter* oat_writer);
-  void ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug);
-
-  class ElfSectionBuilder {
-   public:
-    ElfSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
-                      const ElfSectionBuilder *link, Elf_Word info, Elf_Word align,
-                      Elf_Word entsize)
-        : name_(sec_name), link_(link) {
-      memset(&section_, 0, sizeof(section_));
-      section_.sh_type = type;
-      section_.sh_flags = flags;
-      section_.sh_info = info;
-      section_.sh_addralign = align;
-      section_.sh_entsize = entsize;
-    }
-
-    virtual ~ElfSectionBuilder() {}
-
-    Elf_Shdr section_;
-    Elf_Word section_index_ = 0;
-
-   protected:
-    const std::string name_;
-    const ElfSectionBuilder* link_;
-
-    Elf_Word GetLink() {
-      return (link_) ? link_->section_index_ : 0;
-    }
-
-   private:
-    friend class ElfBuilder;
-  };
-
-  class ElfDynamicBuilder : public ElfSectionBuilder {
-   public:
-    void AddDynamicTag(Elf_Sword tag, Elf_Word d_un);
-    void AddDynamicTag(Elf_Sword tag, Elf_Word offset, ElfSectionBuilder* section);
-
-    ElfDynamicBuilder(const std::string& sec_name, ElfSectionBuilder *link)
-        : ElfSectionBuilder(sec_name, SHT_DYNAMIC, SHF_ALLOC | SHF_ALLOC, link,
-                            0, kPageSize, sizeof(Elf_Dyn)) {}
-    ~ElfDynamicBuilder() {}
-
-   protected:
-    struct ElfDynamicState {
-      ElfSectionBuilder* section_;
-      Elf_Sword tag_;
-      Elf_Word off_;
-    };
-    std::vector<ElfDynamicState> dynamics_;
-    Elf_Word GetSize() {
-      // Add 1 for the DT_NULL, 1 for DT_STRSZ, and 1 for DT_SONAME. All of
-      // these must be added when we actually put the file together because
-      // their values are very dependent on state.
-      return dynamics_.size() + 3;
-    }
-
-    // Create the actual dynamic vector. strsz should be the size of the .dynstr
-    // table and soname_off should be the offset of the soname in .dynstr.
-    // Since niether can be found prior to final layout we will wait until here
-    // to add them.
-    std::vector<Elf_Dyn> GetDynamics(Elf_Word strsz, Elf_Word soname_off);
-
-   private:
-    friend class ElfBuilder;
-  };
-
-  class ElfRawSectionBuilder : public ElfSectionBuilder {
-   public:
-    ElfRawSectionBuilder(const std::string& sec_name, Elf_Word type, Elf_Word flags,
-                         const ElfSectionBuilder* link, Elf_Word info, Elf_Word align,
-                         Elf_Word entsize)
-        : ElfSectionBuilder(sec_name, type, flags, link, info, align, entsize) {}
-    ~ElfRawSectionBuilder() {}
-    std::vector<uint8_t>* GetBuffer() { return &buf_; }
-    void SetBuffer(std::vector<uint8_t>&& buf) { buf_ = buf; }
-
-   protected:
-    std::vector<uint8_t> buf_;
-
-   private:
-    friend class ElfBuilder;
-  };
-
-  class ElfOatSectionBuilder : public ElfSectionBuilder {
-   public:
-    ElfOatSectionBuilder(const std::string& sec_name, Elf_Word size, Elf_Word offset,
-                         Elf_Word type, Elf_Word flags)
-        : ElfSectionBuilder(sec_name, type, flags, NULL, 0, kPageSize, 0),
-          offset_(offset), size_(size) {}
-    ~ElfOatSectionBuilder() {}
-
-   protected:
-    // Offset of the content within the file.
-    Elf_Word offset_;
-    // Size of the content within the file.
-    Elf_Word size_;
-
-   private:
-    friend class ElfBuilder;
-  };
-
-  class ElfSymtabBuilder : public ElfSectionBuilder {
-   public:
-    // Add a symbol with given name to this symtab. The symbol refers to
-    // 'relative_addr' within the given section and has the given attributes.
-    void AddSymbol(const std::string& name,
-                   const ElfSectionBuilder* section,
-                   Elf_Addr addr,
-                   bool is_relative,
-                   Elf_Word size,
-                   uint8_t binding,
-                   uint8_t type,
-                   uint8_t other = 0);
-
-    ElfSymtabBuilder(const std::string& sec_name, Elf_Word type,
-                     const std::string& str_name, Elf_Word str_type, bool alloc)
-        : ElfSectionBuilder(sec_name, type, ((alloc) ? SHF_ALLOC : 0U), &strtab_, 0,
-                            sizeof(Elf_Word), sizeof(Elf_Sym)),
-          str_name_(str_name), str_type_(str_type),
-          strtab_(str_name, str_type, ((alloc) ? SHF_ALLOC : 0U), NULL, 0, 1, 1) {}
-    ~ElfSymtabBuilder() {}
-
-   protected:
-    std::vector<Elf_Word> GenerateHashContents();
-    std::string GenerateStrtab();
-    std::vector<Elf_Sym> GenerateSymtab();
-
-    Elf_Word GetSize() {
-      // 1 is for the implicit NULL symbol.
-      return symbols_.size() + 1;
-    }
-
-    struct ElfSymbolState {
-      const std::string name_;
-      const ElfSectionBuilder* section_;
-      Elf_Addr addr_;
-      Elf_Word size_;
-      bool is_relative_;
-      uint8_t info_;
-      uint8_t other_;
-      // Used during Write() to temporarially hold name index in the strtab.
-      Elf_Word name_idx_;
-    };
-
-    // Information for the strsym for dynstr sections.
-    const std::string str_name_;
-    Elf_Word str_type_;
-    // The symbols in the same order they will be in the symbol table.
-    std::vector<ElfSymbolState> symbols_;
-    ElfSectionBuilder strtab_;
-
-   private:
-    friend class ElfBuilder;
-  };
-
-  class ElfBuilder FINAL {
-   public:
-    ElfBuilder(OatWriter* oat_writer,
-               File* elf_file,
-               InstructionSet isa,
-               Elf_Word rodata_relative_offset,
-               Elf_Word rodata_size,
-               Elf_Word text_relative_offset,
-               Elf_Word text_size,
-               const bool add_symbols,
-               bool debug = false)
-        : oat_writer_(oat_writer),
-          elf_file_(elf_file),
-          add_symbols_(add_symbols),
-          debug_logging_(debug),
-          text_builder_(".text", text_size, text_relative_offset, SHT_PROGBITS,
-                        SHF_ALLOC | SHF_EXECINSTR),
-          rodata_builder_(".rodata", rodata_size, rodata_relative_offset,
-                          SHT_PROGBITS, SHF_ALLOC),
-          dynsym_builder_(".dynsym", SHT_DYNSYM, ".dynstr", SHT_STRTAB, true),
-          symtab_builder_(".symtab", SHT_SYMTAB, ".strtab", SHT_STRTAB, false),
-          hash_builder_(".hash", SHT_HASH, SHF_ALLOC, &dynsym_builder_, 0,
-                        sizeof(Elf_Word), sizeof(Elf_Word)),
-          dynamic_builder_(".dynamic", &dynsym_builder_),
-          shstrtab_builder_(".shstrtab", SHT_STRTAB, 0, NULL, 0, 1, 1) {
-      SetupEhdr();
-      SetupDynamic();
-      SetupRequiredSymbols();
-      SetISA(isa);
-    }
-    ~ElfBuilder() {}
-
-    bool Init();
-    bool Write();
-
-    // Adds the given raw section to the builder. This will copy it. The caller
-    // is responsible for deallocating their copy.
-    void RegisterRawSection(ElfRawSectionBuilder bld) {
-      other_builders_.push_back(bld);
-    }
-
-   private:
-    OatWriter* oat_writer_;
-    File* elf_file_;
-    const bool add_symbols_;
-    const bool debug_logging_;
-
-    bool fatal_error_ = false;
-
-    // What phdr is.
-    static const uint32_t PHDR_OFFSET = sizeof(Elf_Ehdr);
-    enum : uint8_t {
-      PH_PHDR     = 0,
-      PH_LOAD_R__ = 1,
-      PH_LOAD_R_X = 2,
-      PH_LOAD_RW_ = 3,
-      PH_DYNAMIC  = 4,
-      PH_NUM      = 5,
-    };
-    static const uint32_t PHDR_SIZE = sizeof(Elf_Phdr) * PH_NUM;
-    Elf_Phdr program_headers_[PH_NUM];
-
-    Elf_Ehdr elf_header_;
-
-    Elf_Shdr null_hdr_;
-    std::string shstrtab_;
-    uint32_t section_index_;
-    std::string dynstr_;
-    uint32_t dynstr_soname_offset_;
-    std::vector<Elf_Shdr*> section_ptrs_;
-    std::vector<Elf_Word> hash_;
-
-   public:
-    ElfOatSectionBuilder text_builder_;
-    ElfOatSectionBuilder rodata_builder_;
-    ElfSymtabBuilder dynsym_builder_;
-    ElfSymtabBuilder symtab_builder_;
-    ElfSectionBuilder hash_builder_;
-    ElfDynamicBuilder dynamic_builder_;
-    ElfSectionBuilder shstrtab_builder_;
-    std::vector<ElfRawSectionBuilder> other_builders_;
-
-   private:
-    void SetISA(InstructionSet isa);
-    void SetupEhdr();
-
-    // Sets up a bunch of the required Dynamic Section entries.
-    // Namely it will initialize all the mandatory ones that it can.
-    // Specifically:
-    // DT_HASH
-    // DT_STRTAB
-    // DT_SYMTAB
-    // DT_SYMENT
-    //
-    // Some such as DT_SONAME, DT_STRSZ and DT_NULL will be put in later.
-    void SetupDynamic();
-
-    // Sets up the basic dynamic symbols that are needed, namely all those we
-    // can know already.
-    //
-    // Specifically adds:
-    // oatdata
-    // oatexec
-    // oatlastword
-    void SetupRequiredSymbols();
-    void AssignSectionStr(ElfSectionBuilder *builder, std::string* strtab);
-    struct ElfFilePiece {
-      ElfFilePiece(const std::string& name, Elf_Word offset, const void* data, Elf_Word size)
-          : dbg_name_(name), offset_(offset), data_(data), size_(size) {}
-      ~ElfFilePiece() {}
-
-      const std::string& dbg_name_;
-      Elf_Word offset_;
-      const void *data_;
-      Elf_Word size_;
-      static bool Compare(ElfFilePiece a, ElfFilePiece b) {
-        return a.offset_ < b.offset_;
-      }
-    };
-
-    // Write each of the pieces out to the file.
-    bool WriteOutFile(const std::vector<ElfFilePiece>& pieces);
-    bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; }
-  };
-
-  /*
-   * @brief Generate the DWARF debug_info and debug_abbrev sections
-   * @param oat_writer The Oat file Writer.
-   * @param dbg_info Compilation unit information.
-   * @param dbg_abbrev Abbreviations used to generate dbg_info.
-   * @param dbg_str Debug strings.
-   */
-  void FillInCFIInformation(OatWriter* oat_writer, std::vector<uint8_t>* dbg_info,
-                            std::vector<uint8_t>* dbg_abbrev, std::vector<uint8_t>* dbg_str,
-                            std::vector<uint8_t>* dbg_line, uint32_t text_section_offset);
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick);
 };
 
diff --git a/oatdump/Android.mk b/oatdump/Android.mk
index c35ff85..25d10bd 100644
--- a/oatdump/Android.mk
+++ b/oatdump/Android.mk
@@ -22,17 +22,17 @@
 	oatdump.cc
 
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
-  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libcutils libart-disassembler,art/disassembler,target,ndebug))
+  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libcutils libart-disassembler libart-compiler,art/disassembler art/compiler,target,ndebug))
 endif
 ifeq ($(ART_BUILD_TARGET_DEBUG),true)
-  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libcutils libartd-disassembler,art/disassembler,target,debug))
+  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libcutils libartd-disassembler libart-compiler,art/disassembler art/compiler,target,debug))
 endif
 
 ifeq ($(ART_BUILD_HOST_NDEBUG),true)
-  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libart-disassembler,art/disassembler,host,ndebug))
+  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libart-disassembler libart-compiler,art/disassembler art/compiler,host,ndebug))
 endif
 ifeq ($(ART_BUILD_HOST_DEBUG),true)
-  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libartd-disassembler,art/disassembler,host,debug))
+  $(eval $(call build-art-executable,oatdump,$(OATDUMP_SRC_FILES),libartd-disassembler libart-compiler,art/disassembler art/compiler,host,debug))
 endif
 
 ########################################################################
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 931ee56..fff42f6 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -20,6 +20,7 @@
 #include <fstream>
 #include <iostream>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 #include "base/stringpiece.h"
@@ -29,6 +30,7 @@
 #include "dex_file-inl.h"
 #include "dex_instruction.h"
 #include "disassembler.h"
+#include "elf_builder.h"
 #include "field_helper.h"
 #include "gc_map.h"
 #include "gc/space/image_space.h"
@@ -47,6 +49,7 @@
 #include "oat.h"
 #include "oat_file-inl.h"
 #include "os.h"
+#include "output_stream.h"
 #include "runtime.h"
 #include "safe_map.h"
 #include "scoped_thread_state_change.h"
@@ -105,6 +108,224 @@
   "kClassRoots",
 };
 
+class OatSymbolizer : public CodeOutput {
+ public:
+  explicit OatSymbolizer(const OatFile* oat_file, std::string& output_name) :
+      oat_file_(oat_file), builder_(nullptr), elf_output_(nullptr), output_name_(output_name) {}
+
+  bool Init() {
+    Elf32_Word oat_data_size = oat_file_->GetOatHeader().GetExecutableOffset();
+
+    uint32_t diff = static_cast<uint32_t>(oat_file_->End() - oat_file_->Begin());
+    uint32_t oat_exec_size = diff - oat_data_size;
+
+    if (output_name_.empty()) {
+      output_name_ = "symbolized.oat";
+    }
+    elf_output_ = OS::CreateEmptyFile(output_name_.c_str());
+
+    builder_.reset(new ElfBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
+                                  Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(
+        this,
+        elf_output_,
+        oat_file_->GetOatHeader().GetInstructionSet(),
+        0,
+        oat_data_size,
+        oat_data_size,
+        oat_exec_size,
+        true,
+        false));
+
+    if (!builder_->Init()) {
+      builder_.reset(nullptr);
+      return false;
+    }
+
+    return true;
+  }
+
+  typedef void (OatSymbolizer::*Callback)(const DexFile::ClassDef&,
+                                          uint32_t,
+                                          const OatFile::OatMethod&,
+                                          const DexFile&,
+                                          uint32_t,
+                                          const DexFile::CodeItem*,
+                                          uint32_t);
+
+  bool Symbolize() {
+    if (builder_.get() == nullptr) {
+      return false;
+    }
+
+    Walk(&art::OatSymbolizer::RegisterForDedup);
+
+    NormalizeState();
+
+    Walk(&art::OatSymbolizer::AddSymbol);
+
+    bool result = builder_->Write();
+
+    elf_output_->Flush();
+    elf_output_->Close();
+
+    return result;
+  }
+
+  void Walk(Callback callback) {
+    std::vector<const OatFile::OatDexFile*> oat_dex_files = oat_file_->GetOatDexFiles();
+    for (size_t i = 0; i < oat_dex_files.size(); i++) {
+      const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i];
+      CHECK(oat_dex_file != NULL);
+      WalkOatDexFile(oat_dex_file, callback);
+    }
+  }
+
+  void WalkOatDexFile(const OatFile::OatDexFile* oat_dex_file, Callback callback) {
+    std::string error_msg;
+    std::unique_ptr<const DexFile> dex_file(oat_dex_file->OpenDexFile(&error_msg));
+    if (dex_file.get() == nullptr) {
+      return;
+    }
+    for (size_t class_def_index = 0;
+        class_def_index < dex_file->NumClassDefs();
+        class_def_index++) {
+      const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
+      const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
+      OatClassType type = oat_class.GetType();
+      switch (type) {
+        case kOatClassAllCompiled:
+        case kOatClassSomeCompiled:
+          WalkOatClass(oat_class, *dex_file.get(), class_def, callback);
+          break;
+
+        case kOatClassNoneCompiled:
+        case kOatClassMax:
+          // Ignore.
+          break;
+      }
+    }
+  }
+
+  void WalkOatClass(const OatFile::OatClass& oat_class, const DexFile& dex_file,
+                    const DexFile::ClassDef& class_def, Callback callback) {
+    const byte* class_data = dex_file.GetClassData(class_def);
+    if (class_data == nullptr) {  // empty class such as a marker interface?
+      return;
+    }
+    // Note: even if this is an interface or a native class, we still have to walk it, as there
+    //       might be a static initializer.
+    ClassDataItemIterator it(dex_file, class_data);
+    SkipAllFields(&it);
+    uint32_t class_method_idx = 0;
+    while (it.HasNextDirectMethod()) {
+      const OatFile::OatMethod oat_method = oat_class.GetOatMethod(class_method_idx);
+      WalkOatMethod(class_def, class_method_idx, oat_method, dex_file, it.GetMemberIndex(),
+                    it.GetMethodCodeItem(), it.GetMemberAccessFlags(), callback);
+      class_method_idx++;
+      it.Next();
+    }
+    while (it.HasNextVirtualMethod()) {
+      const OatFile::OatMethod oat_method = oat_class.GetOatMethod(class_method_idx);
+      WalkOatMethod(class_def, class_method_idx, oat_method, dex_file, it.GetMemberIndex(),
+                    it.GetMethodCodeItem(), it.GetMemberAccessFlags(), callback);
+      class_method_idx++;
+      it.Next();
+    }
+    DCHECK(!it.HasNext());
+  }
+
+  void WalkOatMethod(const DexFile::ClassDef& class_def, uint32_t class_method_index,
+                     const OatFile::OatMethod& oat_method, const DexFile& dex_file,
+                     uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
+                     uint32_t method_access_flags, Callback callback) {
+    if ((method_access_flags & kAccAbstract) != 0) {
+      // Abstract method, no code.
+      return;
+    }
+    if (oat_method.GetCodeOffset() == 0) {
+      // No code.
+      return;
+    }
+
+    (this->*callback)(class_def, class_method_index, oat_method, dex_file, dex_method_idx, code_item,
+                      method_access_flags);
+  }
+
+  void RegisterForDedup(const DexFile::ClassDef& class_def, uint32_t class_method_index,
+                        const OatFile::OatMethod& oat_method, const DexFile& dex_file,
+                        uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
+                        uint32_t method_access_flags) {
+    state_[oat_method.GetCodeOffset()]++;
+  }
+
+  void NormalizeState() {
+    for (auto& x : state_) {
+      if (x.second == 1) {
+        state_[x.first] = 0;
+      }
+    }
+  }
+
+  enum class DedupState {  // private
+    kNotDeduplicated,
+    kDeduplicatedFirst,
+    kDeduplicatedOther
+  };
+  DedupState IsDuplicated(uint32_t offset) {
+    if (state_[offset] == 0) {
+      return DedupState::kNotDeduplicated;
+    }
+    if (state_[offset] == 1) {
+      return DedupState::kDeduplicatedOther;
+    }
+    state_[offset] = 1;
+    return DedupState::kDeduplicatedFirst;
+  }
+
+  void AddSymbol(const DexFile::ClassDef& class_def, uint32_t class_method_index,
+                 const OatFile::OatMethod& oat_method, const DexFile& dex_file,
+                 uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
+                 uint32_t method_access_flags) {
+    DedupState dedup = IsDuplicated(oat_method.GetCodeOffset());
+    if (dedup != DedupState::kDeduplicatedOther) {
+      std::string pretty_name = PrettyMethod(dex_method_idx, dex_file, true);
+
+      if (dedup == DedupState::kDeduplicatedFirst) {
+        pretty_name = "[Dedup]" + pretty_name;
+      }
+
+      ElfSymtabBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr,
+      Elf32_Sym, Elf32_Shdr>* symtab = &builder_->symtab_builder_;
+
+      symtab->AddSymbol(pretty_name, &builder_->text_builder_, oat_method.GetCodeOffset() -
+                        oat_file_->GetOatHeader().GetExecutableOffset(), true,
+                        oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
+    }
+  }
+
+  // Write oat code. Required by ElfBuilder/CodeOutput.
+  bool Write(OutputStream* out) {
+    return out->WriteFully(oat_file_->Begin(), oat_file_->End() - oat_file_->Begin());
+  }
+
+ private:
+  static void SkipAllFields(ClassDataItemIterator* it) {
+    while (it->HasNextStaticField()) {
+      it->Next();
+    }
+    while (it->HasNextInstanceField()) {
+      it->Next();
+    }
+  }
+
+  const OatFile* oat_file_;
+  std::unique_ptr<ElfBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
+                              Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr> > builder_;
+  File* elf_output_;
+  std::unordered_map<uint32_t, uint32_t> state_;
+  std::string output_name_;
+};
+
 class OatDumper {
  public:
   explicit OatDumper(const OatFile& oat_file, bool dump_raw_mapping_table, bool dump_raw_gc_map)
@@ -1537,8 +1758,10 @@
   std::string elf_filename_prefix;
   std::ostream* os = &std::cout;
   std::unique_ptr<std::ofstream> out;
+  std::string output_name;
   bool dump_raw_mapping_table = false;
   bool dump_raw_gc_map = false;
+  bool symbolize = false;
 
   for (int i = 0; i < argc; i++) {
     const StringPiece option(argv[i]);
@@ -1571,13 +1794,17 @@
           usage();
         }
     } else if (option.starts_with("--output=")) {
-      const char* filename = option.substr(strlen("--output=")).data();
+      output_name = option.substr(strlen("--output=")).ToString();
+      const char* filename = output_name.c_str();
       out.reset(new std::ofstream(filename));
       if (!out->good()) {
         fprintf(stderr, "Failed to open output filename %s\n", filename);
         usage();
       }
       os = out.get();
+    } else if (option.starts_with("--symbolize=")) {
+      oat_filename = option.substr(strlen("--symbolize=")).data();
+      symbolize = true;
     } else {
       fprintf(stderr, "Unknown argument %s\n", option.data());
       usage();
@@ -1602,8 +1829,20 @@
       fprintf(stderr, "Failed to open oat file from '%s': %s\n", oat_filename, error_msg.c_str());
       return EXIT_FAILURE;
     }
-    OatDumper oat_dumper(*oat_file, dump_raw_mapping_table, dump_raw_gc_map);
-    oat_dumper.Dump(*os);
+    if (symbolize) {
+      OatSymbolizer oat_symbolizer(oat_file, output_name);
+      if (!oat_symbolizer.Init()) {
+        fprintf(stderr, "Failed to initialize symbolizer\n");
+        return EXIT_FAILURE;
+      }
+      if (!oat_symbolizer.Symbolize()) {
+        fprintf(stderr, "Failed to symbolize\n");
+        return EXIT_FAILURE;
+      }
+    } else {
+      OatDumper oat_dumper(*oat_file, dump_raw_mapping_table, dump_raw_gc_map);
+      oat_dumper.Dump(*os);
+    }
     return EXIT_SUCCESS;
   }
 
diff --git a/tools/symbolize.sh b/tools/symbolize.sh
new file mode 100755
index 0000000..b66191f
--- /dev/null
+++ b/tools/symbolize.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# Symbolize oat files from the dalvik cache of a device.
+#
+# By default, pulls everything from the dalvik cache. A simple yes/no/quit prompt for each file can
+# be requested by giving "--interactive" as a parameter.
+
+INTERACTIVE="no"
+if [ "x$1" = "x--interactive" ] ; then
+  INTERACTIVE="yes"
+fi
+
+# Pull the file from the device and symbolize it.
+function one() {
+  echo $1 $2
+  if [ "x$INTERACTIVE" = "xyes" ] ; then
+    echo -n "What to do? [Y/n/q] "
+    read -e input
+    if [ "x$input" = "xn" ] ; then
+      return
+    fi
+    if [ "x$input" = "xq" ] ; then
+      exit 0
+    fi
+  fi
+  adb pull /data/dalvik-cache/$1/$2 /tmp || exit 1
+  mkdir -p $OUT/symbols/data/dalvik-cache/$1
+  oatdump --symbolize=/tmp/$2 --output=$OUT/symbols/data/dalvik-cache/$1/$2
+}
+
+# adb shell ls seems to output in DOS format (CRLF), which messes up scripting
+function adbls() {
+  adb shell ls $@ | sed 's/\r$//'
+}
+
+# Check for all ISA directories on device.
+function all() {
+  DIRS=$(adbls /data/dalvik-cache/)
+  for DIR in $DIRS ; do
+    case $DIR in
+      arm|arm64|mips|x86|x86_64)
+        FILES=$(adbls /data/dalvik-cache/$DIR/*.oat /data/dalvik-cache/$DIR/*.dex)
+        for FILE in $FILES ; do
+          # Cannot use basename as the file doesn't exist.
+          NAME=$(echo $FILE | sed -e 's/.*\///')
+          one $DIR $NAME
+        done
+        ;;
+    esac
+  done
+}
+
+all
