// Copyright 2024 Google LLC
//
// 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
//
//     https://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 "mpact/sim/util/asm/simple_assembler.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <functional>
#include <istream>
#include <ostream>
#include <string>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/bind_front.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "elfio/elf_types.hpp"
#include "elfio/elfio.hpp"  // IWYU pragma: keep
#include "elfio/elfio_section.hpp"
#include "elfio/elfio_segment.hpp"
#include "elfio/elfio_strings.hpp"
#include "elfio/elfio_symbols.hpp"
#include "mpact/sim/util/asm/opcode_assembler_interface.h"
#include "mpact/sim/util/asm/resolver.h"
#include "mpact/sim/util/asm/resolver_interface.h"
#include "re2/re2.h"

namespace mpact {
namespace sim {
namespace util {
namespace assembler {

// Helper functions for parsing the assembly code.
namespace {

// This template is used to convert the given type to the smallest valid type
// that absl Atoi functions can handle.
template <typename T>
struct AtoIType {
  using type = T;
};

template <>
struct AtoIType<char> {
  using type = int32_t;
};

template <>
struct AtoIType<uint8_t> {
  using type = uint32_t;
};

template <>
struct AtoIType<uint16_t> {
  using type = uint32_t;
};

template <>
struct AtoIType<int16_t> {
  using type = int32_t;
};

template <>
struct AtoIType<int8_t> {
  using type = int32_t;
};

// Convert the text to an integer. Checks for a leading 0x and then converts
// using absl::SimpleHexAtoi. If the text does not start with 0x, then it
// converts using absl::SimpleAtoi. If the text is not a valid integer, then
// it calls the resolver to see if it is a symbol name, in which case it returns
// the value of the symbol. If the text is not a valid integer or symbol name,
// then it returns an error.
template <typename T>
absl::StatusOr<T> SimpleTextToInt(absl::string_view text,
                                  ResolverInterface *resolver = nullptr) {
  T value;
  if (text.substr(0, 2) == "0x") {
    if (absl::SimpleHexAtoi(text.substr(2), &value)) return value;
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid immediate: ", text));
  }
  if (absl::SimpleAtoi(text, &value)) return value;
  if (resolver == nullptr) {
    return absl::InvalidArgumentError(absl::StrCat("Invalid argument: ", text));
  }
  auto result = resolver->Resolve(text);
  if (!result.ok()) {
    return absl::InvalidArgumentError(absl::StrCat("Invalid argument: ", text));
  }
  return static_cast<T>(result.value());
}

// Expand escaped characters in the given text. This is for use in parsing
// .string, .char, and .cstring directives.
std::string ExpandEscapes(absl::string_view text) {
  std::string result;
  bool in_escape = false;
  for (auto c : text) {
    if (in_escape) {
      switch (c) {
        case 'n':
          result.push_back('\n');
          break;
        case 'r':
          result.push_back('\r');
          break;
        case 'v':
          result.push_back('\v');
          break;
        case 'f':
          result.push_back('\f');
          break;
        case 'a':
          result.push_back('\a');
          break;
        case 'b':
          result.push_back('\b');
          break;
        case 't':
          result.push_back('\t');
          break;
        case '\\':
          result.push_back('\\');
          break;
        case '\'':
          result.push_back('\'');
          break;
        case '"':
          result.push_back('"');
          break;
        case '\?':
          result.push_back('?');
          break;
        default:
          result.push_back('\\');
          result.push_back(c);
          break;
      }
      in_escape = false;
      continue;
    }
    if (c == '\\') {
      in_escape = true;
      continue;
    }
    result.push_back(c);
  }
  if (in_escape) result.push_back('\\');
  return result;
}

// This function is used to parse a list of values from the remainder of an
// assembly directive. The values are separated by commas. The type T is the
// type of the values, and must be an integer type or char. The resolver
// interface is optional and is used to resolve any symbol names in the text.
template <typename T>
absl::StatusOr<std::vector<T>> GetValues(
    absl::string_view remainder, ResolverInterface *resolver = nullptr) {
  std::vector<T> values;
  static RE2 value_re("\\s*(0x[0-9a-fA-F]+|-?[0-9]+)\\s*(?:,|$)");
  std::string match;
  while (RE2::Consume(&remainder, value_re, &match)) {
    auto result = SimpleTextToInt<typename AtoIType<T>::type>(match);
    if (!result.ok()) return result.status();
    T value = static_cast<T>(result.value());
    values.push_back(value);
  }
  return values;
}

// Specialization of the above that handles char values.
template <>
absl::StatusOr<std::vector<char>> GetValues<char>(absl::string_view remainder,
                                                  ResolverInterface *resolver) {
  std::vector<char> values;
  static RE2 value_re("\\s*'(.{1,2})'\\s*(?:,|$)");
  std::string match;
  while (RE2::Consume(&remainder, value_re, &match)) {
    auto expanded = ExpandEscapes(match);
    if (expanded.size() != 1)
      return absl::InvalidArgumentError(
          absl::StrCat("Invalid character: '", match, "'"));
    values.push_back(expanded[0]);
  }
  return values;
}

// Specialization of the above that handles double quoted string values.
template <>
absl::StatusOr<std::vector<std::string>> GetValues<std::string>(
    absl::string_view remainder, ResolverInterface *resolver) {
  std::vector<std::string> values;
  std::string match;
  static RE2 value_re("\\s*\"([^\"]*)\"\\s*(?:,|$)");
  while (RE2::Consume(&remainder, value_re, &match)) {
    values.push_back(ExpandEscapes(match));
  }
  return values;
}

// Specialization of the above that handles labels (string values without
// quotes).
absl::StatusOr<std::vector<std::string>> GetLabels(
    absl::string_view remainder) {
  std::vector<std::string> values;
  std::string match;
  static RE2 label_re("\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:,|$)");
  while (RE2::Consume(&remainder, label_re, &match)) {
    values.push_back(match);
  }
  return values;
}

// Helper that converts a vector of integer values to a vector of bytes.
template <typename T>
inline void ConvertToBytes(const std::vector<T> &values,
                           std::vector<uint8_t> &bytes) {
  union {
    T i;
    uint8_t b[sizeof(T)];
  } u;
  for (auto value : values) {
    u.i = value;
    for (int i = 0; i < sizeof(T); i++) {
      bytes.push_back(u.b[i]);
    }
  }
}

}  // namespace

SimpleAssembler::SimpleAssembler(absl::string_view comment, int elf_file_class,
                                 OpcodeAssemblerInterface *opcode_assembler_if)
    : elf_file_class_(elf_file_class),
      opcode_assembler_if_(opcode_assembler_if),
      comment_re_(absl::StrCat("^(.*?)(?:", comment, ".*?)?(\\\\)?$")),
      asm_line_re_("^(?:(?:(\\S+)\\s*:)?|\\s)\\s*(.*)\\s*$"),
      directive_re_(
          "^\\.(align|bss|bytes|char|cstring|data|global|long|sect"
          "|short|space|string|type|text|uchar|ulong|ushort|uword|word)(?:\\s+("
          ".*)"
          ")?\\s*"
          "$") {
  // Configure the ELF file writer.
  writer_.create(elf_file_class_, ELFDATA2LSB);
  writer_.set_os_abi(ELFOSABI_NONE);
  writer_.set_machine(EM_NONE);
  // Create the symbol table section.
  symtab_ = writer_.sections.add(".symtab");
  section_index_map_.insert({symtab_->get_index(), symtab_});
  symtab_->set_type(SHT_SYMTAB);
  symtab_->set_addr_align(0x8);
  symtab_->set_entry_size(elf_file_class_ == ELFCLASS64
                              ? sizeof(ELFIO::Elf64_Sym)
                              : sizeof(ELFIO::Elf32_Sym));
  // Create the string table section.
  strtab_ = writer_.sections.add(".strtab");
  section_index_map_.insert({strtab_->get_index(), strtab_});
  strtab_->set_type(SHT_STRTAB);
  strtab_->set_addr_align(0x1);
  // Link the symbol table to the string table.
  symtab_->set_link(strtab_->get_index());
  // Create the symbol and string table accessors.
  symbol_accessor_ = new ELFIO::symbol_section_accessor(writer_, symtab_);
  string_accessor_ =
      new ELFIO::string_section_accessor(writer_.sections[".strtab"]);
  // Create .text, .data. and .bss sections.
  SetTextSection(".text");
  SetDataSection(".data");
  SetBssSection(".bss");
  // Clear the current section.
  current_section_ = nullptr;
}

SimpleAssembler::~SimpleAssembler() {
  delete symbol_accessor_;
  symbol_accessor_ = nullptr;
  delete string_accessor_;
  string_accessor_ = nullptr;
}

absl::Status SimpleAssembler::Parse(std::istream &is,
                                    ResolverInterface *zero_resolver) {
  // A trivial symbol resolver that always returns 0.
  bool own_zero_resolver = false;
  std::function<void()> cleanup = []() {};
  if (zero_resolver == nullptr) {
    zero_resolver = new ZeroResolver(
        absl::bind_front(&SimpleAssembler::SimpleAddSymbol, this));
    own_zero_resolver = true;
    cleanup = [zero_resolver]() { delete zero_resolver; };
  }
  // First pass of parsing the input stream. This will add symbols to the symbol
  // table and compute the sizes of all instructions and the sections. The
  // section_address_map_ will keep track of the current location within each
  // section (i.e., the offset within the section of the next
  // instruction/object).
  std::string label;
  std::string statement;
  while (is.good() && !is.eof()) {
    std::string line;
    while (true) {
      std::string tmp;
      if (!is.good() || is.eof()) break;
      getline(is, tmp);
      std::string prefix;
      std::string suffix;
      // Remove comments from the input line.
      if (!RE2::FullMatch(tmp, comment_re_, &prefix, &suffix)) {
        return absl::InternalError("Failed to parse comment");
      }
      tmp = absl::StrCat(prefix, suffix);
      int len = tmp.length();
      // If there is an escaped newline then append the line, up to the  '\',
      // and continue.
      if ((len >= 1) && (tmp[len - 1] == '\\')) {
        // Insert the escaped newline that getline removed.
        absl::StrAppend(&line, tmp, "\n");
        continue;
      }
      absl::StrAppend(&line, tmp);
      break;
    }
    if (line.empty()) continue;
    // Parse the line into a label and a statement. This is done to determine if
    // the line contains a label, only a label, or if the statement is directive
    // or not.
    if (RE2::FullMatch(line, asm_line_re_, &label, &statement)) {
      std::vector<uint8_t> byte_vector;
      std::vector<RelocationInfo> relo_vector;
      auto *section = current_section_;
      uint64_t address =
          (section == nullptr) ? 0 : section_address_map_[section];
      if (!statement.empty()) {
        absl::Status status;
        // Pass the full line into the parse functions, they are responsible
        // for handling the labels in pass one.
        if (statement[0] == '.') {
          status = ParseAsmDirective(line, address, zero_resolver, byte_vector,
                                     relo_vector);
        } else {
          status = ParseAsmStatement(line, address, zero_resolver, byte_vector,
                                     relo_vector);
        }
        if (!status.ok()) return status;
        // Save the statements for processing in pass two (labels are all
        // processed in pass one).
        lines_.push_back(statement);
      } else if (!label.empty()) {
        // This is just a single label definition. Add it to the symbol table.
        uint64_t symbol_address = address;
        if ((current_section_ == data_section_) ||
            (current_section_ == bss_section_)) {
          symbol_address = address / data_address_unit_;
        }
        auto status = AddSymbolToCurrentSection(label, symbol_address, 0,
                                                STT_NOTYPE, 0, 0);
        if (!status.ok()) return status;
      }
      continue;
    }
    // Parse failure.
    cleanup();
    return absl::AbortedError(absl::StrCat("Parse failure: '", line, "'"));
  }

  if (!is.eof()) {
    cleanup();
    return absl::InternalError("Input stream entered bad state");
  }

  // Add undefined symbols to the symbol table.
  for (auto const &symbol : undefined_symbols_) {
    auto status = AddSymbol(symbol, 0, 0, STT_NOTYPE, 0, 0, nullptr);
    if (!status.ok()) {
      cleanup();
      return absl::InternalError(absl::StrCat(
          "Failed to add undefined symbol '", symbol, "': ", status.message()));
    }
  }
  undefined_symbols_.clear();

  if (bss_section_ != nullptr) {
    bss_section_->set_size(section_address_map_[bss_section_]);
  }
  cleanup();
  return absl::OkStatus();
}

absl::Status SimpleAssembler::CreateExecutable(
    uint64_t base_address, uint64_t entry_point,
    ResolverInterface *symbol_resolver) {
  return CreateExecutable(base_address, absl::StrCat(entry_point),
                          symbol_resolver);
}

// Helper function to update the symbol table entries for an executable file.
template <typename SymbolType>
void SimpleAssembler::UpdateSymbolsForExecutable(uint64_t text_segment_start,
                                                 uint64_t data_segment_start,
                                                 uint64_t bss_segment_start) {
  auto num_symbols = symtab_->get_size() / sizeof(SymbolType);
  auto size = num_symbols * sizeof(SymbolType);
  auto *symbols = new SymbolType[num_symbols];
  std::memcpy(symbols, symtab_->get_data(), size);
  for (int i = 0; i < num_symbols; ++i) {
    auto &sym = symbols[i];
    auto shndx = sym.st_shndx;
    std::string name = string_accessor_->get_string(sym.st_name);
    if (global_symbols_.contains(name)) {
      sym.st_info = ELF_ST_INFO(STB_GLOBAL, ELF_ST_TYPE(sym.st_info));
    }
    if ((text_section_ != nullptr) && (shndx == text_section_->get_index())) {
      sym.st_value += text_segment_start;
    } else if ((data_section_ != nullptr) &&
               (shndx == data_section_->get_index())) {
      sym.st_value += data_segment_start;
    } else if ((bss_section_ != nullptr) &&
               (shndx == bss_section_->get_index())) {
      sym.st_value += bss_segment_start;
    }
  }
  symtab_->set_data(reinterpret_cast<char *>(symbols), size);
  delete[] symbols;
}

template <typename SymbolType>
void SimpleAssembler::UpdateSymbolsForRelocatable() {
  auto num_symbols = symtab_->get_size() / sizeof(SymbolType);
  auto size = num_symbols * sizeof(SymbolType);
  auto *symbols = new SymbolType[num_symbols];
  std::memcpy(symbols, symtab_->get_data(), size);
  for (int i = 0; i < num_symbols; ++i) {
    auto &sym = symbols[i];
    std::string name = string_accessor_->get_string(sym.st_name);
    if (global_symbols_.contains(name)) {
      sym.st_info = ELF_ST_INFO(STB_GLOBAL, ELF_ST_TYPE(sym.st_info));
    }
  }
  symtab_->set_data(reinterpret_cast<char *>(symbols), size);
  delete[] symbols;
}

absl::Status SimpleAssembler::CreateExecutable(
    uint64_t base_address, const std::string &entry_point,
    ResolverInterface *symbol_resolver) {
  if (!undefined_symbols_.empty()) {
    std::string message;
    absl::StrAppend(
        &message,
        "Cannot create executable with the following undefined symbols: ");
    for (auto const &symbol : undefined_symbols_) {
      absl::StrAppend(&message, "    ", symbol, "\n");
    }
    return absl::InvalidArgumentError(message);
  }
  writer_.set_type(ET_EXEC);
  // Section sizes are now known. So let's compute the layout and update all
  // the symbol values/addresses before the next pass.
  // The layout is:
  //   text segment starting at base address + any alignment.
  //   data segment starting at the end of the text segment + any alignment.
  // The bss section is added to the end of the data segment + any alignment.

  ELFIO::segment *text_segment = nullptr;
  uint64_t text_segment_start = 0;
  if (text_section_ != nullptr) {
    text_segment_start = base_address & ~4095ULL;
    text_segment = writer_.segments.add();
    if (text_segment == nullptr) {
      return absl::InternalError("Failed to create elf segment for text");
    }
    text_segment->set_type(PT_LOAD);
    text_segment->set_virtual_address(text_segment_start);
    text_segment->set_physical_address(text_segment_start);
    text_segment->set_flags(PF_X | PF_R);
    text_segment->set_align(4096);
  }

  ELFIO::segment *data_segment = nullptr;
  uint64_t data_segment_start = 0;
  uint64_t bss_segment_start = 0;
  if ((data_section_ != nullptr) || (bss_section_ != nullptr)) {
    data_segment_start =
        (text_segment_start + section_address_map_[text_section_] + 4095) &
        ~4095ULL;

    data_segment = writer_.segments.add();
    if (data_segment == nullptr) {
      return absl::InternalError("Failed to create elf segment for data");
    }
    data_segment->set_type(PT_LOAD);
    data_segment->set_virtual_address(data_segment_start);
    data_segment->set_physical_address(data_segment_start);
    data_segment->set_flags(PF_W | PF_R);
    data_segment->set_align(4096);

    uint64_t bss_align = bss_section_->get_addr_align() - 1;
    bss_segment_start =
        (data_segment_start + section_address_map_[data_section_] + bss_align) &
        ~bss_align;
  }

  // Now we can update the symbol table based on the new section sizes.

  // Different size symbol table entries for 32 and 64 bit ELF files.
  if (elf_file_class_ == ELFCLASS64) {
    UpdateSymbolsForExecutable<ELFIO::Elf64_Sym>(
        text_segment_start, data_segment_start, bss_segment_start);
  } else if (elf_file_class_ == ELFCLASS32) {
    UpdateSymbolsForExecutable<ELFIO::Elf32_Sym>(
        text_segment_start, data_segment_start, bss_segment_start);
  } else {
    return absl::InternalError(
        absl::StrCat("Unsupported ELF file class: ", elf_file_class_));
  }

  // Update the section address map so that each section starts at the right
  // address, i.e., it no longer tracks the offset within each section, but the
  // absolute address.
  section_address_map_[text_section_] = text_segment_start;
  section_address_map_[data_section_] = data_segment_start;
  section_address_map_[bss_section_] = bss_segment_start;

  std::function<void()> cleanup = []() {};
  if (symbol_resolver == nullptr) {
    symbol_resolver =
        new SymbolResolver(elf_file_class_, symtab_, symbol_indices_);
    cleanup = [symbol_resolver]() { delete symbol_resolver; };
  }
  // Pass in the relocation vector to the second pass of parsing, but ignore
  // the values, since we are creating an executable file, and all the symbols
  // are resolved.
  std::vector<RelocationInfo> relo_vector;
  auto status = ParsePassTwo(relo_vector, symbol_resolver);
  if (!status.ok()) {
    cleanup();
    return status;
  }

  // Add sections to the segments. First segment gets the text section. The
  // second segment gets the data and bss sections.
  if (text_segment != nullptr) {
    text_segment->add_section_index(text_section_->get_index(),
                                    text_section_->get_addr_align());
  }
  if (data_segment != nullptr) {
    data_segment->add_section_index(data_section_->get_index(),
                                    data_section_->get_addr_align());
    data_segment->add_section_index(bss_section_->get_index(),
                                    bss_section_->get_addr_align());
  }

  auto res = SimpleTextToInt<uint64_t>(entry_point, symbol_resolver);
  if (!res.ok()) {
    cleanup();
    return res.status();
  }
  uint64_t entry_point_value = res.value();

  symbol_accessor_->arrange_local_symbols();
  writer_.set_entry(entry_point_value);
  cleanup();
  return absl::OkStatus();
}

namespace {

// Helper function to add a relocation entry to a relocation section.
template <typename RelocaType>
absl::Status AddRelocationEntries(
    const std::vector<RelocationInfo> &relo_vector,
    absl::flat_hash_map<std::string, ELFIO::Elf_Word> &symbol_indices,
    ELFIO::section *reloca_section) {
  for (auto const &relo : relo_vector) {
    RelocaType rela;
    rela.r_offset = relo.offset;
    rela.r_addend = relo.addend;
    auto iter = symbol_indices.find(relo.symbol);
    if (iter == symbol_indices.end()) {
      return absl::InvalidArgumentError(
          absl::StrCat("Symbol '", relo.symbol, "' not found"));
    }
    if (sizeof(RelocaType) == sizeof(ELFIO::Elf64_Rela)) {
      rela.r_info = ELF64_R_INFO(iter->second, relo.type);
    } else {
      rela.r_info = ELF32_R_INFO(iter->second, relo.type);
    }
    reloca_section->append_data(reinterpret_cast<const char *>(&rela),
                                sizeof(RelocaType));
  }
  return absl::OkStatus();
}

}  // namespace

template <typename SymbolType>
void SimpleAssembler::UpdateSymtabHeaderInfo() {
  int last_local = 0;
  auto syms =
      absl::MakeSpan(reinterpret_cast<const SymbolType *>(symtab_->get_data()),
                     symtab_->get_size() / sizeof(SymbolType));
  for (int i = 0; i < syms.size(); ++i) {
    auto name = string_accessor_->get_string(syms[i].st_name);
    symbol_indices_.insert({name, i});
    if (ELF_ST_BIND(syms[i].st_info) == STB_LOCAL) last_local = i;
  }
  symtab_->set_info(last_local + 1);
}

absl::Status SimpleAssembler::CreateRelocatable(
    ResolverInterface *symbol_resolver) {
  writer_.set_type(ET_REL);
  // Reset the section address map to zero since we are creating a relocatable
  // file.
  section_address_map_[text_section_] = 0;
  section_address_map_[data_section_] = 0;
  section_address_map_[bss_section_] = 0;

  // Since the symbols now are rearranged, we need to set global symbols flag
  // for those in the global_symbols_ set.
  // Different size symbol table entries for 32 and 64 bit ELF files.
  if (elf_file_class_ == ELFCLASS64) {
    UpdateSymbolsForRelocatable<ELFIO::Elf64_Sym>();
  } else if (elf_file_class_ == ELFCLASS32) {
    UpdateSymbolsForRelocatable<ELFIO::Elf32_Sym>();
  } else {
    return absl::InternalError(
        absl::StrCat("Unsupported ELF file class: ", elf_file_class_));
  }
  // Rearrange local symbols in the symbol table so that they are at the
  // beginning (ELF requirement).
  symbol_accessor_->arrange_local_symbols(nullptr);
  // Find the last local symbol and set the section header info for symbtab
  // to point to 1 past that. Update the symbol_indices_ map.
  symbol_indices_.clear();
  if (elf_file_class_ == ELFCLASS64) {
    UpdateSymtabHeaderInfo<ELFIO::Elf64_Sym>();
  } else {
    UpdateSymtabHeaderInfo<ELFIO::Elf32_Sym>();
  }

  std::function<void()> cleanup = []() {};
  if (symbol_resolver == nullptr) {
    symbol_resolver =
        new SymbolResolver(elf_file_class_, symtab_, symbol_indices_);
    cleanup = [symbol_resolver]() { delete symbol_resolver; };
  }
  // Parse the source again, collect relocations.
  std::vector<RelocationInfo> relo_vector;
  auto status = ParsePassTwo(relo_vector, symbol_resolver);
  if (!status.ok()) {
    cleanup();
    return status;
  }

  // Handle relocations if there are any.
  if (!relo_vector.empty()) {
    // First scan through the entries relocation vector and group them by
    // the section in which the relocation is to be applied.
    absl::flat_hash_map<uint16_t, std::vector<RelocationInfo>> relo_map;
    for (auto const &relo : relo_vector) {
      relo_map[relo.section_index].push_back(relo);
    }
    for (auto const &[section_index, relo_vec] : relo_map) {
      if (section_index == 0) {
        cleanup();
        return absl::InternalError(
            "Relocation entry with section index 0 not supported");
      }
      if (!section_index_map_.contains(section_index)) {
        cleanup();
        return absl::InternalError(
            absl::StrCat("Section index not found: ", section_index));
      }
      // Now, create a relocation section for each key in the map.
      std::string name =
          absl::StrCat(".rela", section_index_map_[section_index]->get_name());
      auto *rela_section = writer_.sections.add(name);
      rela_section->set_type(SHT_RELA);
      rela_section->set_flags(SHF_INFO_LINK);
      rela_section->set_entry_size(elf_file_class_ == ELFCLASS64
                                       ? sizeof(ELFIO::Elf64_Rela)
                                       : sizeof(ELFIO::Elf32_Rela));
      rela_section->set_link(symtab_->get_index());
      rela_section->set_info(text_section_->get_index());
      rela_section->set_addr_align(8);
      // Process the relocation vector entries.
      absl::Status status;
      if (elf_file_class_ == ELFCLASS64) {
        status = AddRelocationEntries<ELFIO::Elf64_Rela>(
            relo_vec, symbol_indices_, rela_section);
      } else if (elf_file_class_ == ELFCLASS32) {
        status = AddRelocationEntries<ELFIO::Elf32_Rela>(
            relo_vec, symbol_indices_, rela_section);
      } else {
        cleanup();
        return absl::InternalError(
            absl::StrCat("Unsupported ELF file class: ", elf_file_class_));
      }
      if (!status.ok()) {
        cleanup();
        return status;
      }
    }
  }
  cleanup();
  return absl::OkStatus();
}

absl::Status SimpleAssembler::ParsePassTwo(
    std::vector<RelocationInfo> &relo_vector,
    ResolverInterface *symbol_resolver) {
  // Now fill in the sections. Parse each of the lines saved in the first
  // pass.
  for (auto const &line : lines_) {
    std::vector<uint8_t> byte_vector;
    absl::Status status;
    auto *section = current_section_;
    auto relo_size = relo_vector.size();
    auto address = section_address_map_[section];
    if (line[0] == '.') {
      auto status = ParseAsmDirective(line, address, symbol_resolver,
                                      byte_vector, relo_vector);
    } else {
      auto status = ParseAsmStatement(line, address, symbol_resolver,
                                      byte_vector, relo_vector);
    }
    if (!status.ok()) return status;
    // Update section information in the relocation vector.
    for (int i = relo_size; i < relo_vector.size(); ++i) {
      relo_vector[i].section_index = section->get_index();
      relo_vector[i].offset = address;
    }
    // Go to the next line if there is no data to add to the section.
    if (byte_vector.empty()) continue;
    // Add data to the section, but first make sure it's not bss.
    if (section != bss_section_) {
      if (section == nullptr) {
        return absl::InternalError("Data is added to a null section");
      }
      section->append_data(reinterpret_cast<const char *>(byte_vector.data()),
                           byte_vector.size());
    }
  }
  return absl::OkStatus();
}

// Top level function that writes the ELF file out to disk.
absl::Status SimpleAssembler::Write(std::ostream &os) {
  writer_.save(os);
  return absl::OkStatus();
}

// Parse and process an assembly directive. The assembly directive is
// expected to be in the form of a line starting with a period followed by a
// directive name and an optional argument. The argument is a string of
// tokens separated by spaces. The argument is parsed using regular
// expressions. The byte values are appended to the given vector.
absl::Status SimpleAssembler::ParseAsmDirective(
    absl::string_view line, uint64_t address, ResolverInterface *resolver,
    std::vector<uint8_t> &byte_values,
    std::vector<RelocationInfo> &relocations) {
  std::string match;
  std::string remainder;
  ELFIO::section *section = current_section_;
  uint64_t size = 0;
  std::string directive;
  std::string label;
  if (!RE2::FullMatch(line, asm_line_re_, &label, &directive)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid assembly line: '", line, "'"));
  }
  if (!RE2::FullMatch(directive, directive_re_, &match, &remainder)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid directive: '", directive, "'"));
  }
  if (match == "align") {
    // .align <n>
    if (section == nullptr) {
      return absl::InvalidArgumentError(
          absl::StrCat("No section for directive: '", directive, "'"));
    }
    auto res = SimpleTextToInt<uint64_t>(remainder);
    if (!res.ok()) return res.status();
    uint64_t align = res.value();
    // Verify that the alignment is a power of two.
    if ((align & (align - 1)) != 0) {
      return absl::InvalidArgumentError(
          absl::StrCat("Invalid alignment: '", directive, "'"));
    }
    uint64_t address = section_address_map_[section];
    size = ((address + align - 1) & ~(align - 1)) - address;
  } else if (match == "bss") {
    // .bss
    SetBssSection(".bss");
  } else if (match == "bytes") {
    // .bytes
    auto res = GetValues<uint8_t>(remainder, resolver);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size();
    for (auto const &value : values) byte_values.push_back(value);
  } else if (match == "char") {
    // .char
    auto res = GetValues<char>(remainder, resolver);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size();
    for (auto const &value : values) byte_values.push_back(value);
  } else if (match == "cstring") {
    // .cstring
    auto res = GetValues<std::string>(remainder, resolver);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = 0;
    for (auto const &value : values) {
      for (auto const &c : value) byte_values.push_back(c);
      byte_values.push_back('\0');
      size += value.size() + 1;
    }
  } else if (match == "data") {
    // .data
    SetDataSection(".data");
  } else if (match == "global") {
    // .global <name>
    auto res = GetLabels(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    for (auto const &value : values) {
      global_symbols_.insert(value);
    }
  } else if (match == "long") {
    // .long
    auto res = GetValues<int64_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size() * sizeof(int64_t);
    ConvertToBytes<int64_t>(values, byte_values);
  } else if (match == "sect") {
    // .section <name>,<type>
    // TODO(torerik): Implement.
    return absl::UnimplementedError("Section directive not implemented");
  } else if (match == "short") {
    // .short
    auto res = GetValues<int16_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size() * sizeof(int16_t);
    ConvertToBytes<int16_t>(values, byte_values);
  } else if (match == "space") {
    // .space <n>
    auto res = SimpleTextToInt<uint64_t>(remainder);
    if (!res.ok()) return res.status();
    size = res.value();
  } else if (match == "string") {
    // .string
    auto res = GetValues<std::string>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = 0;
    for (auto const &value : values) {
      for (auto const &c : value) byte_values.push_back(c);
      size += value.size();
    }
  } else if (match == "text") {
    // .text
    SetTextSection(".text");
  } else if (match == "uchar") {
    // .uchar
    auto res = GetValues<uint8_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size();
    for (auto const &value : values) byte_values.push_back(value);
  } else if (match == "ulong") {
    // .ulong
    auto res = GetValues<uint64_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size() * sizeof(uint64_t);
    ConvertToBytes<uint64_t>(values, byte_values);
  } else if (match == "ushort") {
    // .ushort
    auto res = GetValues<uint16_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size() * sizeof(uint16_t);
    ConvertToBytes<uint16_t>(values, byte_values);
  } else if (match == "uword") {
    // .uword
    auto res = GetValues<uint32_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size() * sizeof(uint32_t);
    ConvertToBytes<uint32_t>(values, byte_values);
  } else if (match == "word") {
    // .word
    auto res = GetValues<int32_t>(remainder);
    if (!res.ok()) return res.status();
    auto values = res.value();
    size = values.size() * sizeof(int32_t);
    ConvertToBytes<int32_t>(values, byte_values);
  } else {
    return absl::InvalidArgumentError(
        absl::StrCat("Unsupported directive: '", directive, "'"));
  }
  if ((size > 0) && (section != nullptr)) {
    if (!section_address_map_.contains(section)) {
      return absl::InternalError(
          absl::StrCat("No address for section '", section->get_name(), "'"));
    }
    section_address_map_[section] += size;
  }

  if (!label.empty()) {
    // When initially adding symbols, the address is relative to the start
    // of the containing section. This will be corrected later.
    if (section == nullptr) {
      return absl::InvalidArgumentError(
          absl::StrCat("Label: '", label, "' defined outside of a section"));
    }
    auto status =
        AddSymbol(label, address, size, STT_NOTYPE, STB_LOCAL, 0, section);
  }
  return absl::OkStatus();
}

// Parse and process an assembly statement. The assembly statement is
// expected to be a single line of text. The byte values are appended to the
// given vector.
absl::Status SimpleAssembler::ParseAsmStatement(
    absl::string_view line, uint64_t address, ResolverInterface *resolver,
    std::vector<uint8_t> &byte_values,
    std::vector<RelocationInfo> &relocations) {
  // Call the target specific assembler to encode the statement.
  auto result = opcode_assembler_if_->Encode(
      address, line,
      absl::bind_front(&SimpleAssembler::AddSymbolToCurrentSection, this),
      resolver, byte_values, relocations);
  if (!result.ok()) return result.status();
  section_address_map_[current_section_] += result.value();
  return absl::OkStatus();
}

void SimpleAssembler::SetTextSection(const std::string &name) {
  // First check if the section already exists.
  auto *section = writer_.sections[name];
  if (section != nullptr) {
    current_section_ = section;
    return;
  }
  section = writer_.sections.add(name);
  auto status = AddSymbol(name, 0, 0, STT_SECTION, STB_LOCAL, 0, section);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to add symbol for data section: " << status.message();
  }
  section->set_type(SHT_PROGBITS);
  section->set_flags(SHF_ALLOC | SHF_EXECINSTR);
  section->set_addr_align(0x10);
  // Should probably add the section symbol to the symbol table.
  current_section_ = section;
  text_section_ = section;
  section_index_map_.insert({section->get_index(), text_section_});
}

void SimpleAssembler::SetDataSection(const std::string &name) {
  // First check if the section already exists.
  auto *section = writer_.sections[name];
  if (section != nullptr) {
    current_section_ = section;
    return;
  }
  section = writer_.sections.add(name);
  auto status = AddSymbol(name, 0, 0, STT_SECTION, STB_LOCAL, 0, section);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to add symbol for data section: " << status.message();
  }
  section->set_type(SHT_PROGBITS);
  section->set_flags(SHF_ALLOC | SHF_WRITE);
  section->set_addr_align(0x10);
  // Should probably add the section symbol to the symbol table.
  current_section_ = section;
  data_section_ = section;
  section_index_map_.insert({section->get_index(), data_section_});
}

void SimpleAssembler::SetBssSection(const std::string &name) {
  // First check if the section already exists.
  auto *section = writer_.sections[name];
  if (section != nullptr) {
    current_section_ = section;
    return;
  }
  section = writer_.sections.add(name);
  auto status = AddSymbol(name, 0, 0, STT_SECTION, STB_LOCAL, 0, section);
  if (!status.ok()) {
    LOG(ERROR) << "Failed to add symbol for bss section: " << status.message();
  }
  section->set_type(SHT_NOBITS);
  section->set_flags(SHF_ALLOC | SHF_WRITE);
  section->set_addr_align(0x10);
  // Should probably add the section symbol to the symbol table.
  current_section_ = section;
  bss_section_ = section;
  section_index_map_.insert({section->get_index(), bss_section_});
}
absl::Status SimpleAssembler::AddSymbolToCurrentSection(
    const std::string &name, ELFIO::Elf64_Addr value, ELFIO::Elf_Xword size,
    uint8_t type, uint8_t binding, uint8_t other) {
  return AddSymbol(name, value, size, type, binding, other, current_section_);
}

absl::Status SimpleAssembler::AddSymbol(const std::string &name,
                                        ELFIO::Elf64_Addr value,
                                        ELFIO::Elf_Xword size, uint8_t type,
                                        uint8_t binding, uint8_t other,
                                        const std::string &section_name) {
  ELFIO::section *section = nullptr;
  if (!section_name.empty()) {
    section = writer_.sections[section_name];
    if (section == nullptr) {
      return absl::InvalidArgumentError(
          absl::StrCat("Section '", section_name, "' not found"));
    }
  }
  return AddSymbol(name, value, size, type, binding, other, section);
}

absl::Status SimpleAssembler::AddSymbol(const std::string &name,
                                        ELFIO::Elf64_Addr value,
                                        ELFIO::Elf_Xword size, uint8_t type,
                                        uint8_t binding, uint8_t other,
                                        ELFIO::section *section) {
  auto iter = symbol_indices_.find(name);
  if (iter != symbol_indices_.end()) {
    return absl::AlreadyExistsError(
        absl::StrCat("Symbol '", name, "' already exists"));
  }
  auto index = symbol_accessor_->add_symbol(
      *string_accessor_, name.c_str(), value, size, binding, type, other,
      section == nullptr ? SHN_UNDEF : section->get_index());
  symbol_indices_.insert({name, index});
  // If this is not an undefined symbol reference, then see if the symbol name
  // is part of the "current" undefined symbols, and if so, remove it.
  if (section != nullptr) {
    auto iter = undefined_symbols_.find(name);
    if (iter != undefined_symbols_.end()) {
      undefined_symbols_.erase(iter);
    }
  }
  return absl::OkStatus();
}

void SimpleAssembler::SimpleAddSymbol(absl::string_view name) {
  // If the symbol exists, then just return.
  if (symbol_indices_.contains(name)) return;
  if (undefined_symbols_.contains(name)) return;
  std::string name_str(name);
  undefined_symbols_.insert(name_str);
}

absl::Status SimpleAssembler::AppendData(const char *data, size_t size) {
  if (current_section_ == nullptr) {
    return absl::FailedPreconditionError("No current section");
  }
  current_section_->append_data(data, size);
  return absl::OkStatus();
}

}  // namespace assembler
}  // namespace util
}  // namespace sim
}  // namespace mpact
