/*
 * 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 "base/stl_util.h"
#include "base/value_object.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 ValueObject {
 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)
      : section_index_(0), 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;
  }

  ~ElfSectionBuilder() {}

  Elf_Word GetLink() const {
    return (link_ != nullptr) ? link_->section_index_ : 0;
  }

  const Elf_Shdr* GetSection() const {
    return &section_;
  }

  Elf_Shdr* GetSection() {
    return &section_;
  }

  Elf_Word GetSectionIndex() const {
    return section_index_;
  }

  void SetSectionIndex(Elf_Word section_index) {
    section_index_ = section_index;
  }

  const std::string& GetName() const {
    return name_;
  }

 private:
  Elf_Shdr section_;
  Elf_Word section_index_;
  const std::string name_;
  const ElfSectionBuilder* const link_;
};

template <typename Elf_Word, typename Elf_Sword, typename Elf_Dyn, typename Elf_Shdr>
class ElfDynamicBuilder FINAL : 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,
                     const 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() const {
    // 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) const {
    std::vector<Elf_Dyn> ret;
    for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
      if (it->section_ != nullptr) {
        // We are adding an address relative to a section.
        ret.push_back(
            {it->tag_, {it->off_ + it->section_->GetSection()->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;
  }

 private:
  struct ElfDynamicState {
    const 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 FINAL : 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(const std::vector<uint8_t>& buf) {
    buf_ = buf;
  }

 private:
  std::vector<uint8_t> buf_;
};

template <typename Elf_Word, typename Elf_Sword, typename Elf_Shdr>
class ElfOatSectionBuilder FINAL : 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() const {
    return offset_;
  }

  Elf_Word GetSize() const {
    return size_;
  }

 private:
  // 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 FINAL : 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() const {
    // 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_.GetSection()->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_->GetSection()->sh_offset;
      } else {
        sym.st_value = it->addr_;
      }
      sym.st_size = it->size_;
      sym.st_other = it->other_;
      sym.st_shndx = it->section_->GetSectionIndex();
      sym.st_info = it->info_;

      ret.push_back(sym);
    }
    return ret;
  }

  Elf_Word GetSize() const {
    // 1 is for the implicit NULL symbol.
    return symbols_.size() + 1;
  }

  ElfSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>* GetStrTab() {
    return &strtab_;
  }

 private:
  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_;
};

template <typename Elf_Word>
class ElfFilePiece {
 public:
  virtual ~ElfFilePiece() {}

  virtual bool Write(File* elf_file) {
    if (static_cast<off_t>(offset_) != lseek(elf_file->Fd(), offset_, SEEK_SET)) {
      PLOG(ERROR) << "Failed to seek to " << GetDescription() << " offset " << offset_ << " for "
          << elf_file->GetPath();
      return false;
    }

    return DoActualWrite(elf_file);
  }

  static bool Compare(ElfFilePiece* a, ElfFilePiece* b) {
    return a->offset_ < b->offset_;
  }

 protected:
  explicit ElfFilePiece(Elf_Word offset) : offset_(offset) {}

  Elf_Word GetOffset() const {
    return offset_;
  }

  virtual const char* GetDescription() const = 0;
  virtual bool DoActualWrite(File* elf_file) = 0;

 private:
  const Elf_Word offset_;

  DISALLOW_COPY_AND_ASSIGN(ElfFilePiece);
};

template <typename Elf_Word>
class ElfFileMemoryPiece FINAL : public ElfFilePiece<Elf_Word> {
 public:
  ElfFileMemoryPiece(const std::string& name, Elf_Word offset, const void* data, Elf_Word size)
      : ElfFilePiece<Elf_Word>(offset), dbg_name_(name), data_(data), size_(size) {}

 protected:
  bool DoActualWrite(File* elf_file) OVERRIDE {
    DCHECK(data_ != nullptr || size_ == 0U) << dbg_name_ << " " << size_;

    if (!elf_file->WriteFully(data_, size_)) {
      PLOG(ERROR) << "Failed to write " << dbg_name_ << " for " << elf_file->GetPath();
      return false;
    }

    return true;
  }

  const char* GetDescription() const OVERRIDE {
    return dbg_name_.c_str();
  }

 private:
  const std::string& dbg_name_;
  const void *data_;
  Elf_Word size_;
};

class CodeOutput {
 public:
  virtual void SetCodeOffset(size_t offset) = 0;
  virtual bool Write(OutputStream* out) = 0;
  virtual ~CodeOutput() {}
};

template <typename Elf_Word>
class ElfFileRodataPiece FINAL : public ElfFilePiece<Elf_Word> {
 public:
  ElfFileRodataPiece(Elf_Word offset, CodeOutput* output) : ElfFilePiece<Elf_Word>(offset),
      output_(output) {}

 protected:
  bool DoActualWrite(File* elf_file) OVERRIDE {
    output_->SetCodeOffset(this->GetOffset());
    std::unique_ptr<BufferedOutputStream> output_stream(
        new BufferedOutputStream(new FileOutputStream(elf_file)));
    if (!output_->Write(output_stream.get())) {
      PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file->GetPath();
      return false;
    }

    return true;
  }

  const char* GetDescription() const OVERRIDE {
    return ".rodata";
  }

 private:
  CodeOutput* const output_;

  DISALLOW_COPY_AND_ASSIGN(ElfFileRodataPiece);
};

template <typename Elf_Word>
class ElfFileOatTextPiece FINAL : public ElfFilePiece<Elf_Word> {
 public:
  ElfFileOatTextPiece(Elf_Word offset, CodeOutput* output) : ElfFilePiece<Elf_Word>(offset),
      output_(output) {}

 protected:
  bool DoActualWrite(File* elf_file ATTRIBUTE_UNUSED) OVERRIDE {
    // All data is written by the ElfFileRodataPiece right now, as the oat writer writes in one
    // piece. This is for future flexibility.
    UNUSED(output_);
    return true;
  }

  const char* GetDescription() const OVERRIDE {
    return ".text";
  }

 private:
  CodeOutput* const output_;

  DISALLOW_COPY_AND_ASSIGN(ElfFileOatTextPiece);
};

template <typename Elf_Word>
static bool WriteOutFile(const std::vector<ElfFilePiece<Elf_Word>*>& pieces, File* elf_file) {
  // TODO It would be nice if this checked for overlap.
  for (auto it = pieces.begin(); it != pieces.end(); ++it) {
    if (!(*it)->Write(elf_file)) {
      return false;
    }
  }
  return true;
}

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() {}

  const ElfOatSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr>& GetTextBuilder() const {
    return text_builder_;
  }

  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* GetSymtabBuilder() {
    return &symtab_builder_;
  }

  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_.GetSection());
    AssignSectionStr(&dynsym_builder_, &shstrtab_);
    dynsym_builder_.SetSectionIndex(section_index_);
    section_index_++;

    // Setup .dynstr
    section_ptrs_.push_back(dynsym_builder_.GetStrTab()->GetSection());
    AssignSectionStr(dynsym_builder_.GetStrTab(), &shstrtab_);
    dynsym_builder_.GetStrTab()->SetSectionIndex(section_index_);
    section_index_++;

    // Setup .hash
    section_ptrs_.push_back(hash_builder_.GetSection());
    AssignSectionStr(&hash_builder_, &shstrtab_);
    hash_builder_.SetSectionIndex(section_index_);
    section_index_++;

    // Setup .rodata
    section_ptrs_.push_back(rodata_builder_.GetSection());
    AssignSectionStr(&rodata_builder_, &shstrtab_);
    rodata_builder_.SetSectionIndex(section_index_);
    section_index_++;

    // Setup .text
    section_ptrs_.push_back(text_builder_.GetSection());
    AssignSectionStr(&text_builder_, &shstrtab_);
    text_builder_.SetSectionIndex(section_index_);
    section_index_++;

    // Setup .dynamic
    section_ptrs_.push_back(dynamic_builder_.GetSection());
    AssignSectionStr(&dynamic_builder_, &shstrtab_);
    dynamic_builder_.SetSectionIndex(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_.GetSection()->sh_offset =
        RoundUp(base_offset, dynsym_builder_.GetSection()->sh_addralign);
    dynsym_builder_.GetSection()->sh_addr = dynsym_builder_.GetSection()->sh_offset;
    dynsym_builder_.GetSection()->sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym);
    dynsym_builder_.GetSection()->sh_link = dynsym_builder_.GetLink();

    // Get the layout of the dynstr section.
    dynsym_builder_.GetStrTab()->GetSection()->sh_offset =
        NextOffset<Elf_Word, Elf_Shdr>(*dynsym_builder_.GetStrTab()->GetSection(),
                                       *dynsym_builder_.GetSection());
    dynsym_builder_.GetStrTab()->GetSection()->sh_addr =
        dynsym_builder_.GetStrTab()->GetSection()->sh_offset;
    dynsym_builder_.GetStrTab()->GetSection()->sh_size = dynstr_.size();
    dynsym_builder_.GetStrTab()->GetSection()->sh_link = dynsym_builder_.GetStrTab()->GetLink();

    // Get the layout of the hash section
    hash_builder_.GetSection()->sh_offset =
        NextOffset<Elf_Word, Elf_Shdr>(*hash_builder_.GetSection(),
                                       *dynsym_builder_.GetStrTab()->GetSection());
    hash_builder_.GetSection()->sh_addr = hash_builder_.GetSection()->sh_offset;
    hash_builder_.GetSection()->sh_size = hash_.size() * sizeof(Elf_Word);
    hash_builder_.GetSection()->sh_link = hash_builder_.GetLink();

    // Get the layout of the rodata section.
    rodata_builder_.GetSection()->sh_offset =
        NextOffset<Elf_Word, Elf_Shdr>(*rodata_builder_.GetSection(),
                                       *hash_builder_.GetSection());
    rodata_builder_.GetSection()->sh_addr = rodata_builder_.GetSection()->sh_offset;
    rodata_builder_.GetSection()->sh_size = rodata_builder_.GetSize();
    rodata_builder_.GetSection()->sh_link = rodata_builder_.GetLink();

    // Get the layout of the text section.
    text_builder_.GetSection()->sh_offset =
        NextOffset<Elf_Word, Elf_Shdr>(*text_builder_.GetSection(),
                                       *rodata_builder_.GetSection());
    text_builder_.GetSection()->sh_addr = text_builder_.GetSection()->sh_offset;
    text_builder_.GetSection()->sh_size = text_builder_.GetSize();
    text_builder_.GetSection()->sh_link = text_builder_.GetLink();
    CHECK_ALIGNED(rodata_builder_.GetSection()->sh_offset +
                  rodata_builder_.GetSection()->sh_size, kPageSize);

    // Get the layout of the dynamic section.
    dynamic_builder_.GetSection()->sh_offset =
        NextOffset<Elf_Word, Elf_Shdr>(*dynamic_builder_.GetSection(), *text_builder_.GetSection());
    dynamic_builder_.GetSection()->sh_addr = dynamic_builder_.GetSection()->sh_offset;
    dynamic_builder_.GetSection()->sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn);
    dynamic_builder_.GetSection()->sh_link = dynamic_builder_.GetLink();

    if (debug_logging_) {
      LOG(INFO) << "dynsym off=" << dynsym_builder_.GetSection()->sh_offset
                << " dynsym size=" << dynsym_builder_.GetSection()->sh_size;
      LOG(INFO) << "dynstr off=" << dynsym_builder_.GetStrTab()->GetSection()->sh_offset
                << " dynstr size=" << dynsym_builder_.GetStrTab()->GetSection()->sh_size;
      LOG(INFO) << "hash off=" << hash_builder_.GetSection()->sh_offset
                << " hash size=" << hash_builder_.GetSection()->sh_size;
      LOG(INFO) << "rodata off=" << rodata_builder_.GetSection()->sh_offset
                << " rodata size=" << rodata_builder_.GetSection()->sh_size;
      LOG(INFO) << "text off=" << text_builder_.GetSection()->sh_offset
                << " text size=" << text_builder_.GetSection()->sh_size;
      LOG(INFO) << "dynamic off=" << dynamic_builder_.GetSection()->sh_offset
                << " dynamic size=" << dynamic_builder_.GetSection()->sh_size;
    }

    return true;
  }

  bool Write() {
    std::vector<ElfFilePiece<Elf_Word>*> pieces;
    Elf_Shdr* prev = dynamic_builder_.GetSection();
    std::string strtab;

    if (IncludingDebugSymbols()) {
      // Setup .symtab
      section_ptrs_.push_back(symtab_builder_.GetSection());
      AssignSectionStr(&symtab_builder_, &shstrtab_);
      symtab_builder_.SetSectionIndex(section_index_);
      section_index_++;

      // Setup .strtab
      section_ptrs_.push_back(symtab_builder_.GetStrTab()->GetSection());
      AssignSectionStr(symtab_builder_.GetStrTab(), &shstrtab_);
      symtab_builder_.GetStrTab()->SetSectionIndex(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->GetSection());
      AssignSectionStr(builder, &shstrtab_);
      builder->SetSectionIndex(section_index_);
      section_index_++;
    }

    // Setup shstrtab
    section_ptrs_.push_back(shstrtab_builder_.GetSection());
    AssignSectionStr(&shstrtab_builder_, &shstrtab_);
    shstrtab_builder_.SetSectionIndex(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_.GetSection()->sh_offset =
          NextOffset<Elf_Word, Elf_Shdr>(*symtab_builder_.GetSection(),
                                         *dynamic_builder_.GetSection());
      symtab_builder_.GetSection()->sh_addr = 0;
      // Add to leave space for the null symbol.
      symtab_builder_.GetSection()->sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym);
      symtab_builder_.GetSection()->sh_link = symtab_builder_.GetLink();

      // Get the layout of the dynstr section.
      symtab_builder_.GetStrTab()->GetSection()->sh_offset =
          NextOffset<Elf_Word, Elf_Shdr>(*symtab_builder_.GetStrTab()->GetSection(),
                                         *symtab_builder_.GetSection());
      symtab_builder_.GetStrTab()->GetSection()->sh_addr = 0;
      symtab_builder_.GetStrTab()->GetSection()->sh_size = strtab.size();
      symtab_builder_.GetStrTab()->GetSection()->sh_link = symtab_builder_.GetStrTab()->GetLink();

      prev = symtab_builder_.GetStrTab()->GetSection();
      if (debug_logging_) {
        LOG(INFO) << "symtab off=" << symtab_builder_.GetSection()->sh_offset
                  << " symtab size=" << symtab_builder_.GetSection()->sh_size;
        LOG(INFO) << "strtab off=" << symtab_builder_.GetStrTab()->GetSection()->sh_offset
                  << " strtab size=" << symtab_builder_.GetStrTab()->GetSection()->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->GetSection()->sh_offset = NextOffset<Elf_Word, Elf_Shdr>(*it->GetSection(), *prev);
      it->GetSection()->sh_addr = 0;
      it->GetSection()->sh_size = it->GetBuffer()->size();
      it->GetSection()->sh_link = it->GetLink();

      // We postpone adding an ElfFilePiece to keep the order in "pieces."

      prev = it->GetSection();
      if (debug_logging_) {
        LOG(INFO) << it->GetName() << " off=" << it->GetSection()->sh_offset
                  << " size=" << it->GetSection()->sh_size;
      }
    }

    // Get the layout of the shstrtab section
    shstrtab_builder_.GetSection()->sh_offset =
        NextOffset<Elf_Word, Elf_Shdr>(*shstrtab_builder_.GetSection(), *prev);
    shstrtab_builder_.GetSection()->sh_addr = 0;
    shstrtab_builder_.GetSection()->sh_size = shstrtab_.size();
    shstrtab_builder_.GetSection()->sh_link = shstrtab_builder_.GetLink();
    if (debug_logging_) {
        LOG(INFO) << "shstrtab off=" << shstrtab_builder_.GetSection()->sh_offset
                  << " shstrtab size=" << shstrtab_builder_.GetSection()->sh_size;
    }

    // The section list comes after come after.
    Elf_Word sections_offset = RoundUp(
        shstrtab_builder_.GetSection()->sh_offset + shstrtab_builder_.GetSection()->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_.GetSection()->sh_size);
    std::vector<Elf_Sym> symtab;
    if (IncludingDebugSymbols()) {
      symtab = symtab_builder_.GenerateSymtab();
      CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.GetSection()->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_.GetSection()->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_.GetSection()->sh_offset + rodata_builder_.GetSection()->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_.GetSection()->sh_addralign;

    Elf_Word load_rx_size = text_builder_.GetSection()->sh_size;
    program_headers_[PH_LOAD_R_X].p_offset = text_builder_.GetSection()->sh_offset;
    program_headers_[PH_LOAD_R_X].p_vaddr  = text_builder_.GetSection()->sh_offset;
    program_headers_[PH_LOAD_R_X].p_paddr  = text_builder_.GetSection()->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_.GetSection()->sh_addralign;

    program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.GetSection()->sh_offset;
    program_headers_[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.GetSection()->sh_offset;
    program_headers_[PH_LOAD_RW_].p_paddr  = dynamic_builder_.GetSection()->sh_offset;
    program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.GetSection()->sh_size;
    program_headers_[PH_LOAD_RW_].p_memsz  = dynamic_builder_.GetSection()->sh_size;
    program_headers_[PH_LOAD_RW_].p_align  = dynamic_builder_.GetSection()->sh_addralign;

    program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.GetSection()->sh_offset;
    program_headers_[PH_DYNAMIC].p_vaddr  = dynamic_builder_.GetSection()->sh_offset;
    program_headers_[PH_DYNAMIC].p_paddr  = dynamic_builder_.GetSection()->sh_offset;
    program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.GetSection()->sh_size;
    program_headers_[PH_DYNAMIC].p_memsz  = dynamic_builder_.GetSection()->sh_size;
    program_headers_[PH_DYNAMIC].p_align  = dynamic_builder_.GetSection()->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_.GetSectionIndex();

    // Add the rest of the pieces to the list.
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Elf Header", 0, &elf_header_,
                                                      sizeof(elf_header_)));
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>("Program headers", PHDR_OFFSET,
                                                      &program_headers_, sizeof(program_headers_)));
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynamic",
                                                      dynamic_builder_.GetSection()->sh_offset,
                                                      dynamic.data(),
                                                      dynamic_builder_.GetSection()->sh_size));
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynsym", dynsym_builder_.GetSection()->sh_offset,
                                                      dynsym.data(),
                                                      dynsym.size() * sizeof(Elf_Sym)));
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".dynstr",
                                                    dynsym_builder_.GetStrTab()->GetSection()->sh_offset,
                                                    dynstr_.c_str(), dynstr_.size()));
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".hash", hash_builder_.GetSection()->sh_offset,
                                                      hash_.data(),
                                                      hash_.size() * sizeof(Elf_Word)));
    pieces.push_back(new ElfFileRodataPiece<Elf_Word>(rodata_builder_.GetSection()->sh_offset,
                                                      oat_writer_));
    pieces.push_back(new ElfFileOatTextPiece<Elf_Word>(text_builder_.GetSection()->sh_offset,
                                                       oat_writer_));
    if (IncludingDebugSymbols()) {
      pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".symtab",
                                                        symtab_builder_.GetSection()->sh_offset,
                                                        symtab.data(),
                                                        symtab.size() * sizeof(Elf_Sym)));
      pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".strtab",
                                                    symtab_builder_.GetStrTab()->GetSection()->sh_offset,
                                                    strtab.c_str(), strtab.size()));
    }
    pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(".shstrtab",
                                                      shstrtab_builder_.GetSection()->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(new ElfFileMemoryPiece<Elf_Word>("section table piece", cur_off,
                                                        section_ptrs_[i], sizeof(Elf_Shdr)));
    }

    // Postponed debug info.
    for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
      pieces.push_back(new ElfFileMemoryPiece<Elf_Word>(it->GetName(), it->GetSection()->sh_offset,
                                                        it->GetBuffer()->data(),
                                                        it->GetBuffer()->size()));
    }

    if (!WriteOutFile(pieces)) {
      LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();

      STLDeleteElements(&pieces);  // Have to manually clean pieces.
      return false;
    }

    STLDeleteElements(&pieces);  // Have to manually clean pieces.
    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:
  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]      = (sizeof(Elf_Addr) == sizeof(Elf32_Addr))
                                         ? ELFCLASS32 : ELFCLASS64;;
    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->GetSection()->sh_name = strtab->size();
    *strtab += builder->GetName();
    *strtab += '\0';
    if (debug_logging_) {
      LOG(INFO) << "adding section name \"" << builder->GetName() << "\" "
                << "to shstrtab at offset " << builder->GetSection()->sh_name;
    }
  }


  // Write each of the pieces out to the file.
  bool WriteOutFile(const std::vector<ElfFilePiece<Elf_Word>*>& pieces) {
    for (auto it = pieces.begin(); it != pieces.end(); ++it) {
      if (!(*it)->Write(elf_file_)) {
        return false;
      }
    }
    return true;
  }

  bool IncludingDebugSymbols() const {
    return add_symbols_ && symtab_builder_.GetSize() > 1;
  }

  CodeOutput* const oat_writer_;
  File* const 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_;
  // The index of the current section being built. The first being 1.
  uint32_t section_index_;
  std::string dynstr_;
  uint32_t dynstr_soname_offset_;
  std::vector<const Elf_Shdr*> section_ptrs_;
  std::vector<Elf_Word> hash_;

  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_;

  DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
};

}  // namespace art

#endif  // ART_COMPILER_ELF_BUILDER_H_
