// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/elf.h"

#include "platform/elf.h"
#include "vm/cpu.h"
#include "vm/hash_map.h"
#include "vm/thread.h"
#include "vm/zone_text_buffer.h"

namespace dart {

#if defined(TARGET_ARCH_IS_32_BIT)
static const intptr_t kElfHeaderSize = 52;
static const intptr_t kElfSectionTableAlignment = 4;
static const intptr_t kElfSectionTableEntrySize = 40;
static const intptr_t kElfProgramTableEntrySize = 32;
static const intptr_t kElfSymbolTableEntrySize = 16;
static const intptr_t kElfDynamicTableEntrySize = 8;
static const intptr_t kElfSymbolHashTableEntrySize = 4;
#else
static const intptr_t kElfHeaderSize = 64;
static const intptr_t kElfSectionTableAlignment = 8;
static const intptr_t kElfSectionTableEntrySize = 64;
static const intptr_t kElfProgramTableEntrySize = 56;
static const intptr_t kElfSymbolTableEntrySize = 24;
static const intptr_t kElfDynamicTableEntrySize = 16;
static const intptr_t kElfSymbolHashTableEntrySize = 4;
#endif

#define DEFINE_LINEAR_FIELD_METHODS(name, type, init)                          \
  type name() const {                                                          \
    ASSERT(name##_ != init);                                                   \
    return name##_;                                                            \
  }                                                                            \
  void set_##name(type value) {                                                \
    ASSERT(name##_ == init);                                                   \
    name##_ = value;                                                           \
  }

#define DEFINE_LINEAR_FIELD(name, type, init) type name##_ = init;

class Section : public ZoneAllocated {
 public:
  Section(intptr_t type,
          intptr_t segment_type,
          bool allocate,
          bool executable,
          bool writable,
          intptr_t alignment = 1)
      : section_type(type),
        section_flags(EncodeSectionFlags(allocate, executable, writable)),
        alignment(allocate ? SegmentAlignment(alignment) : alignment),
        segment_type(segment_type),
        segment_flags(EncodeSegmentFlags(allocate, executable, writable)),
        // Non-segments will never have a memory offset, here represented by 0.
        memory_offset_(allocate ? -1 : 0) {
    // Only the reserved section (type 0) should have an alignment of 0.
    ASSERT(type == 0 || alignment > 0);
  }

  // The constructor that most subclasses will use.
  Section(intptr_t type,
          bool allocate,
          bool executable,
          bool writable,
          intptr_t alignment = 1)
      : Section(type,
                /*segment_type=*/allocate ? elf::PT_LOAD : 0,
                allocate,
                executable,
                writable,
                alignment) {}

  virtual ~Section() {}

  // Linker view.
  const intptr_t section_type;
  const intptr_t section_flags;
  const intptr_t alignment;

  // These are fields that only are not set for most kinds of sections and so we
  // set them to a reasonable default.
  intptr_t section_link = elf::SHN_UNDEF;
  intptr_t section_info = 0;
  intptr_t section_entry_size = 0;

#define FOR_EACH_SECTION_LINEAR_FIELD(M)                                       \
  M(section_name, intptr_t, -1)                                                \
  M(section_index, intptr_t, -1)                                               \
  M(file_offset, intptr_t, -1)

  FOR_EACH_SECTION_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);

  virtual intptr_t FileSize() = 0;

  // Loader view.
  const intptr_t segment_type;
  const intptr_t segment_flags;

#define FOR_EACH_SEGMENT_LINEAR_FIELD(M) M(memory_offset, intptr_t, -1)

  FOR_EACH_SEGMENT_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);

  virtual intptr_t MemorySize() = 0;

  // Other methods.
  virtual void Write(Elf* stream) = 0;

  void WriteSegmentEntry(Elf* stream, bool dynamic = false) {
    // This should never be used on either the reserved 0-filled section or
    // on sections without a segment.
    ASSERT(MemorySize() > 0);
    // dynamic should only be true if this section is the dynamic table.
    ASSERT(!dynamic || section_type == elf::SHT_DYNAMIC);
#if defined(TARGET_ARCH_IS_32_BIT)
    stream->WriteWord(dynamic ? elf::PT_DYNAMIC : segment_type);
    stream->WriteOff(file_offset());
    stream->WriteAddr(memory_offset());  // Virtual address.
    stream->WriteAddr(memory_offset());  // Physical address, not used.
    stream->WriteWord(FileSize());
    stream->WriteWord(MemorySize());
    stream->WriteWord(segment_flags);
    stream->WriteWord(alignment);
#else
    stream->WriteWord(dynamic ? elf::PT_DYNAMIC : segment_type);
    stream->WriteWord(segment_flags);
    stream->WriteOff(file_offset());
    stream->WriteAddr(memory_offset());  // Virtual address.
    stream->WriteAddr(memory_offset());  // Physical address, not used.
    stream->WriteXWord(FileSize());
    stream->WriteXWord(MemorySize());
    stream->WriteXWord(alignment);
#endif
  }

  void WriteSectionEntry(Elf* stream) {
#if defined(TARGET_ARCH_IS_32_BIT)
    stream->WriteWord(section_name());
    stream->WriteWord(section_type);
    stream->WriteWord(section_flags);
    stream->WriteAddr(memory_offset());
    stream->WriteOff(file_offset());
    stream->WriteWord(FileSize());  // Has different meaning for BSS.
    stream->WriteWord(section_link);
    stream->WriteWord(section_info);
    stream->WriteWord(alignment);
    stream->WriteWord(section_entry_size);
#else
    stream->WriteWord(section_name());
    stream->WriteWord(section_type);
    stream->WriteXWord(section_flags);
    stream->WriteAddr(memory_offset());
    stream->WriteOff(file_offset());
    stream->WriteXWord(FileSize());  // Has different meaning for BSS.
    stream->WriteWord(section_link);
    stream->WriteWord(section_info);
    stream->WriteXWord(alignment);
    stream->WriteXWord(section_entry_size);
#endif
  }

 private:
  static intptr_t EncodeSectionFlags(bool allocate,
                                     bool executable,
                                     bool writable) {
    if (!allocate) return 0;
    intptr_t flags = elf::SHF_ALLOC;
    if (executable) flags |= elf::SHF_EXECINSTR;
    if (writable) flags |= elf::SHF_WRITE;
    return flags;
  }

  static intptr_t EncodeSegmentFlags(bool allocate,
                                     bool executable,
                                     bool writable) {
    if (!allocate) return 0;
    intptr_t flags = elf::PF_R;
    if (executable) flags |= elf::PF_X;
    if (writable) flags |= elf::PF_W;
    return flags;
  }

  static intptr_t SegmentAlignment(intptr_t alignment) {
    return alignment < Elf::kPageSize ? Elf::kPageSize : alignment;
  }

  FOR_EACH_SECTION_LINEAR_FIELD(DEFINE_LINEAR_FIELD);
  FOR_EACH_SEGMENT_LINEAR_FIELD(DEFINE_LINEAR_FIELD);

#undef FOR_EACH_SECTION_LINEAR_FIELD
#undef FOR_EACH_SEGMENT_LINEAR_FIELD
};

#undef DEFINE_LINEAR_FIELD
#undef DEFINE_LINEAR_FIELD_METHODS

// Represents the first entry in the section table, which should only contain
// zero values. Only used for WriteSectionEntry and should never actually appear
// in sections_.
class ReservedSection : public Section {
 public:
  ReservedSection()
      : Section(/*type=*/0,
                /*allocate=*/false,
                /*executable=*/false,
                /*writable=*/false,
                /*alignment=*/0) {
    set_section_name(0);
    set_section_index(0);
    set_file_offset(0);
  }

  intptr_t FileSize() { return 0; }
  intptr_t MemorySize() { return 0; }
  void Write(Elf* stream) { UNREACHABLE(); }
};

class BlobSection : public Section {
 public:
  BlobSection(intptr_t type,
              intptr_t segment_type,
              bool allocate,
              bool executable,
              bool writable,
              intptr_t filesz,
              intptr_t memsz,
              int alignment = 1)
      : Section(type, segment_type, allocate, executable, writable, alignment),
        file_size_(filesz),
        memory_size_(allocate ? memsz : 0) {}

  BlobSection(intptr_t type,
              bool allocate,
              bool executable,
              bool writable,
              intptr_t filesz,
              intptr_t memsz,
              int alignment = 1)
      : BlobSection(type,
                    /*segment_type=*/allocate ? elf::PT_LOAD : 0,
                    allocate,
                    executable,
                    writable,
                    filesz,
                    memsz,
                    alignment) {}

  intptr_t FileSize() { return file_size_; }
  intptr_t MemorySize() { return memory_size_; }

  virtual void Write(Elf* stream) = 0;

 private:
  const intptr_t file_size_;
  const intptr_t memory_size_;
};

// A section for representing the program header segment in the program header
// table. Only used for WriteSegmentEntry.
class ProgramTable : public BlobSection {
 public:
  ProgramTable(intptr_t offset, intptr_t size)
      : BlobSection(/*type=*/0,
                    /*segment_type=*/elf::PT_PHDR,
                    /*allocate=*/true,
                    /*executable=*/false,
                    /*writable=*/false,
                    /*filesz=*/size,
                    /*memsz=*/size) {
    set_file_offset(offset);
    set_memory_offset(offset);
  }

  // This should never actually be added to sections_ or segments_.
  void Write(Elf* stream) { UNREACHABLE(); }
};

// A section for representing the program header table load segment in the
// program header table. Only used for WriteSegmentEntry.
class ProgramTableLoad : public BlobSection {
 public:
  // The Android dynamic linker in Jelly Bean incorrectly assumes that all
  // non-writable segments are continguous. Since the BSS segment comes directly
  // after the program header segment, we must make this segment writable so
  // later non-writable segments does not cause the BSS to be also marked as
  // read-only.
  //
  // The bug is here:
  //   https://github.com/aosp-mirror/platform_bionic/blob/94963af28e445384e19775a838a29e6a71708179/linker/linker.c#L1991-L2001
  explicit ProgramTableLoad(intptr_t size)
      : BlobSection(/*type=*/0,
                    /*allocate=*/true,
                    /*executable=*/false,
                    /*writable=*/true,
                    /*filesz=*/size,
                    /*memsz=*/size) {
    set_file_offset(0);
    set_memory_offset(0);
  }

  // This should never actually be added to sections_ or segments_.
  void Write(Elf* stream) { UNREACHABLE(); }
};

class ProgramBits : public BlobSection {
 public:
  ProgramBits(bool allocate,
              bool executable,
              bool writable,
              const uint8_t* bytes,
              intptr_t filesz,
              intptr_t memsz = -1)
      : BlobSection(elf::SHT_PROGBITS,
                    allocate,
                    executable,
                    writable,
                    filesz,
                    memsz != -1 ? memsz : filesz),
        bytes_(ASSERT_NOTNULL(bytes)) {}

  void Write(Elf* stream) { stream->WriteBytes(bytes_, FileSize()); }

  const uint8_t* bytes_;
};

class NoBits : public BlobSection {
 public:
  NoBits(bool allocate, bool executable, bool writable, intptr_t memsz)
      : BlobSection(elf::SHT_NOBITS,
                    allocate,
                    executable,
                    writable,
                    /*filesz=*/0,
                    memsz) {}

  void Write(Elf* stream) {}
};

class StringTable : public Section {
 public:
  explicit StringTable(bool allocate)
      : Section(elf::SHT_STRTAB,
                allocate,
                /*executable=*/false,
                /*writable=*/false),
        dynamic_(allocate),
        text_(Thread::Current()->zone(), 128),
        text_indices_() {
    text_.AddChar('\0');
    text_indices_.Insert({"", 1});
  }

  intptr_t FileSize() { return text_.length(); }
  intptr_t MemorySize() { return dynamic_ ? FileSize() : 0; }

  void Write(Elf* stream) {
    stream->WriteBytes(reinterpret_cast<const uint8_t*>(text_.buffer()),
                       text_.length());
  }

  intptr_t AddString(const char* str) {
    if (auto const kv = text_indices_.Lookup(str)) return kv->value - 1;
    intptr_t offset = text_.length();
    text_.AddString(str);
    text_.AddChar('\0');
    text_indices_.Insert({str, offset + 1});
    return offset;
  }

  const bool dynamic_;
  ZoneTextBuffer text_;
  // To avoid kNoValue for intptr_t (0), we store an index n as n + 1.
  CStringMap<intptr_t> text_indices_;
};

class Symbol : public ZoneAllocated {
 public:
  Symbol(const char* cstr,
         intptr_t name,
         intptr_t info,
         intptr_t section,
         intptr_t offset,
         intptr_t size)
      : cstr_(cstr),
        name_index_(name),
        info_(info),
        section_index_(section),
        offset_(offset),
        size_(size) {}

  void Write(Elf* stream) const {
    stream->WriteWord(name_index_);
#if defined(TARGET_ARCH_IS_32_BIT)
    stream->WriteAddr(offset_);
    stream->WriteWord(size_);
    stream->WriteByte(info_);
    stream->WriteByte(0);
    stream->WriteHalf(section_index_);
#else
    stream->WriteByte(info_);
    stream->WriteByte(0);
    stream->WriteHalf(section_index_);
    stream->WriteAddr(offset_);
    stream->WriteXWord(size_);
#endif
  }

 private:
  friend class SymbolHashTable;  // For cstr_ access.

  const char* cstr_;
  intptr_t name_index_;
  intptr_t info_;
  intptr_t section_index_;
  intptr_t offset_;
  intptr_t size_;
};

class SymbolTable : public Section {
 public:
  explicit SymbolTable(bool dynamic)
      : Section(dynamic ? elf::SHT_DYNSYM : elf::SHT_SYMTAB,
                dynamic,
                /*executable=*/false,
                /*writable=*/false,
                compiler::target::kWordSize),
        dynamic_(dynamic),
        reserved_("", 0, 0, 0, 0, 0) {
    section_entry_size = kElfSymbolTableEntrySize;
    // The first symbol table entry is reserved and must be all zeros.
    symbols_.Add(&reserved_);
    section_info = 1;  // One "local" symbol, the reserved first entry.
  }

  intptr_t FileSize() { return Length() * kElfSymbolTableEntrySize; }
  intptr_t MemorySize() { return dynamic_ ? FileSize() : 0; }

  void Write(Elf* stream) {
    for (intptr_t i = 0; i < Length(); i++) {
      auto const symbol = At(i);
      const intptr_t start = stream->position();
      symbol->Write(stream);
      const intptr_t end = stream->position();
      ASSERT((end - start) == kElfSymbolTableEntrySize);
    }
  }

  void AddSymbol(const Symbol* symbol) { symbols_.Add(symbol); }
  intptr_t Length() const { return symbols_.length(); }
  const Symbol* At(intptr_t i) const { return symbols_[i]; }

 private:
  const bool dynamic_;
  const Symbol reserved_;
  GrowableArray<const Symbol*> symbols_;
};

static uint32_t ElfHash(const unsigned char* name) {
  uint32_t h = 0;
  while (*name != '\0') {
    h = (h << 4) + *name++;
    uint32_t g = h & 0xf0000000;
    h ^= g;
    h ^= g >> 24;
  }
  return h;
}

class SymbolHashTable : public Section {
 public:
  SymbolHashTable(StringTable* strtab, SymbolTable* symtab)
      : Section(elf::SHT_HASH,
                /*allocate=*/true,
                /*executable=*/false,
                /*writable=*/false,
                compiler::target::kWordSize) {
    section_link = symtab->section_index();
    section_entry_size = kElfSymbolHashTableEntrySize;

    nchain_ = symtab->Length();
    nbucket_ = symtab->Length();

    auto zone = Thread::Current()->zone();
    bucket_ = zone->Alloc<int32_t>(nbucket_);
    for (intptr_t i = 0; i < nbucket_; i++) {
      bucket_[i] = elf::STN_UNDEF;
    }

    chain_ = zone->Alloc<int32_t>(nchain_);
    for (intptr_t i = 0; i < nchain_; i++) {
      chain_[i] = elf::STN_UNDEF;
    }

    for (intptr_t i = 1; i < symtab->Length(); i++) {
      auto const symbol = symtab->At(i);
      uint32_t hash = ElfHash((const unsigned char*)symbol->cstr_);
      uint32_t probe = hash % nbucket_;
      chain_[i] = bucket_[probe];  // next = head
      bucket_[probe] = i;          // head = symbol
    }
  }

  intptr_t FileSize() { return 4 * (nbucket_ + nchain_ + 2); }
  intptr_t MemorySize() { return FileSize(); }

  void Write(Elf* stream) {
    stream->WriteWord(nbucket_);
    stream->WriteWord(nchain_);
    for (intptr_t i = 0; i < nbucket_; i++) {
      stream->WriteWord(bucket_[i]);
    }
    for (intptr_t i = 0; i < nchain_; i++) {
      stream->WriteWord(chain_[i]);
    }
  }

 private:
  int32_t nbucket_;
  int32_t nchain_;
  int32_t* bucket_;  // "Head"
  int32_t* chain_;   // "Next"
};

class DynamicTable : public Section {
 public:
  DynamicTable(StringTable* strtab, SymbolTable* symtab, SymbolHashTable* hash)
      : Section(elf::SHT_DYNAMIC,
                /*allocate=*/true,
                /*executable=*/false,
                /*writable=*/true,
                compiler::target::kWordSize) {
    section_link = strtab->section_index();
    section_entry_size = kElfDynamicTableEntrySize;

    AddEntry(elf::DT_HASH, hash->memory_offset());
    AddEntry(elf::DT_STRTAB, strtab->memory_offset());
    AddEntry(elf::DT_STRSZ, strtab->MemorySize());
    AddEntry(elf::DT_SYMTAB, symtab->memory_offset());
    AddEntry(elf::DT_SYMENT, kElfSymbolTableEntrySize);
    AddEntry(elf::DT_NULL, 0);
  }

  intptr_t FileSize() { return entries_.length() * kElfDynamicTableEntrySize; }
  intptr_t MemorySize() { return FileSize(); }

  void Write(Elf* stream) {
    for (intptr_t i = 0; i < entries_.length(); i++) {
      const intptr_t start = stream->position();
#if defined(TARGET_ARCH_IS_32_BIT)
      stream->WriteWord(entries_[i]->tag);
      stream->WriteAddr(entries_[i]->value);
#else
      stream->WriteXWord(entries_[i]->tag);
      stream->WriteAddr(entries_[i]->value);
#endif
      const intptr_t end = stream->position();
      ASSERT((end - start) == kElfDynamicTableEntrySize);
    }
  }

  class Entry : public ZoneAllocated {
   public:
    intptr_t tag;
    intptr_t value;
  };

  void AddEntry(intptr_t tag, intptr_t value) {
    Entry* entry = new Entry();
    entry->tag = tag;
    entry->value = value;
    entries_.Add(entry);
  }

 private:
  GrowableArray<Entry*> entries_;
};

// The first section must be written out and contains only zeros.
static const intptr_t kNumInvalidSections = 1;

// Extra segments put in the program table that aren't reified in
// Elf::segments_.
static const intptr_t kNumImplicitSegments = 3;

static const intptr_t kProgramTableSegmentSize = Elf::kPageSize;

Elf::Elf(Zone* zone, StreamingWriteStream* stream)
    : zone_(zone),
      stream_(stream),
      shstrtab_(new (zone) StringTable(/*allocate=*/false)),
      dynstrtab_(new (zone) StringTable(/*allocate=*/true)),
      dynsym_(new (zone) SymbolTable(/*dynamic=*/true)),
      memory_offset_(kProgramTableSegmentSize) {
  // Assumed by various offset logic in this file.
  ASSERT(stream_->position() == 0);
}

void Elf::AddSection(Section* section, const char* name) {
  ASSERT(shstrtab_ != nullptr);
  section->set_section_name(shstrtab_->AddString(name));
  section->set_section_index(sections_.length() + kNumInvalidSections);
  sections_.Add(section);
  if (section->MemorySize() > 0) {
    memory_offset_ = Utils::RoundUp(memory_offset_, section->alignment);
    section->set_memory_offset(memory_offset_);
    segments_.Add(section);
    memory_offset_ += section->MemorySize();
    memory_offset_ = Utils::RoundUp(memory_offset_, kPageSize);
  }
}

intptr_t Elf::NextMemoryOffset() const {
  return memory_offset_;
}

intptr_t Elf::NextSectionIndex() const {
  return sections_.length() + kNumInvalidSections;
}

intptr_t Elf::AddSectionSymbol(const Section* section,
                               const char* name,
                               intptr_t size) {
  auto const name_index = dynstrtab_->AddString(name);
  auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
  auto const section_index = section->section_index();
  // For shared libraries, this is the offset from the DSO base. For static
  // libraries, this is section relative.
  auto const memory_offset = section->memory_offset();
  auto const symbol = new (zone_)
      Symbol(name, name_index, info, section_index, memory_offset, size);
  dynsym_->AddSymbol(symbol);

  return memory_offset;
}

intptr_t Elf::AddText(const char* name, const uint8_t* bytes, intptr_t size) {
  Section* image = nullptr;
  if (bytes != nullptr) {
    image = new (zone_) ProgramBits(true, true, false, bytes, size);
  } else {
    image = new (zone_) NoBits(true, true, false, size);
  }
  AddSection(image, ".text");

  return AddSectionSymbol(image, name, size);
}

void Elf::AddStaticSymbol(intptr_t section,
                          const char* name,
                          intptr_t address,
                          intptr_t size) {
  // Lazily allocate the static string and symbol tables, as we only add static
  // symbols in unstripped ELF files.
  if (strtab_ == nullptr) {
    ASSERT(symtab_ == nullptr);
    strtab_ = new (zone_) StringTable(/* allocate= */ false);
    symtab_ = new (zone_) SymbolTable(/*dynamic=*/false);
  }

  auto const name_index = strtab_->AddString(name);
  auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
  Symbol* symbol =
      new (zone_) Symbol(name, name_index, info, section, address, size);
  symtab_->AddSymbol(symbol);
}

intptr_t Elf::AddBSSData(const char* name, intptr_t size) {
  // Ideally the BSS segment would take no space in the object, but Android's
  // "strip" utility truncates the memory-size of our segments to their
  // file-size.
  //
  // Therefore we must insert zero-filled pages for the BSS.
  uint8_t* const bytes = zone_->Alloc<uint8_t>(size);
  memset(bytes, 0, size);

  ProgramBits* const image =
      new (zone_) ProgramBits(true, false, true, bytes, size);
  AddSection(image, ".bss");

  return AddSectionSymbol(image, name, size);
}

intptr_t Elf::AddROData(const char* name, const uint8_t* bytes, intptr_t size) {
  ASSERT(bytes != nullptr);
  ProgramBits* image = new (zone_) ProgramBits(true, false, false, bytes, size);
  AddSection(image, ".rodata");

  return AddSectionSymbol(image, name, size);
}

void Elf::AddDebug(const char* name, const uint8_t* bytes, intptr_t size) {
  ASSERT(bytes != nullptr);
  ProgramBits* image =
      new (zone_) ProgramBits(false, false, false, bytes, size);
  AddSection(image, name);
}

void Elf::Finalize() {
  AddSection(dynstrtab_, ".dynstr");
  AddSection(dynsym_, ".dynsym");
  dynsym_->section_link = dynstrtab_->section_index();

  auto const hash = new (zone_) SymbolHashTable(dynstrtab_, dynsym_);
  AddSection(hash, ".hash");

  if (symtab_ != nullptr) {
    ASSERT(strtab_ != nullptr);
    AddSection(strtab_, ".strtab");
    AddSection(symtab_, ".symtab");
    symtab_->section_link = strtab_->section_index();
  }

  dynamic_ = new (zone_) DynamicTable(dynstrtab_, dynsym_, hash);
  AddSection(dynamic_, ".dynamic");

  AddSection(shstrtab_, ".shstrtab");

  ComputeFileOffsets();

  WriteHeader();
  WriteProgramTable();
  WriteSections();
  WriteSectionTable();
}

void Elf::ComputeFileOffsets() {
  intptr_t file_offset = kElfHeaderSize;

  program_table_file_offset_ = file_offset;
  program_table_file_size_ =
      (segments_.length() + kNumImplicitSegments) * kElfProgramTableEntrySize;
  file_offset += program_table_file_size_;

  for (intptr_t i = 0; i < sections_.length(); i++) {
    Section* section = sections_[i];
    file_offset = Utils::RoundUp(file_offset, section->alignment);
    section->set_file_offset(file_offset);
    file_offset += section->FileSize();
  }

  file_offset = Utils::RoundUp(file_offset, kElfSectionTableAlignment);
  section_table_file_offset_ = file_offset;
  section_table_file_size_ =
      (sections_.length() + kNumInvalidSections) * kElfSectionTableEntrySize;
  file_offset += section_table_file_size_;
}

void Elf::WriteHeader() {
#if defined(TARGET_ARCH_IS_32_BIT)
  uint8_t size = elf::ELFCLASS32;
#else
  uint8_t size = elf::ELFCLASS64;
#endif
  uint8_t e_ident[16] = {0x7f,
                         'E',
                         'L',
                         'F',
                         size,
                         elf::ELFDATA2LSB,
                         elf::EV_CURRENT,
                         elf::ELFOSABI_SYSV,
                         0,
                         0,
                         0,
                         0,
                         0,
                         0,
                         0,
                         0};
  stream_->WriteBytes(e_ident, 16);

  WriteHalf(elf::ET_DYN);  // Shared library.

#if defined(TARGET_ARCH_IA32)
  WriteHalf(elf::EM_386);
#elif defined(TARGET_ARCH_X64)
  WriteHalf(elf::EM_X86_64);
#elif defined(TARGET_ARCH_ARM)
  WriteHalf(elf::EM_ARM);
#elif defined(TARGET_ARCH_ARM64)
  WriteHalf(elf::EM_AARCH64);
#else
  FATAL("Unknown ELF architecture");
#endif

  WriteWord(elf::EV_CURRENT);  // Version
  WriteAddr(0);                // "Entry point"
  WriteOff(program_table_file_offset_);
  WriteOff(section_table_file_offset_);

#if defined(TARGET_ARCH_ARM)
  uword flags = elf::EF_ARM_ABI | (TargetCPUFeatures::hardfp_supported()
                                       ? elf::EF_ARM_ABI_FLOAT_HARD
                                       : elf::EF_ARM_ABI_FLOAT_SOFT);
#else
  uword flags = 0;
#endif
  WriteWord(flags);

  WriteHalf(kElfHeaderSize);
  WriteHalf(kElfProgramTableEntrySize);
  WriteHalf(segments_.length() + kNumImplicitSegments);
  WriteHalf(kElfSectionTableEntrySize);
  WriteHalf(sections_.length() + kNumInvalidSections);
  WriteHalf(shstrtab_->section_index());

  ASSERT(stream_->position() == kElfHeaderSize);
}

void Elf::WriteProgramTable() {
  ASSERT(stream_->position() == program_table_file_offset_);

  // Self-reference to program header table. Required by Android but not by
  // Linux. Must appear before any PT_LOAD entries.
  {
    ProgramTable program_table(program_table_file_offset_,
                               program_table_file_size_);

    ASSERT(kNumImplicitSegments == 3);
    const intptr_t start = stream_->position();
    program_table.WriteSegmentEntry(this);
    const intptr_t end = stream_->position();
    ASSERT((end - start) == kElfProgramTableEntrySize);
  }
  // Load for self-reference to program header table. Required by Android but
  // not by Linux.
  {
    // We pre-allocated the virtual memory space for the program table itself.
    // Check that we didn't generate too many segments. Currently we generate a
    // fixed num of segments based on the four pieces of a snapshot, but if we
    // use more in the future we'll likely need to do something more compilated
    // to generate DWARF without knowing a piece's virtual address in advance.
    auto const program_table_segment_size =
        program_table_file_offset_ + program_table_file_size_;
    RELEASE_ASSERT(program_table_segment_size < kProgramTableSegmentSize);

    // We create a section that, when printed as a segment, contains the
    // appropriate info for the program table.
    ProgramTableLoad program_table_load(program_table_segment_size);

    ASSERT(kNumImplicitSegments == 3);
    const intptr_t start = stream_->position();
    program_table_load.WriteSegmentEntry(this);
    const intptr_t end = stream_->position();
    ASSERT((end - start) == kElfProgramTableEntrySize);
  }

  for (intptr_t i = 0; i < segments_.length(); i++) {
    Section* section = segments_[i];
    const intptr_t start = stream_->position();
    section->WriteSegmentEntry(this);
    const intptr_t end = stream_->position();
    ASSERT((end - start) == kElfProgramTableEntrySize);
  }

  // Special case: the dynamic section requires both LOAD and DYNAMIC program
  // header table entries.
  {
    ASSERT(kNumImplicitSegments == 3);
    const intptr_t start = stream_->position();
    dynamic_->WriteSegmentEntry(this, /*dynamic=*/true);
    const intptr_t end = stream_->position();
    ASSERT((end - start) == kElfProgramTableEntrySize);
  }
}

void Elf::WriteSectionTable() {
  stream_->Align(kElfSectionTableAlignment);

  ASSERT(stream_->position() == section_table_file_offset_);

  {
    // The first entry in the section table is reserved and must be all zeros.
    ASSERT(kNumInvalidSections == 1);
    const intptr_t start = stream_->position();
    ReservedSection reserved;
    reserved.WriteSectionEntry(this);
    const intptr_t end = stream_->position();
    ASSERT((end - start) == kElfSectionTableEntrySize);
  }

  for (intptr_t i = 0; i < sections_.length(); i++) {
    Section* section = sections_[i];
    const intptr_t start = stream_->position();
    section->WriteSectionEntry(this);
    const intptr_t end = stream_->position();
    ASSERT((end - start) == kElfSectionTableEntrySize);
  }
}

void Elf::WriteSections() {
  for (intptr_t i = 0; i < sections_.length(); i++) {
    Section* section = sections_[i];
    stream_->Align(section->alignment);
    ASSERT(stream_->position() == section->file_offset());
    section->Write(this);
    ASSERT(stream_->position() == section->file_offset() + section->FileSize());
  }
}

}  // namespace dart
