// 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; }

  // 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_ARM) || defined(TARGET_ARCH_ARM64)
  // 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(
        ConcreteRegister(LINK_REGISTER));  // Return address register
    dwarf_stream.uleb128(1);               // Augmentation size
    dwarf_stream.u1(DW_EH_PE_pcrel | DW_EH_PE_sdata4);  // FDE encoding.
    // CFA is FP+0
    dwarf_stream.u1(Dwarf::DW_CFA_def_cfa);
    dwarf_stream.uleb128(FP);
    dwarf_stream.uleb128(0);
  });

  // 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.

      // FP at FP+kSavedCallerPcSlotFromFp*kWordSize
      COMPILE_ASSERT(kSavedCallerFpSlotFromFp >= 0);
      dwarf_stream.u1(Dwarf::DW_CFA_offset | FP);
      dwarf_stream.uleb128(kSavedCallerFpSlotFromFp);

      // LR at FP+kSavedCallerPcSlotFromFp*kWordSize
      COMPILE_ASSERT(kSavedCallerPcSlotFromFp >= 0);
      dwarf_stream.u1(Dwarf::DW_CFA_offset | ConcreteRegister(LINK_REGISTER));
      dwarf_stream.uleb128(kSavedCallerPcSlotFromFp);

      // SP is FP+kCallerSpSlotFromFp*kWordSize
      COMPILE_ASSERT(kCallerSpSlotFromFp >= 0);
      dwarf_stream.u1(Dwarf::DW_CFA_val_offset);
#if defined(TARGET_ARCH_ARM64)
      dwarf_stream.uleb128(ConcreteRegister(CSP));
#elif defined(TARGET_ARCH_ARM)
      dwarf_stream.uleb128(SP);
#else
#error "Unsupported .eh_frame architecture"
#endif
      dwarf_stream.uleb128(kCallerSpSlotFromFp);
    });
  }

  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_ARM) || defined(TARGET_ARCH_ARM64)
}

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.

  // If a build ID was created, we put it 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.
  for (auto* const section : sections_) {
    if (section == build_id) continue;  // Already added.
    if (section->IsAllocated() && !section->IsWritable() &&
        !section->IsExecutable()) {
      add_to_reordered_sections(section);
    }
  }

  // Now add the executable sections in a new segment.
  for (auto* const section : sections_) {
    if (section->IsExecutable()) {  // Implies IsAllocated() && !IsWritable()
      add_to_reordered_sections(section);
    }
  }

  // Now add all the writable sections.
  for (auto* const section : sections_) {
    if (section->IsWritable()) {  // Implies IsAllocated() && !IsExecutable()
      add_to_reordered_sections(section);
    }
  }

  // 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.
  for (intptr_t i = 1; i < num_sections; i++) {
    auto* const section = sections_[i];
    if (section->IsAllocated()) continue;
    add_to_reordered_sections(section);
  }

  // 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);
#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
