/*
 * Copyright (C) 2012 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.
 */

#include "elf_writer_quick.h"

#include "base/logging.h"
#include "base/unix_file/fd_file.h"
#include "buffered_output_stream.h"
#include "driver/compiler_driver.h"
#include "elf_utils.h"
#include "file_output_stream.h"
#include "globals.h"
#include "oat.h"
#include "oat_writer.h"
#include "utils.h"

namespace art {

static constexpr Elf32_Word NextOffset(const Elf32_Shdr& cur, const Elf32_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);
}

bool ElfWriterQuick::ElfBuilder::Write() {
  // The basic layout of the elf file. Order may be different in final output.
  // +-------------------------+
  // | Elf32_Ehdr              |
  // +-------------------------+
  // | Elf32_Phdr PHDR         |
  // | Elf32_Phdr LOAD R       | .dynsym .dynstr .hash .rodata
  // | Elf32_Phdr LOAD R X     | .text
  // | Elf32_Phdr LOAD RW      | .dynamic
  // | Elf32_Phdr DYNAMIC      | .dynamic
  // +-------------------------+
  // | .dynsym                 |
  // | Elf32_Sym  STN_UNDEF    |
  // | Elf32_Sym  oatdata      |
  // | Elf32_Sym  oatexec      |
  // | Elf32_Sym  oatlastword  |
  // +-------------------------+
  // | .dynstr                 |
  // | \0                      |
  // | oatdata\0               |
  // | oatexec\0               |
  // | oatlastword\0           |
  // | boot.oat\0              |
  // +-------------------------+
  // | .hash                   |
  // | Elf32_Word nbucket = b  |
  // | Elf32_Word nchain  = c  |
  // | Elf32_Word bucket[0]    |
  // |         ...             |
  // | Elf32_Word bucket[b - 1]|
  // | Elf32_Word chain[0]     |
  // |         ...             |
  // | Elf32_Word chain[c - 1] |
  // +-------------------------+
  // | .rodata                 |
  // | oatdata..oatexec-4      |
  // +-------------------------+
  // | .text                   |
  // | oatexec..oatlastword    |
  // +-------------------------+
  // | .dynamic                |
  // | Elf32_Dyn DT_SONAME     |
  // | Elf32_Dyn DT_HASH       |
  // | Elf32_Dyn DT_SYMTAB     |
  // | Elf32_Dyn DT_SYMENT     |
  // | Elf32_Dyn DT_STRTAB     |
  // | Elf32_Dyn DT_STRSZ      |
  // | Elf32_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)
  // | .debug_frame\0          |  (Optional)
  // | .debug_abbrev\0         |  (Optional)
  // +-------------------------+  (Optional)
  // | .debug_str              |  (Optional)
  // +-------------------------+  (Optional)
  // | .debug_info             |  (Optional)
  // +-------------------------+  (Optional)
  // | .debug_frame            |  (Optional)
  // +-------------------------+  (Optional)
  // | .debug_abbrev           |  (Optional)
  // +-------------------------+
  // | Elf32_Shdr NULL         |
  // | Elf32_Shdr .dynsym      |
  // | Elf32_Shdr .dynstr      |
  // | Elf32_Shdr .hash        |
  // | Elf32_Shdr .text        |
  // | Elf32_Shdr .rodata      |
  // | Elf32_Shdr .dynamic     |
  // | Elf32_Shdr .shstrtab    |
  // | Elf32_Shdr .debug_str   |  (Optional)
  // | Elf32_Shdr .debug_info  |  (Optional)
  // | Elf32_Shdr .debug_frame |  (Optional)
  // | Elf32_Shdr .debug_abbrev|  (Optional)
  // +-------------------------+


  if (fatal_error_) {
    return false;
  }
  // Step 1. Figure out all the offsets.

  // What phdr is.
  uint32_t phdr_offset = sizeof(Elf32_Ehdr);
  const uint8_t PH_PHDR     = 0;
  const uint8_t PH_LOAD_R__ = 1;
  const uint8_t PH_LOAD_R_X = 2;
  const uint8_t PH_LOAD_RW_ = 3;
  const uint8_t PH_DYNAMIC  = 4;
  const uint8_t PH_NUM      = 5;
  uint32_t phdr_size = sizeof(Elf32_Phdr) * PH_NUM;
  if (debug_logging_) {
    LOG(INFO) << "phdr_offset=" << phdr_offset << std::hex << " " << phdr_offset;
    LOG(INFO) << "phdr_size=" << phdr_size << std::hex << " " << phdr_size;
  }
  Elf32_Phdr program_headers[PH_NUM];
  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(Elf32_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.
  std::string dynstr(dynsym_builder_.GenerateStrtab());

  // Add the SONAME to the dynstr.
  uint32_t 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 strtab
  std::string strtab;
  if (IncludingDebugSymbols()) {
    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();
    }
  }

  // Get the section header string table.
  std::vector<Elf32_Shdr*> section_ptrs;
  std::string shstrtab;
  shstrtab += '\0';

  // Setup sym_undef
  Elf32_Shdr null_hdr;
  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);

  uint32_t 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++;

  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++;
  }
  ElfRawSectionBuilder* it = other_builders_.data();
  for (uint32_t cnt = 0; cnt < other_builders_.size(); ++it, ++cnt) {
    // Setup all the other sections.
    section_ptrs.push_back(&it->section_);
    AssignSectionStr(it, &shstrtab);
    it->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();
  }

  // Fill in the hash section.
  std::vector<Elf32_Word> hash = dynsym_builder_.GenerateHashContents();

  if (debug_logging_) {
    LOG(INFO) << ".hash size (bytes)=" << hash.size() * sizeof(Elf32_Word)
              << std::hex << " " << hash.size() * sizeof(Elf32_Word);
  }

  Elf32_Word base_offset = sizeof(Elf32_Ehdr) + sizeof(program_headers);
  std::vector<ElfFilePiece> pieces;

  // 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(Elf32_Sym);
  dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();

  // Get the layout of the dynstr section.
  dynsym_builder_.strtab_.section_.sh_offset = NextOffset(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(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(Elf32_Word);
  hash_builder_.section_.sh_link = hash_builder_.GetLink();

  // Get the layout of the rodata section.
  rodata_builder_.section_.sh_offset = NextOffset(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(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(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(Elf32_Dyn);
  dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();

  Elf32_Shdr prev = dynamic_builder_.section_;
  if (IncludingDebugSymbols()) {
    // Get the layout of the symtab section.
    symtab_builder_.section_.sh_offset = NextOffset(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(Elf32_Sym);
    symtab_builder_.section_.sh_link = symtab_builder_.GetLink();

    // Get the layout of the dynstr section.
    symtab_builder_.strtab_.section_.sh_offset = NextOffset(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) << "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;
    if (IncludingDebugSymbols()) {
      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(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(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.
  Elf32_Word sections_offset = RoundUp(
      shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
      sizeof(Elf32_Word));

  // Setup the actual symbol arrays.
  std::vector<Elf32_Sym> dynsym = dynsym_builder_.GenerateSymtab();
  CHECK_EQ(dynsym.size() * sizeof(Elf32_Sym), dynsym_builder_.section_.sh_size);
  std::vector<Elf32_Sym> symtab;
  if (IncludingDebugSymbols()) {
    symtab = symtab_builder_.GenerateSymtab();
    CHECK_EQ(symtab.size() * sizeof(Elf32_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<Elf32_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr.size(),
                                                                dynstr_soname_offset);
  CHECK_EQ(dynamic.size() * sizeof(Elf32_Dyn), dynamic_builder_.section_.sh_size);

  // Finish setup of the program headers now that we know the layout of the
  // whole file.
  Elf32_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;

  Elf32_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(Elf32_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(Elf32_Word)));
  pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset,
                                NULL, rodata_builder_.section_.sh_size));
  pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset,
                                NULL, text_builder_.section_.sh_size));
  if (IncludingDebugSymbols()) {
    pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset,
                                  symtab.data(), symtab.size() * sizeof(Elf32_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.
    Elf32_Word cur_off = sections_offset + i * sizeof(Elf32_Shdr);
    pieces.push_back(ElfFilePiece("section table piece", cur_off,
                                  section_ptrs[i], sizeof(Elf32_Shdr)));
  }

  if (!WriteOutFile(pieces)) {
    LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();
    return false;
  }
  // write out the actual oat file data.
  Elf32_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;
}

bool ElfWriterQuick::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;
}

void ElfWriterQuick::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(Elf32_Sym));
}

void ElfWriterQuick::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);
}

void ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un) {
  if (tag == DT_NULL) {
    return;
  }
  dynamics_.push_back({NULL, tag, d_un});
}

void ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un,
                                                      ElfSectionBuilder* section) {
  if (tag == DT_NULL) {
    return;
  }
  dynamics_.push_back({section, tag, d_un});
}

std::vector<Elf32_Dyn> ElfWriterQuick::ElfDynamicBuilder::GetDynamics(Elf32_Word strsz,
                                                                      Elf32_Word soname) {
  std::vector<Elf32_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;
}

std::vector<Elf32_Sym> ElfWriterQuick::ElfSymtabBuilder::GenerateSymtab() {
  std::vector<Elf32_Sym> ret;
  Elf32_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) {
    Elf32_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;
}

std::string ElfWriterQuick::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;
}

void ElfWriterQuick::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;
}


std::vector<Elf32_Word> ElfWriterQuick::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.
  Elf32_Word nbuckets;
  Elf32_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<Elf32_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);

  Elf32_Word* buckets = hash.data() + bucket_offset;
  Elf32_Word* chain   = hash.data() + chain_offset;

  // Set up the actual hash table.
  for (Elf32_Word i = 0; i < symbols_.size(); i++) {
    // Add 1 since we need to have the null symbol that is not in the symbols
    // list.
    Elf32_Word index = i + 1;
    Elf32_Word hash_val = static_cast<Elf32_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<Elf32_Word>(0));
    }
  }

  return hash;
}

void ElfWriterQuick::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(Elf32_Ehdr);
  elf_header_.e_phentsize = sizeof(Elf32_Phdr);
  elf_header_.e_shentsize = sizeof(Elf32_Shdr);
  elf_header_.e_phoff = sizeof(Elf32_Ehdr);
}

void ElfWriterQuick::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;
    }
  }
}

void ElfWriterQuick::ElfSymtabBuilder::AddSymbol(
    const std::string& name, const ElfSectionBuilder* section, Elf32_Addr addr,
    bool is_relative, Elf32_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);
}

bool ElfWriterQuick::Create(File* elf_file,
                            OatWriter* oat_writer,
                            const std::vector<const DexFile*>& dex_files,
                            const std::string& android_root,
                            bool is_host,
                            const CompilerDriver& driver) {
  ElfWriterQuick elf_writer(driver, elf_file);
  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
}

bool ElfWriterQuick::Write(OatWriter* oat_writer,
                           const std::vector<const DexFile*>& dex_files_unused,
                           const std::string& android_root_unused,
                           bool is_host_unused) {
  const bool debug = false;
  const bool add_symbols = oat_writer->DidAddSymbols();
  const OatHeader& oat_header = oat_writer->GetOatHeader();
  Elf32_Word oat_data_size = oat_header.GetExecutableOffset();
  uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;

  ElfBuilder builder(oat_writer, elf_file_, compiler_driver_->GetInstructionSet(), 0,
                     oat_data_size, oat_data_size, oat_exec_size, add_symbols, debug);

  if (add_symbols) {
    AddDebugSymbols(builder, oat_writer, debug);
  }

  bool generateDebugInformation = compiler_driver_->GetCallFrameInformation() != nullptr;
  if (generateDebugInformation) {
    ElfRawSectionBuilder debug_info(".debug_info",   SHT_PROGBITS, 0, NULL, 0, 1, 0);
    ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, NULL, 0, 1, 0);
    ElfRawSectionBuilder debug_str(".debug_str",    SHT_PROGBITS, 0, NULL, 0, 1, 0);
    ElfRawSectionBuilder debug_frame(".debug_frame",  SHT_PROGBITS, 0, NULL, 0, 4, 0);
    debug_frame.SetBuffer(*compiler_driver_->GetCallFrameInformation());

    FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
                         debug_abbrev.GetBuffer(), debug_str.GetBuffer());
    builder.RegisterRawSection(debug_info);
    builder.RegisterRawSection(debug_abbrev);
    builder.RegisterRawSection(debug_frame);
    builder.RegisterRawSection(debug_str);
  }

  return builder.Write();
}

void ElfWriterQuick::AddDebugSymbols(ElfBuilder& builder, OatWriter* oat_writer, bool debug) {
  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);
  }
}

static void UpdateWord(std::vector<uint8_t>*buf, int offset, int data) {
  (*buf)[offset+0] = data;
  (*buf)[offset+1] = data >> 8;
  (*buf)[offset+2] = data >> 16;
  (*buf)[offset+3] = data >> 24;
}

static void PushWord(std::vector<uint8_t>*buf, int data) {
  buf->push_back(data & 0xff);
  buf->push_back((data >> 8) & 0xff);
  buf->push_back((data >> 16) & 0xff);
  buf->push_back((data >> 24) & 0xff);
}

static void PushHalf(std::vector<uint8_t>*buf, int data) {
  buf->push_back(data & 0xff);
  buf->push_back((data >> 8) & 0xff);
}

// DWARF constants needed to generate CFI information.
enum {
  // Tag encodings.
  DW_TAG_compile_unit = 0x11,
  DW_TAG_subprogram = 0X2e,

  // Attribute encodings.
  DW_AT_name = 0x03,
  DW_AT_low_pc = 0x11,
  DW_AT_high_pc = 0x12,
  DW_AT_language = 0x13,

  // Constant encoding.
  DW_CHILDREN_no = 0x00,
  DW_CHILDREN_yes = 0x01,

  // Attribute form encodings.
  DW_FORM_addr = 0x01,
  DW_FORM_data1 = 0x0b,
  DW_FORM_strp = 0x0e,

  // Language encoding.
  DW_LANG_Java = 0x000b
};

void ElfWriterQuick::FillInCFIInformation(OatWriter* oat_writer,
                                          std::vector<uint8_t>* dbg_info,
                                          std::vector<uint8_t>* dbg_abbrev,
                                          std::vector<uint8_t>* dbg_str) {
  // Create the debug_abbrev section with boilerplate information.
  // We only care about low_pc and high_pc right now for the compilation
  // unit and methods.

  // Tag 1: Compilation unit: DW_TAG_compile_unit.
  dbg_abbrev->push_back(1);
  dbg_abbrev->push_back(DW_TAG_compile_unit);

  // There are children (the methods).
  dbg_abbrev->push_back(DW_CHILDREN_yes);

  // DW_LANG_Java DW_FORM_data1.
  dbg_abbrev->push_back(DW_AT_language);
  dbg_abbrev->push_back(DW_FORM_data1);

  // DW_AT_low_pc DW_FORM_addr.
  dbg_abbrev->push_back(DW_AT_low_pc);
  dbg_abbrev->push_back(DW_FORM_addr);

  // DW_AT_high_pc DW_FORM_addr.
  dbg_abbrev->push_back(DW_AT_high_pc);
  dbg_abbrev->push_back(DW_FORM_addr);

  // End of DW_TAG_compile_unit.
  PushHalf(dbg_abbrev, 0);

  // Tag 2: Compilation unit: DW_TAG_subprogram.
  dbg_abbrev->push_back(2);
  dbg_abbrev->push_back(DW_TAG_subprogram);

  // There are no children.
  dbg_abbrev->push_back(DW_CHILDREN_no);

  // Name of the method.
  dbg_abbrev->push_back(DW_AT_name);
  dbg_abbrev->push_back(DW_FORM_strp);

  // DW_AT_low_pc DW_FORM_addr.
  dbg_abbrev->push_back(DW_AT_low_pc);
  dbg_abbrev->push_back(DW_FORM_addr);

  // DW_AT_high_pc DW_FORM_addr.
  dbg_abbrev->push_back(DW_AT_high_pc);
  dbg_abbrev->push_back(DW_FORM_addr);

  // End of DW_TAG_subprogram.
  PushHalf(dbg_abbrev, 0);

  // Start the debug_info section with the header information
  // 'unit_length' will be filled in later.
  PushWord(dbg_info, 0);

  // 'version' - 3.
  PushHalf(dbg_info, 3);

  // Offset into .debug_abbrev section (always 0).
  PushWord(dbg_info, 0);

  // Address size: 4.
  dbg_info->push_back(4);

  // Start the description for the compilation unit.
  // This uses tag 1.
  dbg_info->push_back(1);

  // The language is Java.
  dbg_info->push_back(DW_LANG_Java);

  // Leave space for low_pc and high_pc.
  int low_pc_offset = dbg_info->size();
  PushWord(dbg_info, 0);
  PushWord(dbg_info, 0);

  // Walk through the information in the method table, and enter into dbg_info.
  const std::vector<OatWriter::DebugInfo>& dbg = oat_writer->GetCFIMethodInfo();
  uint32_t low_pc = 0xFFFFFFFFU;
  uint32_t high_pc = 0;

  for (uint32_t i = 0; i < dbg.size(); i++) {
    const OatWriter::DebugInfo& info = dbg[i];
    if (info.low_pc_ < low_pc) {
      low_pc = info.low_pc_;
    }
    if (info.high_pc_ > high_pc) {
      high_pc = info.high_pc_;
    }

    // Start a new TAG: subroutine (2).
    dbg_info->push_back(2);

    // Enter the name into the string table (and NUL terminate).
    uint32_t str_offset = dbg_str->size();
    dbg_str->insert(dbg_str->end(), info.method_name_.begin(), info.method_name_.end());
    dbg_str->push_back('\0');

    // Enter name, low_pc, high_pc.
    PushWord(dbg_info, str_offset);
    PushWord(dbg_info, info.low_pc_);
    PushWord(dbg_info, info.high_pc_);
  }

  // One byte terminator
  dbg_info->push_back(0);

  // We have now walked all the methods.  Fill in lengths and low/high PCs.
  UpdateWord(dbg_info, 0, dbg_info->size() - 4);
  UpdateWord(dbg_info, low_pc_offset, low_pc);
  UpdateWord(dbg_info, low_pc_offset + 4, high_pc);
}

}  // namespace art
