// 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/dwarf.h"
#include "vm/hash_map.h"
#include "vm/image_snapshot.h"
#include "vm/stack_frame.h"
#include "vm/thread.h"
#include "vm/zone_text_buffer.h"

namespace dart {

#if defined(DART_PRECOMPILER)

// A wrapper around BaseWriteStream that provides methods useful for
// writing ELF files (e.g., using ELF definitions of data sizes).
class ElfWriteStream : public ValueObject {
 public:
  explicit ElfWriteStream(BaseWriteStream* stream, const Elf& elf)
      : stream_(ASSERT_NOTNULL(stream)),
        elf_(elf),
        start_(stream_->Position()) {
    // So that we can use the underlying stream's Align, as all alignments
    // will be less than or equal to this alignment.
    ASSERT(Utils::IsAligned(start_, Elf::kPageSize));
  }

  // Subclasses of Section may need to query the Elf object during Write(),
  // so we store it in the ElfWriteStream for easy access.
  const Elf& elf() const { return elf_; }

  // We return positions in terms of the ELF content that has been written,
  // ignoring any previous content on the stream.
  intptr_t Position() const { return stream_->Position() - start_; }
  void Align(const intptr_t alignment) {
    ASSERT(Utils::IsPowerOfTwo(alignment));
    ASSERT(alignment <= Elf::kPageSize);
    stream_->Align(alignment);
  }
  void WriteBytes(const uint8_t* b, intptr_t size) {
    stream_->WriteBytes(b, size);
  }
  void WriteByte(uint8_t value) { stream_->WriteByte(value); }
  void WriteHalf(uint16_t value) { stream_->WriteFixed(value); }
  void WriteWord(uint32_t value) { stream_->WriteFixed(value); }
  void WriteAddr(compiler::target::uword value) { stream_->WriteFixed(value); }
  void WriteOff(compiler::target::uword value) { stream_->WriteFixed(value); }
#if defined(TARGET_ARCH_IS_64_BIT)
  void WriteXWord(uint64_t value) { stream_->WriteFixed(value); }
#endif

 private:
  BaseWriteStream* const stream_;
  const Elf& elf_;
  const intptr_t start_;
};

static constexpr intptr_t kLinearInitValue = -1;

#define DEFINE_LINEAR_FIELD_METHODS(name)                                      \
  intptr_t name() const {                                                      \
    ASSERT(name##_ != kLinearInitValue);                                       \
    return name##_;                                                            \
  }                                                                            \
  bool name##_is_set() const { return name##_ != kLinearInitValue; }           \
  void set_##name(intptr_t value) {                                            \
    ASSERT(value != kLinearInitValue);                                         \
    ASSERT_EQUAL(name##_, kLinearInitValue);                                   \
    name##_ = value;                                                           \
  }

#define DEFINE_LINEAR_FIELD(name) intptr_t name##_ = kLinearInitValue;

// We only allow for dynamic casting to a subset of section types, since
// these are the only ones we need to distinguish at runtime.
#define FOR_EACH_SECTION_TYPE(V)                                               \
  V(ReservedSection)                                                           \
  V(SymbolTable)                                                               \
  V(DynamicTable)                                                              \
  V(BitsContainer)                                                             \
  V(TextSection) V(DataSection) V(BssSection) V(PseudoSection) V(SectionTable)
#define DEFINE_TYPE_CHECK_FOR(Type)                                            \
  bool Is##Type() const { return true; }

#define DECLARE_SECTION_TYPE_CLASS(Type) class Type;
FOR_EACH_SECTION_TYPE(DECLARE_SECTION_TYPE_CLASS)
#undef DECLARE_SECTION_TYPE_CLASS

class BitsContainer;
class Segment;

// Align note sections and segments to 4 byte boundries.
static constexpr intptr_t kNoteAlignment = 4;

class Section : public ZoneAllocated {
 public:
  Section(elf::SectionHeaderType t,
          bool allocate,
          bool executable,
          bool writable,
          intptr_t align = compiler::target::kWordSize)
      : type(t),
        flags(EncodeFlags(allocate, executable, writable)),
        alignment(align),
        // Non-segments will never have a memory offset, here represented by 0.
        memory_offset_(allocate ? kLinearInitValue : 0) {
    // Only SHT_NULL sections (namely, the reserved section) are allowed to have
    // an alignment of 0 (as the written section header entry for the reserved
    // section must be all 0s).
    ASSERT(alignment > 0 || type == elf::SectionHeaderType::SHT_NULL);
    // Non-zero alignments must be a power of 2.
    ASSERT(alignment == 0 || Utils::IsPowerOfTwo(alignment));
  }

  virtual ~Section() {}

  // Linker view.

  const elf::SectionHeaderType type;
  const intptr_t 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 link = elf::SHN_UNDEF;
  intptr_t info = 0;
  intptr_t entry_size = 0;
  // This field is set for all sections, but due to reordering, we may set it
  // more than once.
  intptr_t index = elf::SHN_UNDEF;

#define FOR_EACH_SECTION_LINEAR_FIELD(M)                                       \
  M(name)                                                                      \
  M(file_offset)

  FOR_EACH_SECTION_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);

  // Only needs to be overridden for sections that may not be allocated or
  // for allocated sections where MemorySize() and FileSize() may differ.
  virtual intptr_t FileSize() const {
    if (!IsAllocated()) {
      UNREACHABLE();
    }
    return MemorySize();
  }

  // Loader view.

#define FOR_EACH_SEGMENT_LINEAR_FIELD(M) M(memory_offset)

  FOR_EACH_SEGMENT_LINEAR_FIELD(DEFINE_LINEAR_FIELD_METHODS);

  // Only needs to be overridden for sections that may be allocated.
  virtual intptr_t MemorySize() const {
    if (IsAllocated()) {
      UNREACHABLE();
    }
    return 0;
  }

  // Other methods.

  bool IsAllocated() const {
    return (flags & elf::SHF_ALLOC) == elf::SHF_ALLOC;
  }
  bool IsExecutable() const {
    return (flags & elf::SHF_EXECINSTR) == elf::SHF_EXECINSTR;
  }
  bool IsWritable() const { return (flags & elf::SHF_WRITE) == elf::SHF_WRITE; }

  bool HasBits() const { return type != elf::SectionHeaderType::SHT_NOBITS; }

  // Returns whether the size of a section can change.
  bool HasBeenFinalized() const {
    // Sections can grow or shrink up until Elf::ComputeOffsets has been run,
    // which sets the file (and memory, if applicable) offsets.
    return file_offset_is_set();
  }

#define DEFINE_BASE_TYPE_CHECKS(Type)                                          \
  Type* As##Type() {                                                           \
    return Is##Type() ? reinterpret_cast<Type*>(this) : nullptr;               \
  }                                                                            \
  const Type* As##Type() const {                                               \
    return const_cast<Type*>(const_cast<Section*>(this)->As##Type());          \
  }                                                                            \
  virtual bool Is##Type() const { return false; }

  FOR_EACH_SECTION_TYPE(DEFINE_BASE_TYPE_CHECKS)
#undef DEFINE_BASE_TYPE_CHECKS

  // Only some sections support merging.
  virtual bool CanMergeWith(const Section& other) const { return false; }
  virtual void Merge(const Section& other) { UNREACHABLE(); }

  // Writes the file contents of the section.
  virtual void Write(ElfWriteStream* stream) const { UNREACHABLE(); }

  virtual void WriteSectionHeader(ElfWriteStream* stream) const {
#if defined(TARGET_ARCH_IS_32_BIT)
    stream->WriteWord(name());
    stream->WriteWord(static_cast<uint32_t>(type));
    stream->WriteWord(flags);
    stream->WriteAddr(memory_offset());
    stream->WriteOff(file_offset());
    stream->WriteWord(FileSize());
    stream->WriteWord(link);
    stream->WriteWord(info);
    stream->WriteWord(alignment);
    stream->WriteWord(entry_size);
#else
    stream->WriteWord(name());
    stream->WriteWord(static_cast<uint32_t>(type));
    stream->WriteXWord(flags);
    stream->WriteAddr(memory_offset());
    stream->WriteOff(file_offset());
    stream->WriteXWord(FileSize());
    stream->WriteWord(link);
    stream->WriteWord(info);
    stream->WriteXWord(alignment);
    stream->WriteXWord(entry_size);
#endif
  }

 private:
  static intptr_t EncodeFlags(bool allocate, bool executable, bool writable) {
    // Executable and writable only make sense if this is an allocated section.
    ASSERT(allocate || (!executable && !writable));
    if (!allocate) return 0;
    intptr_t flags = elf::SHF_ALLOC;
    // We currently don't allow sections that are both executable and writable.
    ASSERT(!executable || !writable);
    if (executable) flags |= elf::SHF_EXECINSTR;
    if (writable) flags |= elf::SHF_WRITE;
    return flags;
  }

  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

class Segment : public ZoneAllocated {
 public:
  Segment(Zone* zone,
          Section* initial_section,
          elf::ProgramHeaderType segment_type)
      : type(segment_type),
        // Flags for the segment are the same as the initial section.
        flags(EncodeFlags(ASSERT_NOTNULL(initial_section)->IsExecutable(),
                          ASSERT_NOTNULL(initial_section)->IsWritable())),
        sections_(zone, 0) {
    // Unlike sections, we don't have a reserved segment with the null type,
    // so we never should pass this value.
    ASSERT(segment_type != elf::ProgramHeaderType::PT_NULL);
    // All segments should have at least one section.
    ASSERT(initial_section != nullptr);
    ASSERT(initial_section->IsAllocated());
    sections_.Add(initial_section);
  }

  virtual ~Segment() {}

  const GrowableArray<Section*>& sections() const { return sections_; }

  intptr_t Alignment() const {
    switch (type) {
      case elf::ProgramHeaderType::PT_LOAD:
        return Elf::kPageSize;
      case elf::ProgramHeaderType::PT_PHDR:
      case elf::ProgramHeaderType::PT_DYNAMIC:
        return compiler::target::kWordSize;
      case elf::ProgramHeaderType::PT_NOTE:
        return kNoteAlignment;
      default:
        UNREACHABLE();
        return 0;
    }
  }

  bool IsExecutable() const { return (flags & elf::PF_X) == elf::PF_X; }
  bool IsWritable() const { return (flags & elf::PF_W) == elf::PF_W; }

  void WriteProgramHeader(ElfWriteStream* stream) const {
#if defined(TARGET_ARCH_IS_32_BIT)
    stream->WriteWord(static_cast<uint32_t>(type));
    stream->WriteOff(FileOffset());
    stream->WriteAddr(MemoryOffset());  // Virtual address.
    stream->WriteAddr(MemoryOffset());  // Physical address.
    stream->WriteWord(FileSize());
    stream->WriteWord(MemorySize());
    stream->WriteWord(flags);
    stream->WriteWord(Alignment());
#else
    stream->WriteWord(static_cast<uint32_t>(type));
    stream->WriteWord(flags);
    stream->WriteOff(FileOffset());
    stream->WriteAddr(MemoryOffset());  // Virtual address.
    stream->WriteAddr(MemoryOffset());  // Physical address.
    stream->WriteXWord(FileSize());
    stream->WriteXWord(MemorySize());
    stream->WriteXWord(Alignment());
#endif
  }

  // Adds a given section to the end of this segment. Returns whether the
  // section was successfully added.
  bool Add(Section* section) {
    ASSERT(section != nullptr);
    // We can't add if memory offsets have already been calculated.
    ASSERT(!section->memory_offset_is_set());
    // We only add additional sections to load segments.
    ASSERT(type == elf::ProgramHeaderType::PT_LOAD);
    // We only add sections with the same executable and writable bits.
    if (IsExecutable() != section->IsExecutable() ||
        IsWritable() != section->IsWritable()) {
      return false;
    }
    sections_.Add(section);
    return true;
  }

  intptr_t FileOffset() const { return sections_[0]->file_offset(); }

  intptr_t FileSize() const {
    auto const last = sections_.Last();
    const intptr_t end = last->file_offset() + last->FileSize();
    return end - FileOffset();
  }

  intptr_t MemoryOffset() const { return sections_[0]->memory_offset(); }

  intptr_t MemorySize() const {
    auto const last = sections_.Last();
    const intptr_t end = last->memory_offset() + last->MemorySize();
    return end - MemoryOffset();
  }

  intptr_t MemoryEnd() const { return MemoryOffset() + MemorySize(); }

  const elf::ProgramHeaderType type;
  const intptr_t flags;

 private:
  static intptr_t EncodeFlags(bool executable, bool writable) {
    intptr_t flags = elf::PF_R;
    if (executable) flags |= elf::PF_X;
    if (writable) flags |= elf::PF_W;
    return flags;
  }

  GrowableArray<Section*> sections_;
};

// Represents the first entry in the section table, which should only contain
// zero values and does not correspond to a memory segment.
class ReservedSection : public Section {
 public:
  ReservedSection()
      : Section(elf::SectionHeaderType::SHT_NULL,
                /*allocate=*/false,
                /*executable=*/false,
                /*writable=*/false,
                /*alignment=*/0) {
    set_file_offset(0);
  }

  DEFINE_TYPE_CHECK_FOR(ReservedSection);
  intptr_t FileSize() const { return 0; }
};

class StringTable : public Section {
 public:
  explicit StringTable(Zone* zone, bool allocate)
      : Section(elf::SectionHeaderType::SHT_STRTAB,
                allocate,
                /*executable=*/false,
                /*writable=*/false),
        dynamic_(allocate),
        text_(zone, 128),
        text_indices_(zone) {
    Add("");
  }

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

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

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

  const char* At(intptr_t index) const {
    if (index >= text_.length()) return nullptr;
    return text_.buffer() + index;
  }

  static const intptr_t kNotIndexed = CStringIntMapKeyValueTrait::kNoValue;

  // Returns the index of |str| if it is present in the string table
  // and |kNotIndexed| otherwise.
  intptr_t Lookup(const char* str) const {
    return text_indices_.LookupValue(str);
  }

  const bool dynamic_;
  ZoneTextBuffer text_;
  CStringIntMap text_indices_;
};

class SymbolTable : public Section {
 public:
  SymbolTable(Zone* zone, StringTable* table, bool dynamic)
      : Section(dynamic ? elf::SectionHeaderType::SHT_DYNSYM
                        : elf::SectionHeaderType::SHT_SYMTAB,
                dynamic,
                /*executable=*/false,
                /*writable=*/false),
        zone_(zone),
        table_(table),
        dynamic_(dynamic),
        symbols_(zone, 1),
        by_name_index_(zone) {
    link = table_->index;
    entry_size = sizeof(elf::Symbol);
    // The first symbol table entry is reserved and must be all zeros.
    // (String tables always have the empty string at the 0th index.)
    ASSERT_EQUAL(table_->Lookup(""), 0);
    symbols_.Add({/*name_index=*/0, elf::STB_LOCAL, elf::STT_NOTYPE, /*size=*/0,
                  elf::SHN_UNDEF, /*offset=*/0});
    // The info field on a symbol table section holds the index of the first
    // non-local symbol, so since there are none yet, it points past the single
    // symbol we do have.
    info = 1;
  }

  DEFINE_TYPE_CHECK_FOR(SymbolTable)
  const StringTable& strtab() const { return *table_; }
  intptr_t FileSize() const { return symbols_.length() * entry_size; }
  intptr_t MemorySize() const { return dynamic_ ? FileSize() : 0; }

  struct Symbol {
    void Write(ElfWriteStream* stream) const {
      const intptr_t start = stream->Position();
      ASSERT(section_index == elf::SHN_UNDEF || offset > 0);
      stream->WriteWord(name_index);
#if defined(TARGET_ARCH_IS_32_BIT)
      stream->WriteAddr(offset);
      stream->WriteWord(size);
      stream->WriteByte(elf::SymbolInfo(binding, type));
      stream->WriteByte(0);
      stream->WriteHalf(section_index);
#else
      stream->WriteByte(elf::SymbolInfo(binding, type));
      stream->WriteByte(0);
      stream->WriteHalf(section_index);
      stream->WriteAddr(offset);
      stream->WriteXWord(size);
#endif
      ASSERT_EQUAL(stream->Position() - start, sizeof(elf::Symbol));
    }

    intptr_t name_index;
    intptr_t binding;
    intptr_t type;
    intptr_t size;
    // Must be updated whenever sections are reordered.
    intptr_t section_index;
    // Initialized to the section-relative offset, must be updated to the
    // snapshot-relative offset before writing.
    intptr_t offset;

   private:
    DISALLOW_ALLOCATION();
  };

  const GrowableArray<Symbol>& symbols() const { return symbols_; }

  void Initialize(const GrowableArray<Section*>& sections);

  void Write(ElfWriteStream* stream) const {
    for (const auto& symbol : symbols_) {
      const intptr_t start = stream->Position();
      symbol.Write(stream);
      ASSERT_EQUAL(stream->Position() - start, entry_size);
    }
  }

  void AddSymbol(const char* name,
                 intptr_t binding,
                 intptr_t type,
                 intptr_t size,
                 intptr_t index,
                 intptr_t offset) {
    ASSERT(!table_->HasBeenFinalized());
    auto const name_index = table_->Add(name);
    ASSERT(name_index != 0);
    const intptr_t new_index = symbols_.length();
    symbols_.Add({name_index, binding, type, size, index, offset});
    by_name_index_.Insert(name_index, new_index);
    // The info field on a symbol table section holds the index of the first
    // non-local symbol, so they can be skipped if desired. Thus, we need to
    // make sure local symbols are before any non-local ones.
    if (binding == elf::STB_LOCAL) {
      if (info != new_index) {
        // There are non-local symbols, as otherwise [info] would be the
        // index of the new symbol. Since the order doesn't otherwise matter,
        // swap the new local symbol with the value at index [info], so when
        // [info] is incremented it will point just past the new local symbol.
        ASSERT(symbols_[info].binding != elf::STB_LOCAL);
        symbols_.Swap(info, new_index);
        // Since by_name_index has indices into symbols_, we need to update it.
        by_name_index_.Update({symbols_[info].name_index, info});
        by_name_index_.Update({symbols_[new_index].name_index, new_index});
      }
      info += 1;
    }
  }

  void UpdateSectionIndices(const GrowableArray<intptr_t>& index_map) {
#if defined(DEBUG)
    const intptr_t map_size = index_map.length();
    // The first entry must be 0 so that symbols with index SHN_UNDEF, like
    // the initial reserved symbol, are unchanged.
    ASSERT_EQUAL(index_map[0], 0);
    for (intptr_t i = 1; i < map_size; i++) {
      ASSERT(index_map[i] != 0);
      ASSERT(index_map[i] < map_size);
    }
#endif
    for (auto& symbol : symbols_) {
      DEBUG_ASSERT(symbol.section_index < map_size);
      symbol.section_index = index_map[symbol.section_index];
    }
  }

  void Finalize(const GrowableArray<intptr_t>& address_map) {
#if defined(DEBUG)
    const intptr_t map_size = address_map.length();
    // The first entry must be 0 so that symbols with index SHN_UNDEF, like
    // the initial reserved symbol, are unchanged.
    ASSERT_EQUAL(address_map[0], 0);
    for (intptr_t i = 1; i < map_size; i++) {
      // No section begins at the start of the snapshot.
      ASSERT(address_map[i] != 0);
    }
#endif
    for (auto& symbol : symbols_) {
      DEBUG_ASSERT(symbol.section_index < map_size);
      symbol.offset += address_map[symbol.section_index];
    }
  }

  const Symbol* Find(const char* name) const {
    ASSERT(name != nullptr);
    const intptr_t name_index = table_->Lookup(name);
    // 0 is kNoValue for by_name_index, but luckily that's the name of the
    // initial reserved symbol.
    if (name_index == 0) return &symbols_[0];
    const intptr_t symbols_index = by_name_index_.Lookup(name_index);
    if (symbols_index == 0) return nullptr;  // Not found.
    return &symbols_[symbols_index];
  }

 private:
  Zone* const zone_;
  StringTable* const table_;
  const bool dynamic_;
  GrowableArray<Symbol> symbols_;
  // Maps name indexes in table_ to indexes in symbols_. Does not include an
  // entry for the reserved symbol (name ""), as 0 is kNoValue.
  IntMap<intptr_t> by_name_index_;
};

class SymbolHashTable : public Section {
 public:
  SymbolHashTable(Zone* zone, SymbolTable* symtab)
      : Section(elf::SectionHeaderType::SHT_HASH,
                /*allocate=*/true,
                /*executable=*/false,
                /*writable=*/false),
        buckets_(zone, 0),
        chains_(zone, 0) {
    link = symtab->index;
    entry_size = sizeof(int32_t);

    const auto& symbols = symtab->symbols();
    const intptr_t num_symbols = symbols.length();
    buckets_.FillWith(elf::STN_UNDEF, 0, num_symbols);
    chains_.FillWith(elf::STN_UNDEF, 0, num_symbols);

    for (intptr_t i = 1; i < num_symbols; i++) {
      const auto& symbol = symbols[i];
      uint32_t hash = HashSymbolName(symtab->strtab().At(symbol.name_index));
      uint32_t probe = hash % num_symbols;
      chains_[i] = buckets_[probe];  // next = head
      buckets_[probe] = i;           // head = symbol
    }
  }

  intptr_t MemorySize() const {
    return entry_size * (buckets_.length() + chains_.length() + 2);
  }

  void Write(ElfWriteStream* stream) const {
    stream->WriteWord(buckets_.length());
    stream->WriteWord(chains_.length());
    for (const int32_t bucket : buckets_) {
      stream->WriteWord(bucket);
    }
    for (const int32_t chain : chains_) {
      stream->WriteWord(chain);
    }
  }

  static uint32_t HashSymbolName(const void* p) {
    auto* name = reinterpret_cast<const uint8_t*>(p);
    uint32_t h = 0;
    while (*name != '\0') {
      h = (h << 4) + *name++;
      uint32_t g = h & 0xf0000000;
      h ^= g;
      h ^= g >> 24;
    }
    return h;
  }

 private:
  GrowableArray<int32_t> buckets_;  // "Head"
  GrowableArray<int32_t> chains_;   // "Next"
};

class DynamicTable : public Section {
 public:
  // .dynamic section is expected to be writable on most Linux systems
  // unless dynamic linker is explicitly built with support for an read-only
  // .dynamic section (DL_RO_DYN_SECTION).
  DynamicTable(Zone* zone, SymbolTable* symtab, SymbolHashTable* hash)
      : Section(elf::SectionHeaderType::SHT_DYNAMIC,
                /*allocate=*/true,
                /*executable=*/false,
                /*writable=*/true),
        symtab_(symtab),
        hash_(hash) {
    link = strtab().index;
    entry_size = sizeof(elf::DynamicEntry);

    AddEntry(zone, elf::DynamicEntryType::DT_HASH, kInvalidEntry);
    AddEntry(zone, elf::DynamicEntryType::DT_STRTAB, kInvalidEntry);
    AddEntry(zone, elf::DynamicEntryType::DT_STRSZ, kInvalidEntry);
    AddEntry(zone, elf::DynamicEntryType::DT_SYMTAB, kInvalidEntry);
    AddEntry(zone, elf::DynamicEntryType::DT_SYMENT, sizeof(elf::Symbol));
    AddEntry(zone, elf::DynamicEntryType::DT_NULL, 0);
  }

  static constexpr intptr_t kInvalidEntry = -1;

  DEFINE_TYPE_CHECK_FOR(DynamicTable)
  const SymbolHashTable& hash() const { return *hash_; }
  const SymbolTable& symtab() const { return *symtab_; }
  const StringTable& strtab() const { return symtab().strtab(); }
  intptr_t MemorySize() const { return entries_.length() * entry_size; }

  void Write(ElfWriteStream* stream) const {
    for (intptr_t i = 0; i < entries_.length(); i++) {
      entries_[i]->Write(stream);
    }
  }

  void Finalize() {
    FinalizeEntry(elf::DynamicEntryType::DT_HASH, hash().memory_offset());
    FinalizeEntry(elf::DynamicEntryType::DT_STRTAB, strtab().memory_offset());
    FinalizeEntry(elf::DynamicEntryType::DT_STRSZ, strtab().MemorySize());
    FinalizeEntry(elf::DynamicEntryType::DT_SYMTAB, symtab().memory_offset());
  }

 private:
  struct Entry : public ZoneAllocated {
    Entry(elf::DynamicEntryType tag, intptr_t value) : tag(tag), value(value) {}

    void Write(ElfWriteStream* stream) const {
      ASSERT(value != kInvalidEntry);
      const intptr_t start = stream->Position();
#if defined(TARGET_ARCH_IS_32_BIT)
      stream->WriteWord(static_cast<uint32_t>(tag));
      stream->WriteAddr(value);
#else
      stream->WriteXWord(static_cast<uint64_t>(tag));
      stream->WriteAddr(value);
#endif
      ASSERT_EQUAL(stream->Position() - start, sizeof(elf::DynamicEntry));
    }

    elf::DynamicEntryType tag;
    intptr_t value;
  };

  void AddEntry(Zone* zone, elf::DynamicEntryType tag, intptr_t value) {
    auto const entry = new (zone) Entry(tag, value);
    entries_.Add(entry);
  }

  void FinalizeEntry(elf::DynamicEntryType tag, intptr_t value) {
    for (auto* entry : entries_) {
      if (entry->tag == tag) {
        entry->value = value;
        break;
      }
    }
  }

  SymbolTable* const symtab_;
  SymbolHashTable* const hash_;
  GrowableArray<Entry*> entries_;
};

class BitsContainer : public Section {
 public:
  // Fully specified BitsContainer information. Unless otherwise specified,
  // BitContainers are aligned on byte boundaries (i.e., no padding is used).
  BitsContainer(elf::SectionHeaderType type,
                bool allocate,
                bool executable,
                bool writable,
                int alignment = 1)
      : Section(type, allocate, executable, writable, alignment) {}

  // For BitsContainers used only as unallocated sections.
  explicit BitsContainer(elf::SectionHeaderType type, intptr_t alignment = 1)
      : BitsContainer(type,
                      /*allocate=*/false,
                      /*executable=*/false,
                      /*writable=*/false,
                      alignment) {}

  // For BitsContainers used as segments whose type differ on the type of the
  // ELF file. Creates an elf::SHT_PROGBITS section if type is Snapshot,
  // otherwise creates an elf::SHT_NOBITS section.
  BitsContainer(Elf::Type t,
                bool executable,
                bool writable,
                intptr_t alignment = 1)
      : BitsContainer(t == Elf::Type::Snapshot
                          ? elf::SectionHeaderType::SHT_PROGBITS
                          : elf::SectionHeaderType::SHT_NOBITS,
                      /*allocate=*/true,
                      executable,
                      writable,
                      alignment) {}

  DEFINE_TYPE_CHECK_FOR(BitsContainer)

  bool IsNoBits() const { return type == elf::SectionHeaderType::SHT_NOBITS; }
  bool HasBytes() const {
    return portions_.length() != 0 && portions_[0].bytes != nullptr;
  }

  struct Portion {
    void Write(ElfWriteStream* stream, intptr_t section_start) const {
      ASSERT(bytes != nullptr);
      if (relocations == nullptr) {
        stream->WriteBytes(bytes, size);
        return;
      }
      const SymbolTable& symtab = stream->elf().symtab();
      // Resolve relocations as we write.
      intptr_t current_pos = 0;
      for (const auto& reloc : *relocations) {
        // We assume here that the relocations are sorted in increasing order,
        // with unique section offsets.
        ASSERT(current_pos <= reloc.section_offset);
        if (current_pos < reloc.section_offset) {
          stream->WriteBytes(bytes + current_pos,
                             reloc.section_offset - current_pos);
        }
        intptr_t source_address = reloc.source_offset;
        if (reloc.source_symbol != nullptr) {
          auto* const source_symbol = symtab.Find(reloc.source_symbol);
          ASSERT(source_symbol != nullptr);
          source_address += source_symbol->offset;
        } else {
          source_address += section_start + offset + reloc.section_offset;
        }
        ASSERT(reloc.size_in_bytes <= kWordSize);
        word to_write = reloc.target_offset - source_address;
        if (reloc.target_symbol != nullptr) {
          if (auto* const symbol = symtab.Find(reloc.target_symbol)) {
            to_write += symbol->offset;
          } else {
            ASSERT_EQUAL(strcmp(reloc.target_symbol, kSnapshotBuildIdAsmSymbol),
                         0);
            ASSERT_EQUAL(reloc.target_offset, 0);
            ASSERT_EQUAL(reloc.source_offset, 0);
            ASSERT_EQUAL(reloc.size_in_bytes, compiler::target::kWordSize);
            // TODO(dartbug.com/43516): Special case for snapshots with deferred
            // sections that handles the build ID relocation in an
            // InstructionsSection when there is no build ID.
            to_write = Image::kNoRelocatedAddress;
          }
        } else {
          to_write += section_start + offset + reloc.section_offset;
        }
        ASSERT(Utils::IsInt(reloc.size_in_bytes * kBitsPerByte, to_write));
        stream->WriteBytes(reinterpret_cast<const uint8_t*>(&to_write),
                           reloc.size_in_bytes);
        current_pos = reloc.section_offset + reloc.size_in_bytes;
      }
      stream->WriteBytes(bytes + current_pos, size - current_pos);
    }

    intptr_t offset;
    const char* symbol_name;
    const uint8_t* bytes;
    intptr_t size;
    const ZoneGrowableArray<Elf::Relocation>* relocations;
    const ZoneGrowableArray<Elf::SymbolData>* symbols;

   private:
    DISALLOW_ALLOCATION();
  };

  const GrowableArray<Portion>& portions() const { return portions_; }

  const Portion& AddPortion(
      const uint8_t* bytes,
      intptr_t size,
      const ZoneGrowableArray<Elf::Relocation>* relocations = nullptr,
      const ZoneGrowableArray<Elf::SymbolData>* symbols = nullptr,
      const char* symbol_name = nullptr) {
    ASSERT(IsNoBits() || bytes != nullptr);
    ASSERT(bytes != nullptr || relocations == nullptr);
    // Make sure all portions are consistent in containing bytes.
    ASSERT(portions_.is_empty() || HasBytes() == (bytes != nullptr));
    const intptr_t offset = Utils::RoundUp(total_size_, alignment);
    portions_.Add({offset, symbol_name, bytes, size, relocations, symbols});
    const Portion& portion = portions_.Last();
    total_size_ = offset + size;
    return portion;
  }

  void Write(ElfWriteStream* stream) const {
    if (type == elf::SectionHeaderType::SHT_NOBITS) return;
    intptr_t start_position = stream->Position();  // Used for checks.
    for (const auto& portion : portions_) {
      stream->Align(alignment);
      ASSERT_EQUAL(stream->Position(), start_position + portion.offset);
      portion.Write(stream, memory_offset());
    }
    ASSERT_EQUAL(stream->Position(), start_position + total_size_);
  }

  // Returns the hash for the portion corresponding to symbol_name.
  // Returns 0 if the portion has no bytes or no portions have that name.
  uint32_t Hash(const char* symbol_name) const {
    for (const auto& portion : portions_) {
      if (strcmp(symbol_name, portion.symbol_name) == 0) {
        if (portion.bytes == nullptr) return 0;
        const uint32_t hash = Utils::StringHash(portion.bytes, portion.size);
        // Ensure a non-zero return.
        return hash == 0 ? 1 : hash;
      }
    }
    return 0;
  }

  intptr_t FileSize() const { return IsNoBits() ? 0 : total_size_; }
  intptr_t MemorySize() const { return IsAllocated() ? total_size_ : 0; }

 private:
  GrowableArray<Portion> portions_;
  intptr_t total_size_ = 0;
};

class NoteSection : public BitsContainer {
 public:
  NoteSection()
      : BitsContainer(elf::SectionHeaderType::SHT_NOTE,
                      /*allocate=*/true,
                      /*executable=*/false,
                      /*writable=*/false,
                      kNoteAlignment) {}
};

// Abstract bits container that allows merging by just appending the portion
// information (with properly adjusted offsets) of the other to this one.
class ConcatenableBitsContainer : public BitsContainer {
 public:
  ConcatenableBitsContainer(Elf::Type type,
                            bool executable,
                            bool writable,
                            intptr_t alignment)
      : BitsContainer(type, executable, writable, alignment) {}

  virtual bool CanMergeWith(const Section& other) const = 0;
  virtual void Merge(const Section& other) {
    ASSERT(other.IsBitsContainer());
    ASSERT(CanMergeWith(other));
    for (const auto& portion : other.AsBitsContainer()->portions()) {
      AddPortion(portion.bytes, portion.size, portion.relocations,
                 portion.symbols, portion.symbol_name);
    }
  }
};

class TextSection : public ConcatenableBitsContainer {
 public:
  explicit TextSection(Elf::Type t)
      : ConcatenableBitsContainer(t,
                                  /*executable=*/true,
                                  /*writable=*/false,
                                  ImageWriter::kTextAlignment) {}

  DEFINE_TYPE_CHECK_FOR(TextSection);

  virtual bool CanMergeWith(const Section& other) const {
    return other.IsTextSection();
  }
};

class DataSection : public ConcatenableBitsContainer {
 public:
  explicit DataSection(Elf::Type t)
      : ConcatenableBitsContainer(t,
                                  /*executable=*/false,
                                  /*writable=*/false,
                                  ImageWriter::kRODataAlignment) {}

  DEFINE_TYPE_CHECK_FOR(DataSection);

  virtual bool CanMergeWith(const Section& other) const {
    return other.IsDataSection();
  }
};

class BssSection : public ConcatenableBitsContainer {
 public:
  explicit BssSection(Elf::Type t)
      : ConcatenableBitsContainer(t,
                                  /*executable=*/false,
                                  /*writable=*/true,
                                  ImageWriter::kBssAlignment) {}

  DEFINE_TYPE_CHECK_FOR(BssSection);

  virtual bool CanMergeWith(const Section& other) const {
    return other.IsBssSection();
  }
};

// Represents portions of the file/memory space which do not correspond to
// sections from the section header. Should never be added to the section table,
// but may be added to segments.
class PseudoSection : public Section {
 public:
  // All PseudoSections are aligned to target word size.
  static const intptr_t kAlignment = compiler::target::kWordSize;

  PseudoSection(bool allocate, bool executable, bool writable)
      : Section(elf::SectionHeaderType::SHT_NULL,
                allocate,
                executable,
                writable,
                kAlignment) {}

  DEFINE_TYPE_CHECK_FOR(PseudoSection)

  void Write(ElfWriteStream* stream) const = 0;
};

class ProgramTable : public PseudoSection {
 public:
  explicit ProgramTable(Zone* zone)
      : PseudoSection(/*allocate=*/true,
                      /*executable=*/false,
                      /*writable=*/false),
        segments_(zone, 0) {
    entry_size = sizeof(elf::ProgramHeader);
  }

  const GrowableArray<Segment*>& segments() const { return segments_; }
  intptr_t SegmentCount() const { return segments_.length(); }
  intptr_t MemorySize() const {
    return segments_.length() * sizeof(elf::ProgramHeader);
  }

  void Add(Segment* segment) {
    ASSERT(segment != nullptr);
    segments_.Add(segment);
  }

  void Write(ElfWriteStream* stream) const;

 private:
  GrowableArray<Segment*> segments_;
};

// This particular PseudoSection should not appear in segments either (hence
// being marked non-allocated), but is directly held by the Elf object.
class SectionTable : public PseudoSection {
 public:
  explicit SectionTable(Zone* zone)
      : PseudoSection(/*allocate=*/false,
                      /*executable=*/false,
                      /*writable=*/false),
        zone_(zone),
        sections_(zone_, 2),
        shstrtab_(zone_, /*allocate=*/false) {
    entry_size = sizeof(elf::SectionHeader);
    // The section at index 0 (elf::SHN_UNDEF) must be all 0s.
    ASSERT_EQUAL(shstrtab_.Lookup(""), 0);
    Add(new (zone_) ReservedSection(), "");
    Add(&shstrtab_, ".shstrtab");
  }

  const GrowableArray<Section*>& sections() const { return sections_; }
  intptr_t SectionCount() const { return sections_.length(); }
  intptr_t StringTableIndex() const { return shstrtab_.index; }

  bool HasSectionNamed(const char* name) {
    return shstrtab_.Lookup(name) != StringTable::kNotIndexed;
  }

  void Add(Section* section, const char* name = nullptr) {
    ASSERT(!section->IsPseudoSection());
    ASSERT(name != nullptr || section->name_is_set());
    if (name != nullptr) {
      // First, check for an existing section with the same table name.
      if (auto* const old_section = Find(name)) {
        ASSERT(old_section->CanMergeWith(*section));
        old_section->Merge(*section);
        return;
      }
      // No existing section with this name.
      const intptr_t name_index = shstrtab_.Add(name);
      section->set_name(name_index);
    }
    section->index = sections_.length();
    sections_.Add(section);
  }

  Section* Find(const char* name) {
    const intptr_t name_index = shstrtab_.Lookup(name);
    if (name_index == StringTable::kNotIndexed) {
      // We're guaranteed that no section with this name has been added yet.
      return nullptr;
    }
    // We check walk all sections to check for uniqueness in DEBUG mode.
    Section* result = nullptr;
    for (Section* const section : sections_) {
      if (section->name() == name_index) {
#if defined(DEBUG)
        ASSERT(result == nullptr);
        result = section;
#else
        return section;
#endif
      }
    }
    return result;
  }

  intptr_t FileSize() const {
    return sections_.length() * sizeof(elf::SectionHeader);
  }

  void Write(ElfWriteStream* stream) const;

  // Reorders the sections for creating a minimal amount of segments and
  // creates and returns an appropriate program table.
  //
  // Also takes and adjusts section indices in the static symbol table, since it
  // is not recorded in sections_ for stripped outputs.
  ProgramTable* CreateProgramTable(SymbolTable* symtab);

 private:
  Zone* const zone_;
  GrowableArray<Section*> sections_;
  StringTable shstrtab_;
};

class ElfHeader : public PseudoSection {
 public:
  ElfHeader(const ProgramTable& program_table,
            const SectionTable& section_table)
      : PseudoSection(/*allocate=*/true,
                      /*executable=*/false,
                      /*writable=*/false),
        program_table_(program_table),
        section_table_(section_table) {}

  intptr_t MemorySize() const { return sizeof(elf::ElfHeader); }

  void Write(ElfWriteStream* stream) const;

 private:
  const ProgramTable& program_table_;
  const SectionTable& section_table_;
};

#undef DEFINE_TYPE_CHECK_FOR
#undef FOR_EACH_SECTION_TYPE

Elf::Elf(Zone* zone, BaseWriteStream* stream, Type type, Dwarf* dwarf)
    : zone_(zone),
      unwrapped_stream_(stream),
      type_(type),
      dwarf_(dwarf),
      section_table_(new (zone) SectionTable(zone)) {
  // Separate debugging information should always have a Dwarf object.
  ASSERT(type_ == Type::Snapshot || dwarf_ != nullptr);
  // Assumed by various offset logic in this file.
  ASSERT_EQUAL(unwrapped_stream_->Position(), 0);
}

void Elf::AddText(const char* name,
                  const uint8_t* bytes,
                  intptr_t size,
                  const ZoneGrowableArray<Relocation>* relocations,
                  const ZoneGrowableArray<SymbolData>* symbols) {
  auto* const container = new (zone_) TextSection(type_);
  container->AddPortion(bytes, size, relocations, symbols, name);
  section_table_->Add(container, kTextName);
}

void Elf::CreateBSS() {
  // Not idempotent.
  ASSERT(section_table_->Find(kBssName) == nullptr);
  // No text section means no BSS section.
  auto* const text_section = section_table_->Find(kTextName);
  if (text_section == nullptr) return;
  ASSERT(text_section->IsTextSection());

  auto* const bss_container = new (zone_) BssSection(type_);
  for (const auto& portion : text_section->AsBitsContainer()->portions()) {
    size_t size;
    const char* symbol_name;
    // First determine whether this is the VM's text portion or the isolate's.
    if (strcmp(portion.symbol_name, kVmSnapshotInstructionsAsmSymbol) == 0) {
      size = BSS::kVmEntryCount * compiler::target::kWordSize;
      symbol_name = kVmSnapshotBssAsmSymbol;
    } else if (strcmp(portion.symbol_name,
                      kIsolateSnapshotInstructionsAsmSymbol) == 0) {
      size = BSS::kIsolateEntryCount * compiler::target::kWordSize;
      symbol_name = kIsolateSnapshotBssAsmSymbol;
    } else {
      // Not VM or isolate text.
      UNREACHABLE();
      continue;
    }

    uint8_t* bytes = nullptr;
    if (type_ == Type::Snapshot) {
      // 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 data for the BSS.
      bytes = zone_->Alloc<uint8_t>(size);
      memset(bytes, 0, size);
    }
    // For the BSS section, we add the section symbols as local symbols in the
    // static symbol table, as these addresses are only used for relocation.
    // (This matches the behavior in the assembly output.)
    auto* symbols = new (zone_) ZoneGrowableArray<Elf::SymbolData>();
    symbols->Add({symbol_name, elf::STT_SECTION, 0, size});
    bss_container->AddPortion(bytes, size, /*relocations=*/nullptr, symbols);
  }

  section_table_->Add(bss_container, kBssName);
}

void Elf::AddROData(const char* name,
                    const uint8_t* bytes,
                    intptr_t size,
                    const ZoneGrowableArray<Relocation>* relocations,
                    const ZoneGrowableArray<SymbolData>* symbols) {
  auto* const container = new (zone_) DataSection(type_);
  container->AddPortion(bytes, size, relocations, symbols, name);
  section_table_->Add(container, kDataName);
}

#if defined(DART_PRECOMPILER)
class DwarfElfStream : public DwarfWriteStream {
 public:
  DwarfElfStream(Zone* zone, NonStreamingWriteStream* stream)
      : zone_(ASSERT_NOTNULL(zone)),
        stream_(ASSERT_NOTNULL(stream)),
        relocations_(new (zone) ZoneGrowableArray<Elf::Relocation>()) {}

  const uint8_t* buffer() const { return stream_->buffer(); }
  intptr_t bytes_written() const { return stream_->bytes_written(); }
  intptr_t Position() const { return stream_->Position(); }

  void sleb128(intptr_t value) { stream_->WriteSLEB128(value); }
  void uleb128(uintptr_t value) { stream_->WriteLEB128(value); }
  void u1(uint8_t value) { stream_->WriteByte(value); }
  void u2(uint16_t value) { stream_->WriteFixed(value); }
  void u4(uint32_t value) { stream_->WriteFixed(value); }
  void u8(uint64_t value) { stream_->WriteFixed(value); }
  void string(const char* cstr) {  // NOLINT
    // Unlike stream_->WriteString(), we want the null terminator written.
    stream_->WriteBytes(cstr, strlen(cstr) + 1);
  }
  // The prefix is ignored for DwarfElfStreams.
  EncodedPosition WritePrefixedLength(const char* symbol_prefix,
                                      std::function<void()> body) {
    const intptr_t fixup = stream_->Position();
    // We assume DWARF v2 currently, so all sizes are 32-bit.
    u4(0);
    // All sizes for DWARF sections measure the size of the section data _after_
    // the size value.
    const intptr_t start = stream_->Position();
    body();
    const intptr_t end = stream_->Position();
    stream_->SetPosition(fixup);
    u4(end - start);
    stream_->SetPosition(end);
    return EncodedPosition(fixup);
  }
  // Shorthand for when working directly with DwarfElfStreams.
  intptr_t WritePrefixedLength(std::function<void()> body) {
    const EncodedPosition& pos = WritePrefixedLength(nullptr, body);
    return pos.position();
  }

  void OffsetFromSymbol(const char* symbol, intptr_t offset) {
    relocations_->Add(
        {kAddressSize, stream_->Position(), "", 0, symbol, offset});
    addr(0);  // Resolved later.
  }
  template <typename T>
  void RelativeSymbolOffset(const char* symbol) {
    relocations_->Add({sizeof(T), stream_->Position(), nullptr, 0, symbol, 0});
    stream_->WriteFixed<T>(0);  // Resolved later.
  }
  void InitializeAbstractOrigins(intptr_t size) {
    abstract_origins_size_ = size;
    abstract_origins_ = zone_->Alloc<uint32_t>(abstract_origins_size_);
  }
  void RegisterAbstractOrigin(intptr_t index) {
    ASSERT(abstract_origins_ != nullptr);
    ASSERT(index < abstract_origins_size_);
    abstract_origins_[index] = stream_->Position();
  }
  void AbstractOrigin(intptr_t index) { u4(abstract_origins_[index]); }

  const ZoneGrowableArray<Elf::Relocation>* relocations() const {
    return relocations_;
  }

 protected:
#if defined(TARGET_ARCH_IS_32_BIT)
  static constexpr intptr_t kAddressSize = kInt32Size;
#else
  static constexpr intptr_t kAddressSize = kInt64Size;
#endif

  void addr(uword value) {
#if defined(TARGET_ARCH_IS_32_BIT)
    u4(value);
#else
    u8(value);
#endif
  }

  Zone* const zone_;
  NonStreamingWriteStream* const stream_;
  ZoneGrowableArray<Elf::Relocation>* relocations_ = nullptr;
  uint32_t* abstract_origins_ = nullptr;
  intptr_t abstract_origins_size_ = -1;

 private:
  DISALLOW_COPY_AND_ASSIGN(DwarfElfStream);
};

static constexpr intptr_t kInitialDwarfBufferSize = 64 * KB;
#endif

void SymbolTable::Initialize(const GrowableArray<Section*>& sections) {
  for (auto* const section : sections) {
    // The values of all added symbols are memory addresses.
    if (!section->IsAllocated()) continue;
    if (auto* const bits = section->AsBitsContainer()) {
      for (const auto& portion : section->AsBitsContainer()->portions()) {
        if (portion.symbol_name != nullptr) {
          // Global dynamic symbols for the content of a given section, which is
          // always a single structured element (and thus we use STT_OBJECT).
          const intptr_t binding = elf::STB_GLOBAL;
          const intptr_t type = elf::STT_OBJECT;
          // Some tools assume the static symbol table is a superset of the
          // dynamic symbol table when it exists and only use it, so put all
          // dynamic symbols there also. (see dartbug.com/41783).
          AddSymbol(portion.symbol_name, binding, type, portion.size,
                    section->index, portion.offset);
        }
        if (!dynamic_ && portion.symbols != nullptr) {
          for (const auto& symbol_data : *portion.symbols) {
            // Local static-only symbols, e.g., code payloads or RO objects.
            AddSymbol(symbol_data.name, elf::STB_LOCAL, symbol_data.type,
                      symbol_data.size, section->index,
                      portion.offset + symbol_data.offset);
          }
        }
      }
    }
  }
}

void Elf::InitializeSymbolTables() {
  // Not idempotent.
  ASSERT(symtab_ == nullptr);

  // Create static and dynamic symbol tables.
  auto* const dynstrtab = new (zone_) StringTable(zone_, /*allocate=*/true);
  section_table_->Add(dynstrtab, ".dynstr");
  auto* const dynsym =
      new (zone_) SymbolTable(zone_, dynstrtab, /*dynamic=*/true);
  section_table_->Add(dynsym, ".dynsym");
  dynsym->Initialize(section_table_->sections());
  // Now the dynamic symbol table is populated, set up the hash table and
  // dynamic table.
  auto* const hash = new (zone_) SymbolHashTable(zone_, dynsym);
  section_table_->Add(hash, ".hash");
  auto* const dynamic = new (zone_) DynamicTable(zone_, dynsym, hash);
  section_table_->Add(dynamic, kDynamicTableName);

  // We only add the static string and symbol tables to the section table if
  // this is an unstripped output, but we always create them as they are used
  // to resolve relocations.
  auto* const strtab = new (zone_) StringTable(zone_, /*allocate=*/false);
  if (!IsStripped()) {
    section_table_->Add(strtab, ".strtab");
  }
  symtab_ = new (zone_) SymbolTable(zone_, strtab, /*dynamic=*/false);
  if (!IsStripped()) {
    section_table_->Add(symtab_, ".symtab");
  }
  symtab_->Initialize(section_table_->sections());
}

void Elf::FinalizeEhFrame() {
#if !defined(TARGET_ARCH_IA32)
#if defined(TARGET_ARCH_X64)
  // The x86_64 psABI defines the DWARF register numbers, which differ from
  // the registers' usual encoding within instructions.
  const intptr_t DWARF_RA = 16;  // No corresponding register.
  const intptr_t DWARF_FP = 6;   // RBP
#else
  const intptr_t DWARF_RA = ConcreteRegister(LINK_REGISTER);
  const intptr_t DWARF_FP = FP;
#endif

  // No text section added means no .eh_frame.
  TextSection* text_section = nullptr;
  if (auto* const section = section_table_->Find(kTextName)) {
    text_section = section->AsTextSection();
    ASSERT(text_section != nullptr);
  }
  // No text section added means no .eh_frame.
  if (text_section == nullptr) return;

  // Multiplier which will be used to scale operands of DW_CFA_offset and
  // DW_CFA_val_offset.
  const intptr_t kDataAlignment = -compiler::target::kWordSize;

  static const uint8_t DW_EH_PE_pcrel = 0x10;
  static const uint8_t DW_EH_PE_sdata4 = 0x0b;

  ZoneWriteStream stream(zone(), kInitialDwarfBufferSize);
  DwarfElfStream dwarf_stream(zone_, &stream);

  // Emit CIE.

  // Used to calculate offset to CIE in FDEs.
  const intptr_t cie_start = dwarf_stream.WritePrefixedLength([&] {
    dwarf_stream.u4(0);  // CIE
    dwarf_stream.u1(1);  // Version (must be 1 or 3)
    // Augmentation String
    dwarf_stream.string("zR");             // NOLINT
    dwarf_stream.uleb128(1);               // Code alignment (must be 1).
    dwarf_stream.sleb128(kDataAlignment);  // Data alignment
    dwarf_stream.u1(DWARF_RA);             // Return address register
    dwarf_stream.uleb128(1);               // Augmentation size
    dwarf_stream.u1(DW_EH_PE_pcrel | DW_EH_PE_sdata4);  // FDE encoding.
    // CFA is caller's SP (FP+kCallerSpSlotFromFp*kWordSize)
    dwarf_stream.u1(Dwarf::DW_CFA_def_cfa);
    dwarf_stream.uleb128(DWARF_FP);
    dwarf_stream.uleb128(kCallerSpSlotFromFp * compiler::target::kWordSize);
  });

  // Emit rule defining that |reg| value is stored at CFA+offset.
  const auto cfa_offset = [&](intptr_t reg, intptr_t offset) {
    const intptr_t scaled_offset = offset / kDataAlignment;
    RELEASE_ASSERT(scaled_offset >= 0);
    dwarf_stream.u1(Dwarf::DW_CFA_offset | reg);
    dwarf_stream.uleb128(scaled_offset);
  };

  // Emit an FDE covering each .text section.
  for (const auto& portion : text_section->portions()) {
    ASSERT(portion.symbol_name != nullptr);  // Needed for relocations.
    dwarf_stream.WritePrefixedLength([&]() {
      // Offset to CIE. Note that unlike pcrel this offset is encoded
      // backwards: it will be subtracted from the current position.
      dwarf_stream.u4(stream.Position() - cie_start);
      // Start address as a PC relative reference.
      dwarf_stream.RelativeSymbolOffset<int32_t>(portion.symbol_name);
      dwarf_stream.u4(portion.size);           // Size.
      dwarf_stream.u1(0);                      // Augmentation Data length.

      // Caller FP at FP+kSavedCallerPcSlotFromFp*kWordSize,
      // where FP is CFA - kCallerSpSlotFromFp*kWordSize.
      COMPILE_ASSERT((kSavedCallerFpSlotFromFp - kCallerSpSlotFromFp) <= 0);
      cfa_offset(DWARF_FP, (kSavedCallerFpSlotFromFp - kCallerSpSlotFromFp) *
                               compiler::target::kWordSize);

      // Caller LR at FP+kSavedCallerPcSlotFromFp*kWordSize,
      // where FP is CFA - kCallerSpSlotFromFp*kWordSize
      COMPILE_ASSERT((kSavedCallerPcSlotFromFp - kCallerSpSlotFromFp) <= 0);
      cfa_offset(DWARF_RA, (kSavedCallerPcSlotFromFp - kCallerSpSlotFromFp) *
                               compiler::target::kWordSize);
    });
  }

  dwarf_stream.u4(0);  // end of section (FDE with zero length)

  auto* const eh_frame = new (zone_)
      BitsContainer(type_, /*writable=*/false, /*executable=*/false);
  eh_frame->AddPortion(dwarf_stream.buffer(), dwarf_stream.bytes_written(),
                       dwarf_stream.relocations());
  section_table_->Add(eh_frame, ".eh_frame");
#endif  // !defined(TARGET_ARCH_IA32)
}

void Elf::FinalizeDwarfSections() {
  if (dwarf_ == nullptr) return;

  // Currently we only output DWARF information involving code.
  ASSERT(section_table_->HasSectionNamed(kTextName));

  auto add_debug = [&](const char* name, const DwarfElfStream& stream) {
    auto const container =
        new (zone_) BitsContainer(elf::SectionHeaderType::SHT_PROGBITS);
    container->AddPortion(stream.buffer(), stream.bytes_written(),
                          stream.relocations());
    section_table_->Add(container, name);
  };
  {
    ZoneWriteStream stream(zone(), kInitialDwarfBufferSize);
    DwarfElfStream dwarf_stream(zone_, &stream);
    dwarf_->WriteAbbreviations(&dwarf_stream);
    add_debug(".debug_abbrev", dwarf_stream);
  }

  {
    ZoneWriteStream stream(zone(), kInitialDwarfBufferSize);
    DwarfElfStream dwarf_stream(zone_, &stream);
    dwarf_->WriteDebugInfo(&dwarf_stream);
    add_debug(".debug_info", dwarf_stream);
  }

  {
    ZoneWriteStream stream(zone(), kInitialDwarfBufferSize);
    DwarfElfStream dwarf_stream(zone_, &stream);
    dwarf_->WriteLineNumberProgram(&dwarf_stream);
    add_debug(".debug_line", dwarf_stream);
  }
}

ProgramTable* SectionTable::CreateProgramTable(SymbolTable* symtab) {
  const intptr_t num_sections = sections_.length();
  // Should have at least the reserved entry in sections_.
  ASSERT(!sections_.is_empty());
  ASSERT_EQUAL(sections_[0]->alignment, 0);

  // The new program table that collects the segments for allocated sections
  // and a few special segments.
  auto* const program_table = new (zone_) ProgramTable(zone_);

  GrowableArray<Section*> reordered_sections(zone_, num_sections);
  // Maps the old indices of sections to the new ones.
  GrowableArray<intptr_t> index_map(zone_, num_sections);
  index_map.FillWith(0, 0, num_sections);

  Segment* current_segment = nullptr;
  // Only called for sections in the section table (i.e., not special sections
  // appearing in segments only or the section table itself).
  auto add_to_reordered_sections = [&](Section* section) {
    intptr_t new_index = reordered_sections.length();
    index_map[section->index] = new_index;
    section->index = new_index;
    reordered_sections.Add(section);
    if (section->IsAllocated()) {
      ASSERT(current_segment != nullptr);
      if (!current_segment->Add(section)) {
        // The current segment is incompatible for the current sectioni, so
        // create a new one.
        current_segment = new (zone_)
            Segment(zone_, section, elf::ProgramHeaderType::PT_LOAD);
        program_table->Add(current_segment);
      }
    }
  };

  // The first section in the section header table is always a reserved
  // entry containing only 0 values, so copy it over from sections_.
  add_to_reordered_sections(sections_[0]);

  // There are few important invariants originating from Android idiosyncrasies
  // we are trying to maintain when ordering sections:
  //
  //   - Android requires the program header table be in the first load segment,
  //     so create PseudoSections representing the ELF header and program header
  //     table to initialize that segment.
  //
  //   - The Android dynamic linker in Jelly Bean incorrectly assumes that all
  //     non-writable segments are continguous. Thus we write them all together.
  //     The bug is here: https://github.com/aosp-mirror/platform_bionic/blob/94963af28e445384e19775a838a29e6a71708179/linker/linker.c#L1991-L2001
  //
  //   - On Android native libraries can be mapped directly from an APK
  //     they are stored uncompressed in it. In such situations the name
  //     of the mapping no longer provides enough information for libunwindstack
  //     to find the original ELF file and instead it has to rely on heuristics
  //     to locate program header table. These heuristics currently assume that
  //     program header table will be located in the RO mapping which precedes
  //     RX mapping.
  //
  // These invariants imply the following order of segments: RO (program
  // header,  .note.gnu.build-id, .dynstr, .dynsym, .hash, .rodata
  // and .eh_frame), RX (.text), RW (.dynamic and .bss).
  //
  auto* const elf_header = new (zone_) ElfHeader(*program_table, *this);

  // Self-reference to program header table. Required by Android but not by
  // Linux. Must appear before any PT_LOAD entries.
  program_table->Add(new (zone_) Segment(zone_, program_table,
                                         elf::ProgramHeaderType::PT_PHDR));

  // Create the initial load segment which contains the ELF header and program
  // table.
  current_segment =
      new (zone_) Segment(zone_, elf_header, elf::ProgramHeaderType::PT_LOAD);
  program_table->Add(current_segment);
  current_segment->Add(program_table);

  // We now do several passes over the collected sections to reorder them in
  // a way that minimizes segments (and thus padding) in the resulting snapshot.

  auto add_sections_matching =
      [&](const std::function<bool(Section*)>& should_add) {
        // We order the sections in a segment so all non-NOBITS sections come
        // before NOBITS sections, since the former sections correspond to the
        // file contents for the segment.
        for (auto* const section : sections_) {
          if (!section->HasBits()) continue;
          if (should_add(section)) {
            add_to_reordered_sections(section);
          }
        }
        for (auto* const section : sections_) {
          if (section->HasBits()) continue;
          if (should_add(section)) {
            add_to_reordered_sections(section);
          }
        }
      };

  // If a build ID was created, we put it right after the program table so it
  // can be read with a minimum number of bytes from the ELF file.
  auto* const build_id = Find(Elf::kBuildIdNoteName);
  if (build_id != nullptr) {
    ASSERT(build_id->type == elf::SectionHeaderType::SHT_NOTE);
    add_to_reordered_sections(build_id);
  }

  // Now add the other non-writable, non-executable allocated sections.
  add_sections_matching([&](Section* section) -> bool {
    if (section == build_id) return false;  // Already added.
    return section->IsAllocated() && !section->IsWritable() &&
           !section->IsExecutable();
  });

  // Now add the executable sections in a new segment.
  add_sections_matching([](Section* section) -> bool {
    return section->IsExecutable();  // Implies IsAllocated() && !IsWritable()
  });

  // Now add all the writable sections.
  add_sections_matching([](Section* section) -> bool {
    return section->IsWritable();  // Implies IsAllocated() && !IsExecutable()
  });

  // We put all non-reserved unallocated sections last. Otherwise, they would
  // affect the file offset but not the memory offset of any following allocated
  // sections. Doing it in this order makes it easier to keep file and memory
  // offsets page-aligned with respect to each other, which is required for
  // some loaders.
  add_sections_matching([](Section* section) -> bool {
    // Don't re-add the initial reserved section.
    return !section->IsReservedSection() && !section->IsAllocated();
  });

  // All sections should have been accounted for in the loops above.
  ASSERT_EQUAL(sections_.length(), reordered_sections.length());
  // Replace the content of sections_ with the reordered sections.
  sections_.Clear();
  sections_.AddArray(reordered_sections);

  // This must be true for uses of the map to be correct.
  ASSERT_EQUAL(index_map[elf::SHN_UNDEF], elf::SHN_UNDEF);

  // Since the section indices have been updated, change links to match
  // and update the indexes of symbols in any symbol tables.
  for (auto* const section : sections_) {
    // SHN_UNDEF maps to SHN_UNDEF, so no need to check for it.
    section->link = index_map[section->link];
    if (auto* const table = section->AsSymbolTable()) {
      table->UpdateSectionIndices(index_map);
    }
  }
  if (symtab->index == elf::SHN_UNDEF) {
    // The output is stripped, so this wasn't finalized during the loop above.
    symtab->UpdateSectionIndices(index_map);
  }

  // Add any special non-load segments.
  if (build_id != nullptr) {
    // Add a PT_NOTE segment for the build ID.
    program_table->Add(
        new (zone_) Segment(zone_, build_id, elf::ProgramHeaderType::PT_NOTE));
  }

  // Add a PT_DYNAMIC segment for the dynamic symbol table.
  ASSERT(HasSectionNamed(Elf::kDynamicTableName));
  auto* const dynamic = Find(Elf::kDynamicTableName)->AsDynamicTable();
  program_table->Add(
      new (zone_) Segment(zone_, dynamic, elf::ProgramHeaderType::PT_DYNAMIC));

  return program_table;
}

void Elf::Finalize() {
  // Generate the build ID now that we have all user-provided sections.
  GenerateBuildId();

  // We add a BSS section in all cases, even to the separate debugging
  // information, to ensure that relocated addresses are consistent between ELF
  // snapshots and the corresponding separate debugging information.
  CreateBSS();

  FinalizeEhFrame();
  FinalizeDwarfSections();

  // Create and initialize the dynamic and static symbol tables and any
  // other associated sections now that all other sections have been added.
  InitializeSymbolTables();
  // Creates an appropriate program table containing load segments for allocated
  // sections and any other segments needed. May reorder sections to minimize
  // the number of load segments, so also takes the static symbol table so
  // symbol section indices can be adjusted if needed.
  program_table_ = section_table_->CreateProgramTable(symtab_);
  // Calculate file and memory offsets, and finalizes symbol values in any
  // symbol tables.
  ComputeOffsets();

#if defined(DEBUG)
  if (type_ == Type::Snapshot) {
    // For files that will be dynamically loaded, ensure the file offsets
    // of allocated sections are page aligned to the memory offsets.
    for (auto* const segment : program_table_->segments()) {
      for (auto* const section : segment->sections()) {
        ASSERT_EQUAL(section->file_offset() % Elf::kPageSize,
                     section->memory_offset() % Elf::kPageSize);
      }
    }
  }
#endif

  // Finally, write the ELF file contents.
  ElfWriteStream wrapped(unwrapped_stream_, *this);

  auto write_section = [&](const Section* section) {
    wrapped.Align(section->alignment);
    ASSERT_EQUAL(wrapped.Position(), section->file_offset());
    section->Write(&wrapped);
    ASSERT_EQUAL(wrapped.Position(),
                 section->file_offset() + section->FileSize());
  };

  // To match ComputeOffsets, first we write allocated sections and then
  // unallocated sections. We access the allocated sections via the load
  // segments so we can properly align the stream for each entered segment.
  intptr_t section_index = 1;  // We don't visit the reserved section.
  for (auto* const segment : program_table_->segments()) {
    if (segment->type != elf::ProgramHeaderType::PT_LOAD) continue;
    wrapped.Align(segment->Alignment());
    for (auto* const section : segment->sections()) {
      ASSERT(section->IsAllocated());
      write_section(section);
      if (!section->IsPseudoSection()) {
        ASSERT_EQUAL(section->index, section_index);
        section_index++;
      }
    }
  }
  const auto& sections = section_table_->sections();
  for (; section_index < sections.length(); section_index++) {
    auto* const section = sections[section_index];
    ASSERT(!section->IsAllocated());
    write_section(section);
  }
  // Finally, write the section table.
  write_section(section_table_);
}

// For the build ID, we generate a 128-bit hash, where each 32 bits is a hash of
// the contents of the following segments in order:
//
// .text(VM) | .text(Isolate) | .rodata(VM) | .rodata(Isolate)
static constexpr const char* kBuildIdSegmentNames[]{
    kVmSnapshotInstructionsAsmSymbol,
    kIsolateSnapshotInstructionsAsmSymbol,
    kVmSnapshotDataAsmSymbol,
    kIsolateSnapshotDataAsmSymbol,
};
static constexpr intptr_t kBuildIdSegmentNamesLength =
    ARRAY_SIZE(kBuildIdSegmentNames);
// Includes the note name, but not the description.
static constexpr intptr_t kBuildIdHeaderSize =
    sizeof(elf::Note) + sizeof(elf::ELF_NOTE_GNU);

void Elf::GenerateBuildId() {
  // Not idempotent.
  ASSERT(section_table_->Find(kBuildIdNoteName) == nullptr);
  uint32_t hashes[kBuildIdSegmentNamesLength];
  // Currently, we construct the build ID out of data from two different
  // sections: the .text section and the .rodata section. We only create
  // a build ID when we have all four sections and when we have the actual
  // bytes from those sections.
  //
  // TODO(dartbug.com/43274): Generate build IDs for separate debugging
  // information for assembly snapshots.
  //
  // TODO(dartbug.com/43516): Generate build IDs for snapshots with deferred
  // sections.
  auto* const text_section = section_table_->Find(kTextName);
  if (text_section == nullptr) return;
  ASSERT(text_section->IsTextSection());
  auto* const text_bits = text_section->AsBitsContainer();
  auto* const data_section = section_table_->Find(kDataName);
  if (data_section == nullptr) return;
  ASSERT(data_section->IsDataSection());
  auto* const data_bits = data_section->AsBitsContainer();
  // Now try to find
  for (intptr_t i = 0; i < kBuildIdSegmentNamesLength; i++) {
    auto* const name = kBuildIdSegmentNames[i];
    hashes[i] = text_bits->Hash(name);
    if (hashes[i] == 0) {
      hashes[i] = data_bits->Hash(name);
    }
    // The symbol wasn't found in either section or there were no bytes
    // associated with the symbol.
    if (hashes[i] == 0) return;
  }
  auto const description_bytes = reinterpret_cast<uint8_t*>(hashes);
  const size_t description_length = sizeof(hashes);
  // Now that we have the description field contents, create the section.
  ZoneWriteStream stream(zone(), kBuildIdHeaderSize + description_length);
  stream.WriteFixed<decltype(elf::Note::name_size)>(sizeof(elf::ELF_NOTE_GNU));
  stream.WriteFixed<decltype(elf::Note::description_size)>(description_length);
  stream.WriteFixed<decltype(elf::Note::type)>(elf::NoteType::NT_GNU_BUILD_ID);
  ASSERT_EQUAL(stream.Position(), sizeof(elf::Note));
  stream.WriteBytes(elf::ELF_NOTE_GNU, sizeof(elf::ELF_NOTE_GNU));
  ASSERT_EQUAL(stream.bytes_written(), kBuildIdHeaderSize);
  stream.WriteBytes(description_bytes, description_length);
  auto* const container = new (zone_) NoteSection();
  container->AddPortion(stream.buffer(), stream.bytes_written(),
                        /*relocations=*/nullptr, /*symbols=*/nullptr,
                        kSnapshotBuildIdAsmSymbol);
  section_table_->Add(container, kBuildIdNoteName);
}

void Elf::ComputeOffsets() {
  intptr_t file_offset = 0;
  intptr_t memory_offset = 0;

  // Maps indices of allocated sections in the section table to memory offsets.
  const intptr_t num_sections = section_table_->SectionCount();
  GrowableArray<intptr_t> address_map(zone_, num_sections);
  address_map.Add(0);  // Don't adjust offsets for symbols with index SHN_UNDEF.

  auto calculate_section_offsets = [&](Section* section) {
    file_offset = Utils::RoundUp(file_offset, section->alignment);
    section->set_file_offset(file_offset);
    file_offset += section->FileSize();
    if (section->IsAllocated()) {
      memory_offset = Utils::RoundUp(memory_offset, section->alignment);
      section->set_memory_offset(memory_offset);
      memory_offset += section->MemorySize();
    }
  };

  intptr_t section_index = 1;  // We don't visit the reserved section.
  for (auto* const segment : program_table_->segments()) {
    if (segment->type != elf::ProgramHeaderType::PT_LOAD) continue;
    // Adjust file and memory offsets for segment alignment on entry.
    file_offset = Utils::RoundUp(file_offset, segment->Alignment());
    memory_offset = Utils::RoundUp(memory_offset, segment->Alignment());
    for (auto* const section : segment->sections()) {
      ASSERT(section->IsAllocated());
      calculate_section_offsets(section);
      if (!section->IsPseudoSection()) {
        // Note: this assumes that the sections in the section header has all
        // allocated sections before all (non-reserved) unallocated sections and
        // in the same order as the load segments in in the program table.
        address_map.Add(section->memory_offset());
        ASSERT_EQUAL(section->index, section_index);
        section_index++;
      }
    }
  }

  const auto& sections = section_table_->sections();
  for (; section_index < sections.length(); section_index++) {
    auto* const section = sections[section_index];
    ASSERT(!section->IsAllocated());
    calculate_section_offsets(section);
  }

  ASSERT_EQUAL(section_index, sections.length());
  // Now that all sections have been handled, set the file offset for the
  // section table, as it will be written after the last section.
  calculate_section_offsets(section_table_);

#if defined(DEBUG)
  // Double check that segment starts are aligned as expected.
  for (auto* const segment : program_table_->segments()) {
    ASSERT(Utils::IsAligned(segment->MemoryOffset(), segment->Alignment()));
  }
#endif

  // This must be true for uses of the map to be correct.
  ASSERT_EQUAL(address_map[elf::SHN_UNDEF], 0);
  // Adjust addresses in symbol tables as we now have section memory offsets.
  // Also finalize the entries of the dynamic table, as some are memory offsets.
  for (auto* const section : sections) {
    if (auto* const table = section->AsSymbolTable()) {
      table->Finalize(address_map);
    } else if (auto* const dynamic = section->AsDynamicTable()) {
      dynamic->Finalize();
    }
  }
  // Also adjust addresses in symtab for stripped snapshots.
  if (IsStripped()) {
    ASSERT_EQUAL(symtab_->index, elf::SHN_UNDEF);
    symtab_->Finalize(address_map);
  }
}

void ElfHeader::Write(ElfWriteStream* stream) const {
  ASSERT_EQUAL(file_offset(), 0);
  ASSERT_EQUAL(memory_offset(), 0);
#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);

  stream->WriteHalf(elf::ET_DYN);  // Shared library.

#if defined(TARGET_ARCH_IA32)
  stream->WriteHalf(elf::EM_386);
#elif defined(TARGET_ARCH_X64)
  stream->WriteHalf(elf::EM_X86_64);
#elif defined(TARGET_ARCH_ARM)
  stream->WriteHalf(elf::EM_ARM);
#elif defined(TARGET_ARCH_ARM64)
  stream->WriteHalf(elf::EM_AARCH64);
#elif defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
  stream->WriteHalf(elf::EM_RISCV);
#else
  FATAL("Unknown ELF architecture");
#endif

  stream->WriteWord(elf::EV_CURRENT);  // Version
  stream->WriteAddr(0);                // "Entry point"
  stream->WriteOff(program_table_.file_offset());
  stream->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
  stream->WriteWord(flags);

  stream->WriteHalf(sizeof(elf::ElfHeader));
  stream->WriteHalf(program_table_.entry_size);
  stream->WriteHalf(program_table_.SegmentCount());
  stream->WriteHalf(section_table_.entry_size);
  stream->WriteHalf(section_table_.SectionCount());
  stream->WriteHalf(stream->elf().section_table().StringTableIndex());
}

void ProgramTable::Write(ElfWriteStream* stream) const {
  ASSERT(segments_.length() > 0);
  // Make sure all relevant segments were created by checking the type of the
  // first.
  ASSERT(segments_[0]->type == elf::ProgramHeaderType::PT_PHDR);
  const intptr_t start = stream->Position();
  // Should be immediately following the ELF header.
  ASSERT_EQUAL(start, sizeof(elf::ElfHeader));
#if defined(DEBUG)
  // Here, we count the number of times that a PT_LOAD writable segment is
  // followed by a non-writable segment. We initialize last_writable to true
  // so that we catch the case where the first segment is non-writable.
  bool last_writable = true;
  int non_writable_groups = 0;
#endif
  for (intptr_t i = 0; i < segments_.length(); i++) {
    const Segment* const segment = segments_[i];
    ASSERT(segment->type != elf::ProgramHeaderType::PT_NULL);
    ASSERT_EQUAL(i == 0, segment->type == elf::ProgramHeaderType::PT_PHDR);
#if defined(DEBUG)
    if (segment->type == elf::ProgramHeaderType::PT_LOAD) {
      if (last_writable && !segment->IsWritable()) {
        non_writable_groups++;
      }
      last_writable = segment->IsWritable();
    }
#endif
    const intptr_t start = stream->Position();
    segment->WriteProgramHeader(stream);
    const intptr_t end = stream->Position();
    ASSERT_EQUAL(end - start, entry_size);
  }
#if defined(DEBUG)
  // All PT_LOAD non-writable segments must be contiguous. If not, some older
  // Android dynamic linkers fail to handle writable segments between
  // non-writable ones. See https://github.com/flutter/flutter/issues/43259.
  ASSERT(non_writable_groups <= 1);
#endif
}

void SectionTable::Write(ElfWriteStream* stream) const {
  for (intptr_t i = 0; i < sections_.length(); i++) {
    const Section* const section = sections_[i];
    ASSERT_EQUAL(i == 0, section->IsReservedSection());
    ASSERT_EQUAL(section->index, i);
    ASSERT(section->link < sections_.length());
    const intptr_t start = stream->Position();
    section->WriteSectionHeader(stream);
    const intptr_t end = stream->Position();
    ASSERT_EQUAL(end - start, entry_size);
  }
}

#endif  // DART_PRECOMPILER

}  // namespace dart
