// Copyright (c) 2017, 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/image_snapshot.h"

#include "include/dart_api.h"
#include "platform/assert.h"
#include "platform/elf.h"
#include "platform/mach_o.h"
#include "vm/bss_relocs.h"
#include "vm/class_id.h"
#include "vm/compiler/runtime_api.h"
#include "vm/dwarf.h"
#include "vm/elf.h"
#include "vm/hash.h"
#include "vm/hash_map.h"
#include "vm/heap/heap.h"
#include "vm/instructions.h"
#include "vm/json_writer.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/program_visitor.h"
#include "vm/stub_code.h"
#include "vm/timeline.h"
#include "vm/type_testing_stubs.h"
#include "vm/zone_text_buffer.h"

#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/backend/code_statistics.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

#if defined(DART_PRECOMPILER)
DEFINE_FLAG(bool,
            print_instruction_stats,
            false,
            "Print instruction statistics");

DEFINE_FLAG(charp,
            print_instructions_sizes_to,
            nullptr,
            "Print sizes of all instruction objects to the given file");
#endif

const UntaggedInstructionsSection* Image::ExtraInfo(const uword raw_memory,
                                                    const uword size) {
#if defined(DART_PRECOMPILED_RUNTIME)
  auto const raw_value =
      FieldValue(raw_memory, HeaderField::InstructionsSectionOffset);
  if (raw_value != kNoInstructionsSection) {
    ASSERT(raw_value >= kHeaderSize);
    ASSERT(raw_value <= size - InstructionsSection::HeaderSize());
    auto const layout = reinterpret_cast<const UntaggedInstructionsSection*>(
        raw_memory + raw_value);
    // The instructions section is likely non-empty in bare instructions mode
    // (unless splitting into multiple outputs and there are no Code objects
    // in this particular output), but is guaranteed empty otherwise (the
    // instructions follow the InstructionsSection object instead).
    ASSERT(raw_value <=
           size - InstructionsSection::InstanceSize(layout->payload_length_));
    return layout;
  }
#endif
  return nullptr;
}

uword* Image::bss() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  ASSERT(extra_info_ != nullptr);
  // There should always be a non-zero BSS offset.
  ASSERT(extra_info_->bss_offset_ != 0);
  // Returning a non-const uword* is safe because we're translating from
  // the start of the instructions (read-only) to the start of the BSS
  // (read-write).
  return reinterpret_cast<uword*>(raw_memory_ + extra_info_->bss_offset_);
#else
  return nullptr;
#endif
}

uword Image::instructions_relocated_address() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  ASSERT(extra_info_ != nullptr);
  return extra_info_->instructions_relocated_address_;
#else
  return kNoRelocatedAddress;
#endif
}

const void* Image::build_id_start() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  if (compiled_to_shared_object() &&
      extra_info_->build_id_offset_ != kNoBuildId) {
    return reinterpret_cast<const void*>(raw_memory_ +
                                         extra_info_->build_id_offset_);
  }
#endif
  return nullptr;
}

const uint8_t* Image::build_id() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  auto* const start = build_id_start();
  if (start == nullptr) return nullptr;
  if (compiled_to_elf()) {
    auto* const note = reinterpret_cast<const elf::Note*>(start);
    return note->data + note->name_size;
  } else if (compiled_to_macho()) {
    return reinterpret_cast<const mach_o::uuid_command*>(start)->uuid;
  }
#endif
  return nullptr;
}

intptr_t Image::build_id_length() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  ASSERT(extra_info_ != nullptr);
  auto* const start = build_id_start();
  if (start == nullptr) return 0;
  if (compiled_to_elf()) {
    auto const note = reinterpret_cast<const elf::Note*>(start);
    return note->description_size;
  } else if (compiled_to_macho()) {
    return sizeof(mach_o::uuid_command::uuid);
  }
#endif
  return 0;
}

bool Image::compiled_to_shared_object() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  ASSERT(extra_info_ != nullptr);
  // Since assembly snapshots can't set up this field correctly, it is used
  // to detect direct-to-shared-object snapshots.
  return extra_info_->instructions_relocated_address_ != kNoRelocatedAddress;
#else
  return false;
#endif
}

const uint8_t* Image::shared_object_start() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  if (compiled_to_shared_object()) {
    return reinterpret_cast<const uint8_t*>(
        raw_memory_ - extra_info_->instructions_relocated_address_);
  }
#endif
  return nullptr;
}

bool Image::compiled_to_elf() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  if (!compiled_to_shared_object()) return false;
  auto* const ident =
      reinterpret_cast<const elf::ElfHeader*>(shared_object_start())->ident;
  for (size_t i = 0; i < ARRAY_SIZE(elf::ELFMAG); ++i) {
    if (ident[i] != elf::ELFMAG[i]) return false;
  }
  return true;
#else
  return false;
#endif
}

bool Image::compiled_to_macho() const {
#if defined(DART_PRECOMPILED_RUNTIME)
  if (!compiled_to_shared_object()) return false;
  auto const magic =
      reinterpret_cast<const mach_o::mach_header*>(shared_object_start())
          ->magic;
  return magic == mach_o::MH_MAGIC || magic == mach_o::MH_CIGAM ||
         magic == mach_o::MH_MAGIC_64 || magic == mach_o::MH_CIGAM_64;
#else
  return false;
#endif
}

uword ObjectOffsetTrait::Hash(Key key) {
  ObjectPtr obj = key;
  ASSERT(!obj->IsSmi());

  uword body = UntaggedObject::ToAddr(obj) + sizeof(UntaggedObject);
  uword end = UntaggedObject::ToAddr(obj) + obj->untag()->HeapSize();

  uint32_t hash = obj->GetClassIdOfHeapObject();
  // Don't include the header. Objects in the image are pre-marked, but objects
  // in the current isolate are not.
  for (uword cursor = body; cursor < end; cursor += sizeof(uint32_t)) {
    hash = CombineHashes(hash, *reinterpret_cast<uint32_t*>(cursor));
  }

  return FinalizeHash(hash, 30);
}

bool ObjectOffsetTrait::IsKeyEqual(Pair pair, Key key) {
  ObjectPtr a = pair.object;
  ObjectPtr b = key;
  ASSERT(!a->IsSmi());
  ASSERT(!b->IsSmi());

  if (a->GetClassIdOfHeapObject() != b->GetClassIdOfHeapObject()) {
    return false;
  }

  intptr_t heap_size = a->untag()->HeapSize();
  if (b->untag()->HeapSize() != heap_size) {
    return false;
  }

  // Don't include the header. Objects in the image are pre-marked, but objects
  // in the current isolate are not.
  uword body_a = UntaggedObject::ToAddr(a) + sizeof(UntaggedObject);
  uword body_b = UntaggedObject::ToAddr(b) + sizeof(UntaggedObject);
  uword body_size = heap_size - sizeof(UntaggedObject);
  return 0 == memcmp(reinterpret_cast<const void*>(body_a),
                     reinterpret_cast<const void*>(body_b), body_size);
}

#if !defined(DART_PRECOMPILED_RUNTIME)
#if defined(DART_PRECOMPILER)
ImageWriter::ImageWriter(Thread* t,
                         bool generates_assembly,
                         bool needs_unique_names,
                         const Trie<const char>* deobfuscation_trie)
#else
ImageWriter::ImageWriter(Thread* t,
                         bool generates_assembly,
                         bool needs_unique_names)
#endif
    : thread_(ASSERT_NOTNULL(t)),
      zone_(t->zone()),
      next_data_offset_(0),
      next_text_offset_(0),
      objects_(),
      instructions_(),
#if defined(DART_PRECOMPILER)
      namer_(t->zone(),
             deobfuscation_trie,
             /*for_assembly=*/generates_assembly,
             /*create_unique_names=*/needs_unique_names),
#endif
      image_type_(TagObjectTypeAsReadOnly(zone_, "Image")),
      instructions_section_type_(
          TagObjectTypeAsReadOnly(zone_, "InstructionsSection")),
      instructions_type_(TagObjectTypeAsReadOnly(zone_, "Instructions")),
      trampoline_type_(TagObjectTypeAsReadOnly(zone_, "Trampoline")),
      padding_type_(TagObjectTypeAsReadOnly(zone_, "Padding")) {
  ResetOffsets();
}

void ImageWriter::PrepareForSerialization(
    GrowableArray<ImageWriterCommand>* commands) {
  if (commands != nullptr) {
    const intptr_t initial_offset = next_text_offset_;
    for (auto& inst : *commands) {
      ASSERT((initial_offset + inst.expected_offset) == next_text_offset_);
      switch (inst.op) {
        case ImageWriterCommand::InsertInstructionOfCode: {
          Heap* const heap = thread_->heap();
          CodePtr code = inst.insert_instruction_of_code.code;
          InstructionsPtr instructions = Code::InstructionsOf(code);
          const intptr_t offset = next_text_offset_;
          instructions_.Add(InstructionsData(instructions, code, offset));
          next_text_offset_ += SizeInSnapshot(instructions);
          ASSERT(heap->GetObjectId(instructions) == 0);
          heap->SetObjectId(instructions, offset);
          break;
        }
        case ImageWriterCommand::InsertBytesOfTrampoline: {
          auto trampoline_bytes = inst.insert_trampoline_bytes.buffer;
          auto trampoline_length = inst.insert_trampoline_bytes.buffer_length;
          const intptr_t offset = next_text_offset_;
          instructions_.Add(
              InstructionsData(trampoline_bytes, trampoline_length, offset));
          next_text_offset_ += trampoline_length;
          break;
        }
        case ImageWriterCommand::InsertPadding: {
          auto padding_length = inst.insert_padding.padding_length;
          const intptr_t offset = next_text_offset_;
          instructions_.Add(InstructionsData(nullptr, padding_length, offset));
          next_text_offset_ += padding_length;
          break;
        }
        default:
          UNREACHABLE();
      }
    }
  }
}

int32_t ImageWriter::GetTextOffsetFor(InstructionsPtr instructions,
                                      CodePtr code) {
  Heap* const heap = thread_->heap();
  intptr_t offset = heap->GetObjectId(instructions);
  if (offset != 0) {
    return offset;
  }

  offset = next_text_offset_;
  heap->SetObjectId(instructions, offset);
  next_text_offset_ += SizeInSnapshot(instructions);
  instructions_.Add(InstructionsData(instructions, code, offset));

  ASSERT(offset != 0);
  return offset;
}

intptr_t ImageWriter::SizeInSnapshotForBytes(intptr_t length) {
  // We are just going to write it out as a string.
  return compiler::target::String::InstanceSize(
      length * OneByteString::kBytesPerElement);
}

intptr_t ImageWriter::SizeInSnapshot(ObjectPtr raw_object) {
  const classid_t cid = raw_object->GetClassIdOfHeapObject();

  switch (cid) {
    case kCompressedStackMapsCid: {
      auto raw_maps = CompressedStackMaps::RawCast(raw_object);
      return compiler::target::CompressedStackMaps::InstanceSize(
          CompressedStackMaps::PayloadSizeOf(raw_maps));
    }
    case kCodeSourceMapCid: {
      auto raw_map = CodeSourceMap::RawCast(raw_object);
      return compiler::target::CodeSourceMap::InstanceSize(
          raw_map->untag()->length_);
    }
    case kPcDescriptorsCid: {
      auto raw_desc = PcDescriptors::RawCast(raw_object);
      return compiler::target::PcDescriptors::InstanceSize(
          raw_desc->untag()->length_);
    }
    case kInstructionsCid: {
      auto raw_insns = Instructions::RawCast(raw_object);
      return compiler::target::Instructions::InstanceSize(
          Instructions::Size(raw_insns));
    }
    case kOneByteStringCid: {
      auto raw_str = String::RawCast(raw_object);
      return compiler::target::String::InstanceSize(
          String::LengthOf(raw_str) * OneByteString::kBytesPerElement);
    }
    case kTwoByteStringCid: {
      auto raw_str = String::RawCast(raw_object);
      return compiler::target::String::InstanceSize(
          String::LengthOf(raw_str) * TwoByteString::kBytesPerElement);
    }
    default: {
      const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
      FATAL("Unsupported class %s in rodata section.\n", clazz.ToCString());
      return 0;
    }
  }
}

#if defined(SNAPSHOT_BACKTRACE)
uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object,
                                       ObjectPtr raw_parent) {
#else
uint32_t ImageWriter::GetDataOffsetFor(ObjectPtr raw_object) {
#endif
  const intptr_t snap_size = SizeInSnapshot(raw_object);
  const intptr_t offset = next_data_offset_;
  next_data_offset_ += snap_size;
#if defined(SNAPSHOT_BACKTRACE)
  objects_.Add(ObjectData(raw_object, raw_parent));
#else
  objects_.Add(ObjectData(raw_object));
#endif
  return offset;
}

uint32_t ImageWriter::AddBytesToData(uint8_t* bytes, intptr_t length) {
  const intptr_t snap_size = SizeInSnapshotForBytes(length);
  const intptr_t offset = next_data_offset_;
  next_data_offset_ += snap_size;
  objects_.Add(ObjectData(bytes, length));
  return offset;
}

intptr_t ImageWriter::GetTextObjectCount() const {
  return instructions_.length();
}

void ImageWriter::GetTrampolineInfo(intptr_t* count, intptr_t* size) const {
  ASSERT(count != nullptr && size != nullptr);
  *count = 0;
  *size = 0;
  for (auto const& data : instructions_) {
    if (data.trampoline_length != 0) {
      *count += 1;
      *size += data.trampoline_length;
    }
  }
}

// Returns nullptr if there is no profile writer.
const char* ImageWriter::ObjectTypeForProfile(const Object& object) const {
  if (profile_writer_ == nullptr) return nullptr;
  ASSERT(IsROSpace());
  REUSABLE_CLASS_HANDLESCOPE(thread_);
  REUSABLE_STRING_HANDLESCOPE(thread_);
  Class& klass = thread_->ClassHandle();
  String& name = thread_->StringHandle();
  klass = object.clazz();
  name = klass.UserVisibleName();
  auto const name_str = name.ToCString();
  return TagObjectTypeAsReadOnly(zone_, name_str);
}

const char* ImageWriter::TagObjectTypeAsReadOnly(Zone* zone, const char* type) {
  ASSERT(zone != nullptr && type != nullptr);
  return OS::SCreate(zone, "(RO) %s", type);
}

#if defined(DART_PRECOMPILER)
void ImageWriter::DumpInstructionStats() {
  std::unique_ptr<CombinedCodeStatistics> instruction_stats(
      new CombinedCodeStatistics());
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    CodeStatistics* stats = data.insns_->stats();
    if (stats != nullptr) {
      stats->AppendTo(instruction_stats.get());
    }
  }
  instruction_stats->DumpStatistics();
}

void ImageWriter::DumpInstructionsSizes() {
  auto& cls = Class::Handle(zone_);
  auto& lib = Library::Handle(zone_);
  auto& owner = Object::Handle(zone_);
  auto& url = String::Handle(zone_);
  auto& name = String::Handle(zone_);
  intptr_t trampolines_total_size = 0;

  JSONWriter js;
  js.OpenArray();
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    // We count alignment padding into trampolines for now.
    const bool is_trampoline = data.trampoline_length != 0;
    if (is_trampoline) {
      trampolines_total_size += data.trampoline_length;
      continue;
    }
    owner = WeakSerializationReference::Unwrap(data.code_->owner());
    js.OpenObject();
    if (owner.IsFunction()) {
      cls = Function::Cast(owner).Owner();
      name = cls.ScrubbedName();
      lib = cls.library();
      url = lib.url();
      js.PrintPropertyStr("l", url);
      js.PrintPropertyStr("c", name);
    } else if (owner.IsClass()) {
      cls ^= owner.ptr();
      name = cls.ScrubbedName();
      lib = cls.library();
      url = lib.url();
      js.PrintPropertyStr("l", url);
      js.PrintPropertyStr("c", name);
    }
    js.PrintProperty("n",
                     data.code_->QualifiedName(
                         NameFormattingParams::DisambiguatedWithoutClassName(
                             Object::kInternalName)));
    js.PrintProperty("s", SizeInSnapshot(data.insns_->ptr()));
    js.CloseObject();
  }
  if (trampolines_total_size != 0) {
    js.OpenObject();
    js.PrintProperty("n", "[Stub] Trampoline");
    js.PrintProperty("s", trampolines_total_size);
    js.CloseObject();
  }
  js.CloseArray();

  auto file_open = Dart::file_open_callback();
  auto file_write = Dart::file_write_callback();
  auto file_close = Dart::file_close_callback();
  if ((file_open == nullptr) || (file_write == nullptr) ||
      (file_close == nullptr)) {
    OS::PrintErr("warning: Could not access file callbacks.");
    return;
  }

  const char* filename = FLAG_print_instructions_sizes_to;
  void* file = file_open(filename, /*write=*/true);
  if (file == nullptr) {
    OS::PrintErr("warning: Failed to write instruction sizes: %s\n", filename);
    return;
  }

  char* output = nullptr;
  intptr_t output_length = 0;
  js.Steal(&output, &output_length);
  file_write(output, output_length, file);
  free(output);
  file_close(file);
}

void ImageWriter::DumpStatistics() {
  if (FLAG_print_instruction_stats) {
    DumpInstructionStats();
  }

  if (FLAG_print_instructions_sizes_to != nullptr) {
    DumpInstructionsSizes();
  }
}
#endif

void ImageWriter::Write(NonStreamingWriteStream* clustered_stream, bool vm) {
  Heap* heap = thread_->heap();
  TIMELINE_DURATION(thread_, Isolate, "WriteInstructions");

  // Handlify collected raw pointers as building the names below
  // will allocate on the Dart heap.
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    InstructionsData& data = instructions_[i];
    if (data.trampoline_length != 0) continue;

    data.insns_ = &Instructions::Handle(zone_, data.raw_insns_);
    ASSERT(data.raw_code_ != nullptr);
    data.code_ = &Code::Handle(zone_, data.raw_code_);

    // Reset object id as an isolate snapshot after a VM snapshot will not use
    // the VM snapshot's text image.
    heap->SetObjectId(data.insns_->ptr(), 0);
  }
  for (auto& data : objects_) {
    if (data.is_object()) {
      data.obj = &Object::Handle(zone_, data.raw_obj);
#if defined(SNAPSHOT_BACKTRACE)
      data.parent = &Object::Handle(zone_, data.raw_parent);
#endif
    }
  }

  // Once we have everything handlified we are going to do convert raw bytes
  // to string objects. String is used for simplicity as a bit container,
  // can't use TypedData because it has an internal pointer (data_) field.
  for (auto& data : objects_) {
    if (!data.is_object()) {
      const auto bytes = data.bytes;
      data.obj = &Object::Handle(
          zone_, OneByteString::New(bytes.buf, bytes.length, Heap::kOld));
#if defined(SNAPSHOT_BACKTRACE)
      data.parent = &Object::null_object();
#endif
      data.set_is_object(true);
      String::Cast(*data.obj).Hash();
      free(bytes.buf);
    }
  }

  WriteBss(vm);

  offset_space_ = vm ? IdSpace::kVmText : IdSpace::kIsolateText;
  WriteText(vm);

  // Append the direct-mapped RO data objects after the clustered snapshot
  // and then for shared object and assembly outputs, add appropriate sections
  // with that combined data.
  offset_space_ = vm ? IdSpace::kVmData : IdSpace::kIsolateData;
  WriteROData(clustered_stream, vm);
}

void ImageWriter::WriteROData(NonStreamingWriteStream* stream, bool vm) {
  ASSERT(Utils::IsAligned(stream->Position(), kRODataAlignment));
  // Heap page starts here.
  intptr_t section_start = stream->Position();

  stream->WriteWord(next_data_offset_);  // Data length.
  stream->WriteWord(Image::kNoInstructionsSection);
  // Zero values for the rest of the Image object header bytes.
  stream->Align(Image::kHeaderSize);
  ASSERT_EQUAL(stream->Position() - section_start, Image::kHeaderSize);
#if defined(DART_PRECOMPILER)
  if (profile_writer_ != nullptr) {
    // Attribute the Image header to the artificial root.
    profile_writer_->AttributeBytesTo(
        V8SnapshotProfileWriter::kArtificialRootId, Image::kHeaderSize);
  }
#endif

  // Heap page objects start here.

  for (auto entry : objects_) {
    ASSERT(entry.is_object());
    const Object& obj = *entry.obj;
#if defined(DART_PRECOMPILER)
    AutoTraceImage(obj, section_start, stream);
    const char* object_name = namer_.SnapshotNameFor(entry);
#endif
    auto const object_start = stream->Position();

    NoSafepointScope no_safepoint;

    // Write object header with the mark and read-only bits set.
    stream->WriteTargetWord(GetMarkedTags(obj));
    if (obj.IsCompressedStackMaps()) {
      const CompressedStackMaps& map = CompressedStackMaps::Cast(obj);
      const intptr_t payload_size = map.payload_size();
      stream->WriteFixed<uint32_t>(
          map.ptr()->untag()->payload()->flags_and_size());
      stream->WriteBytes(map.ptr()->untag()->payload()->data(), payload_size);
    } else if (obj.IsCodeSourceMap()) {
      const CodeSourceMap& map = CodeSourceMap::Cast(obj);
      stream->WriteTargetWord(map.Length());
      ASSERT_EQUAL(stream->Position() - object_start,
                   compiler::target::CodeSourceMap::HeaderSize());
      stream->WriteBytes(map.Data(), map.Length());
    } else if (obj.IsPcDescriptors()) {
      const PcDescriptors& desc = PcDescriptors::Cast(obj);
      stream->WriteTargetWord(desc.Length());
      ASSERT_EQUAL(stream->Position() - object_start,
                   compiler::target::PcDescriptors::HeaderSize());
      stream->WriteBytes(desc.ptr()->untag()->data(), desc.Length());
    } else if (obj.IsString()) {
      const String& str = String::Cast(obj);
      RELEASE_ASSERT(String::GetCachedHash(str.ptr()) != 0);
      RELEASE_ASSERT(str.IsOneByteString() || str.IsTwoByteString());

#if !defined(HASH_IN_OBJECT_HEADER)
      stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->hash()));
#endif
      stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->length()));
      ASSERT_EQUAL(stream->Position() - object_start,
                   compiler::target::String::InstanceSize());
      stream->WriteBytes(
          str.IsOneByteString()
              ? static_cast<const void*>(OneByteString::DataStart(str))
              : static_cast<const void*>(TwoByteString::DataStart(str)),
          str.Length() * (str.IsOneByteString()
                              ? OneByteString::kBytesPerElement
                              : TwoByteString::kBytesPerElement));
    } else {
      const Class& clazz = Class::Handle(obj.clazz());
      FATAL("Unsupported class %s in rodata section.\n", clazz.ToCString());
    }
    stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
    ASSERT_EQUAL(stream->Position() - object_start, SizeInSnapshot(obj));
#if defined(DART_PRECOMPILER)
    AddDataSymbol(object_name, object_start, stream->Position() - object_start);
#endif
  }
}

static constexpr uword kReadOnlyGCBits =
    UntaggedObject::AlwaysSetBit::encode(true) |
    UntaggedObject::NotMarkedBit::encode(false) |
    UntaggedObject::OldAndNotRememberedBit::encode(true) |
    UntaggedObject::NewOrEvacuationCandidateBit::encode(false);

uword ImageWriter::GetMarkedTags(classid_t cid,
                                 intptr_t size,
                                 bool is_canonical /* = false */,
                                 bool is_immutable /* = false */) {
  // UntaggedObject::SizeTag expects a size divisible by kObjectAlignment and
  // checks this in debug mode, but the size on the target machine may not be
  // divisible by the host machine's object alignment if they differ.
  //
  // We define [adjusted_size] as [size] * m, where m is the host alignment
  // divided by the target alignment. This means [adjusted_size] encodes on the
  // host machine to the same bits that decode to [size] on the target machine.
  // That is,
  //    [adjusted_size] / host align ==
  //    [size] * (host align / target align) / host align ==
  //    [size] / target align
  //
  // Since alignments are always powers of 2, we use shifts and logs.
  const intptr_t adjusted_size =
      size << (kObjectAlignmentLog2 -
               compiler::target::ObjectAlignment::kObjectAlignmentLog2);

  return kReadOnlyGCBits | UntaggedObject::ClassIdTag::encode(cid) |
         UntaggedObject::SizeTag::encode(adjusted_size) |
         UntaggedObject::CanonicalBit::encode(is_canonical) |
         UntaggedObject::ImmutableBit::encode(is_immutable);
}

uword ImageWriter::GetMarkedTags(const Object& obj) {
  uword tags =
      GetMarkedTags(obj.ptr()->untag()->GetClassId(), SizeInSnapshot(obj),
                    obj.IsCanonical(), obj.IsImmutable());
#if defined(HASH_IN_OBJECT_HEADER)
  tags = UntaggedObject::HashTag::update(obj.ptr()->untag()->GetHeaderHash(),
                                         tags);
#endif
  return tags;
}

const char* ImageWriter::SectionSymbol(ProgramSection section, bool vm) {
  switch (section) {
    case ProgramSection::Text:
      return vm ? kVmSnapshotInstructionsAsmSymbol
                : kIsolateSnapshotInstructionsAsmSymbol;
    case ProgramSection::Data:
      return vm ? kVmSnapshotDataAsmSymbol : kIsolateSnapshotDataAsmSymbol;
    case ProgramSection::Bss:
      return vm ? kVmSnapshotBssAsmSymbol : kIsolateSnapshotBssAsmSymbol;
    case ProgramSection::BuildId:
      return kSnapshotBuildIdAsmSymbol;
  }
  UNREACHABLE();
  return nullptr;
}

#if (defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)) &&    \
    defined(TARGET_ARCH_ARM64)
// When generating ARM64 Mach-O LLVM tends to generate Compact Unwind Info
// (__unwind_info) rather than traditional DWARF unwinding information
// (__eh_frame).
//
// Unfortunately when generating __unwind_info LLVM seems to only apply CFI
// rules to the region between two non-local symbols that contains these CFI
// directives. In other words given:
//
//   Abc:
//   .cfi_startproc
//   .cfi_def_cfa x29, 16
//   .cfi_offset x30, -8
//   .cfi_offset x29, -16
//   ;; ...
//   Xyz:
//   ;; ...
//   .cfi_endproc
//
// __unwind_info would specify proper unwinding information only for the region
// between Abc and Xyz symbols. And the region Xyz onwards will have no
// unwinding information.
//
// There also seems to be a difference in how unwinding information is
// canonicalized and compressed: when building __unwind_info from CFI directives
// LLVM will fold together similar entries, the same does not happen for
// __eh_frame. This means that emitting CFI directives for each function would
// balloon the size of __eh_frame.
//
// Hence to work around the problem of incorrect __unwind_info without
// ballooning snapshot size when __eh_frame is generated we choose to emit CFI
// directives per function specifically on ARM64 Mac OS X and iOS.
//
// See also |useCompactUnwind| method in LLVM (https://github.com/llvm/llvm-project/blob/b27430f9f46b88bcd54d992debc8d72e131e1bd0/llvm/lib/MC/MCObjectFileInfo.cpp#L28-L50)
#define EMIT_UNWIND_DIRECTIVES_PER_FUNCTION 1
#endif

void ImageWriter::WriteText(bool vm) {
  const bool bare_instruction_payloads = FLAG_precompiled_mode;

  // Start snapshot at page boundary.
  intptr_t alignment_padding = 0;
  if (!EnterSection(ProgramSection::Text, vm, ImageWriter::kTextAlignment,
                    &alignment_padding)) {
    return;
  }

  intptr_t text_offset = 0;
#if defined(DART_PRECOMPILER)
  // Parent used for later profile objects. Starts off as the Image. When
  // writing bare instructions payloads, this is later updated with the
  // InstructionsSection object which contains all the bare payloads.
  V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
#endif

  // This head also provides the gap to make the instructions snapshot
  // look like a Page.
  const intptr_t image_size = Utils::RoundUp(
      next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
  text_offset += WriteTargetWord(image_size);
  // Output the offset to the InstructionsSection object from the start of the
  // image, if any.
  text_offset +=
      WriteTargetWord(FLAG_precompiled_mode ? Image::kHeaderSize
                                            : Image::kNoInstructionsSection);
  // Zero values for the rest of the Image object header bytes.
  text_offset += Align(Image::kHeaderSize, 0, text_offset);
  ASSERT_EQUAL(text_offset, Image::kHeaderSize);

#if defined(DART_PRECOMPILER)
  const char* instructions_symbol = SectionSymbol(ProgramSection::Text, vm);
  ASSERT(instructions_symbol != nullptr);
  intptr_t instructions_label = SectionLabel(ProgramSection::Text, vm);
  ASSERT(instructions_label > 0);
  const char* bss_symbol = SectionSymbol(ProgramSection::Bss, vm);
  ASSERT(bss_symbol != nullptr);
  intptr_t bss_label = SectionLabel(ProgramSection::Bss, vm);
  ASSERT(bss_label > 0);

  if (profile_writer_ != nullptr) {
    profile_writer_->SetObjectTypeAndName(parent_id, image_type_,
                                          instructions_symbol);
    profile_writer_->AttributeBytesTo(
        parent_id, ImageWriter::kTextAlignment + alignment_padding);
    profile_writer_->AddRoot(parent_id);
  }

  if (FLAG_precompiled_mode) {
    const intptr_t section_header_length =
        compiler::target::InstructionsSection::HeaderSize();
    // Calculated using next_text_offset_, which doesn't include post-payload
    // padding to object alignment. Note that if not in bare instructions mode,
    // the section has no contents, instead the instructions objects follow it.
    const intptr_t section_payload_length =
        bare_instruction_payloads
            ? next_text_offset_ - text_offset - section_header_length
            : 0;
    const intptr_t section_size =
        compiler::target::InstructionsSection::InstanceSize(
            section_payload_length);

    const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
    if (profile_writer_ != nullptr) {
      profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
                                            instructions_symbol);
      profile_writer_->AttributeBytesTo(id,
                                        section_size - section_payload_length);
      const intptr_t element_offset = id.nonce() - parent_id.nonce();
      profile_writer_->AttributeReferenceTo(
          parent_id,
          V8SnapshotProfileWriter::Reference::Element(element_offset), id);
      // Later objects will have the InstructionsSection as a parent if in
      // bare instructions mode, otherwise the image.
      if (bare_instruction_payloads) {
        parent_id = id;
      }
    }

    // Add the RawInstructionsSection header.
    text_offset +=
        WriteTargetWord(GetMarkedTags(kInstructionsSectionCid, section_size));
    // An InstructionsSection has five fields:
    // 1) The length of the payload.
    text_offset += WriteTargetWord(section_payload_length);
    // 2) The BSS offset from this section.
    text_offset += Relocation(text_offset, instructions_label, bss_label);
    // 3) The relocated address of the instructions.
    text_offset += RelocatedAddress(text_offset, instructions_label);
    // 4) The GNU build ID note offset from this section.
    text_offset += Relocation(text_offset, instructions_label,
                              SectionLabel(ProgramSection::BuildId, vm));

    const intptr_t section_contents_alignment =
        bare_instruction_payloads
            ? InstructionsSection::kPayloadAlignment
            : compiler::target::ObjectAlignment::kObjectAlignment;
    const intptr_t alignment_offset =
        compiler::target::ObjectAlignment::kOldObjectAlignmentOffset;
    const intptr_t expected_size =
        bare_instruction_payloads
            ? compiler::target::InstructionsSection::HeaderSize()
            : compiler::target::InstructionsSection::InstanceSize(0);
    text_offset +=
        Align(section_contents_alignment, alignment_offset, text_offset);
    ASSERT_EQUAL(text_offset - id.nonce(), expected_size);
  }
#endif

#if !defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
  FrameUnwindPrologue();
#endif

#if defined(DART_PRECOMPILER)
  PcDescriptors& descriptors = PcDescriptors::Handle(zone_);
#endif

  // We don't expect more than 64 bytes of padding.
  uint8_t padding_bytes[64];
  memset(&padding_bytes[0], 0, sizeof(padding_bytes));

  ASSERT(offset_space_ != IdSpace::kSnapshot);
  for (intptr_t i = 0; i < instructions_.length(); i++) {
    auto& data = instructions_[i];
    const bool is_trampoline = data.trampoline_bytes != nullptr;
    const bool is_padding =
        data.trampoline_bytes == nullptr && data.trampoline_length != 0;
    ASSERT_EQUAL(data.text_offset_, text_offset);

#if defined(DART_PRECOMPILER)
    const char* object_name = namer_.SnapshotNameFor(data);

    if (profile_writer_ != nullptr) {
      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
      auto const type = is_trampoline ? trampoline_type_
                        : is_padding  ? padding_type_
                                      : instructions_type_;
      const intptr_t size = (is_trampoline || is_padding)
                                ? data.trampoline_length
                                : SizeInSnapshot(data.insns_->ptr());
      profile_writer_->SetObjectTypeAndName(id, type, object_name);
      profile_writer_->AttributeBytesTo(id, size);
      const intptr_t element_offset = id.nonce() - parent_id.nonce();
      profile_writer_->AttributeReferenceTo(
          parent_id,
          V8SnapshotProfileWriter::Reference::Element(element_offset), id);
    }
#endif

    if (is_trampoline) {
      text_offset += WriteBytes(data.trampoline_bytes, data.trampoline_length);
      delete[] data.trampoline_bytes;
      data.trampoline_bytes = nullptr;
      continue;
    }

    if (is_padding) {
      text_offset += WriteBytes(padding_bytes, data.trampoline_length);
      continue;
    }

    const intptr_t instr_start = text_offset;
    const auto& insns = *data.insns_;

    // 1. Write from the object start to the payload start. This includes the
    // object header and the fixed fields.  Not written for AOT snapshots using
    // bare instructions.
    if (!bare_instruction_payloads) {
      NoSafepointScope no_safepoint;

      // Write Instructions with the mark and read-only bits set.
      text_offset += WriteTargetWord(GetMarkedTags(insns));
      text_offset += WriteFixed(insns.untag()->size_and_flags_);
      text_offset +=
          Align(compiler::target::Instructions::kNonBarePayloadAlignment,
                compiler::target::ObjectAlignment::kOldObjectAlignmentOffset,
                text_offset);
    }

    ASSERT_EQUAL(text_offset - instr_start,
                 compiler::target::Instructions::HeaderSize());

#if defined(DART_PRECOMPILER)
    const auto& code = *data.code_;
    // 2. Add a symbol for the code at the entry point in precompiled snapshots.
    // Linux's perf uses these labels.
    AddCodeSymbol(code, object_name, text_offset);
#endif

#if defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
    FrameUnwindPrologue();
#endif

    {
      NoSafepointScope no_safepoint;

      // 3. Write from the payload start to payload end. For AOT snapshots
      // with bare instructions, this is the only part serialized other than
      // any padding needed for alignment.
      auto const payload_start =
          reinterpret_cast<const uint8_t*>(insns.PayloadStart());
      // Double-check the payload alignment, since we will load and write
      // target-sized words starting from that address.
      ASSERT(Utils::IsAligned(payload_start, compiler::target::kWordSize));
      const uword payload_size = insns.Size();
      auto const payload_end = payload_start + payload_size;
      auto cursor = payload_start;
#if defined(DART_PRECOMPILER)
      descriptors = code.pc_descriptors();
      PcDescriptors::Iterator iterator(
          descriptors, /*kind_mask=*/UntaggedPcDescriptors::kBSSRelocation);
      while (iterator.MoveNext()) {
        // We only generate BSS relocations in the precompiler.
        ASSERT(FLAG_precompiled_mode);
        auto const next_reloc_offset = iterator.PcOffset();
        auto const next_reloc_address = payload_start + next_reloc_offset;
        // We only generate BSS relocations that are target word-sized and at
        // target word-aligned offsets in the payload. Double-check this.
        ASSERT(
            Utils::IsAligned(next_reloc_address, compiler::target::kWordSize));
        text_offset += WriteBytes(cursor, next_reloc_address - cursor);

        // The instruction stream at the relocation position holds the target
        // offset into the BSS section.
        const auto target_offset =
            *reinterpret_cast<const compiler::target::word*>(
                next_reloc_address);
        text_offset += Relocation(text_offset, instructions_label, text_offset,
                                  bss_label, target_offset);
        cursor = next_reloc_address + compiler::target::kWordSize;
      }
#endif
      text_offset += WriteBytes(cursor, payload_end - cursor);
    }

    // 4. Add appropriate padding. Note we can't simply copy from the object
    // because the host object may have less alignment filler than the target
    // object in the cross-word case.
    const intptr_t alignment =
        bare_instruction_payloads
            ? compiler::target::Instructions::kBarePayloadAlignment
            : compiler::target::ObjectAlignment::kObjectAlignment;
    text_offset += AlignWithBreakInstructions(alignment, text_offset);

    ASSERT_EQUAL(text_offset - instr_start, SizeInSnapshot(insns.ptr()));
#if defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
    FrameUnwindEpilogue();
#endif
  }

  // Should be a no-op unless writing bare instruction payloads, in which case
  // we need to add post-payload padding for the InstructionsSection object.
  // Since this follows instructions, we'll use break instructions for padding.
  ASSERT(bare_instruction_payloads ||
         Utils::IsAligned(text_offset,
                          compiler::target::ObjectAlignment::kObjectAlignment));
  text_offset += AlignWithBreakInstructions(
      compiler::target::ObjectAlignment::kObjectAlignment, text_offset);

  ASSERT_EQUAL(text_offset, image_size);

#if !defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
  FrameUnwindEpilogue();
#endif

  ExitSection(ProgramSection::Text, vm, text_offset);
}

intptr_t ImageWriter::AlignWithBreakInstructions(intptr_t alignment,
                                                 intptr_t offset) {
  intptr_t bytes_written = 0;
  uword remaining;
  for (remaining = Utils::RoundUp(offset, alignment) - offset;
       remaining >= compiler::target::kWordSize;
       remaining -= compiler::target::kWordSize) {
    bytes_written += WriteTargetWord(kBreakInstructionFiller);
  }
  // clang-format off
#if defined(TARGET_ARCH_ARM)
  // All instructions are 4 bytes long on ARM architectures, so on 32-bit ARM
  // there won't be any padding.
  ASSERT_EQUAL(remaining, 0);
#elif defined(TARGET_ARCH_ARM64)
  // All instructions are 4 bytes long on ARM architectures, so on 64-bit ARM
  // there is only 0 or 4 bytes of padding.
  if (remaining != 0) {
    ASSERT_EQUAL(remaining, 4);
    bytes_written += WriteBytes(&kBreakInstructionFiller, remaining);
  }
#elif defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) ||                 \
    defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
  // The break instruction is a single byte, repeated to fill a word.
  bytes_written += WriteBytes(&kBreakInstructionFiller, remaining);
#else
#error Unexpected architecture.
#endif
  // clang-format on
  ASSERT_EQUAL(bytes_written, Utils::RoundUp(offset, alignment) - offset);
  return bytes_written;
}

#if defined(DART_PRECOMPILER)

// Indices are log2(size in bytes).
static constexpr const char* kSizeDirectives[] = {".byte", ".2byte", ".long",
                                                  ".quad"};

static constexpr const char* kWordDirective =
    kSizeDirectives[compiler::target::kWordSizeLog2];

class DwarfAssemblyStream : public DwarfWriteStream {
 public:
  explicit DwarfAssemblyStream(Zone* zone,
                               BaseWriteStream* stream,
                               const IntMap<const char*>& label_to_name)
      : zone_(ASSERT_NOTNULL(zone)),
        stream_(ASSERT_NOTNULL(stream)),
        label_to_name_(label_to_name) {}

  void sleb128(intptr_t value) override {
    stream_->Printf(".sleb128 %" Pd "\n", value);
  }
  void uleb128(uintptr_t value) override {
    stream_->Printf(".uleb128 %" Pd "\n", value);
  }
  void u1(uint8_t value) override {
    stream_->Printf("%s %u\n", kSizeDirectives[kInt8SizeLog2], value);
  }
  void u2(uint16_t value) override {
    stream_->Printf("%s %u\n", kSizeDirectives[kInt16SizeLog2], value);
  }
  void u4(uint32_t value) override {
    stream_->Printf("%s %" Pu32 "\n", kSizeDirectives[kInt32SizeLog2], value);
  }
  void u8(uint64_t value) override {
    stream_->Printf("%s %" Pu64 "\n", kSizeDirectives[kInt64SizeLog2], value);
  }
  void string(const char* cstr) override {  // NOLINT
    stream_->WriteString(".string \"");     // NOLINT
    while (char c = *cstr++) {
      if (c == '"') {
        stream_->WriteString("\\\"");
      } else if (c == '\\') {
        stream_->WriteString("\\\\");
      } else if (c == '\n') {
        stream_->WriteString("\\n");
      } else if (c == '\r') {
        stream_->WriteString("\\r");
      } else {
        stream_->WriteByte(c);
      }
    }
    stream_->WriteString("\"\n");
  }
  void WritePrefixedLength(const char* prefix,
                           std::function<void()> body) override {
    ASSERT(prefix != nullptr);
    const char* const length_prefix_symbol =
        OS::SCreate(zone_, ".L%s_length_prefix", prefix);
    // Assignment to temp works around buggy Mac assembler.
    stream_->Printf("L%s_size = .L%s_end - .L%s_start\n", prefix, prefix,
                    prefix);
    // We assume DWARF v2 currently, so all sizes are 32-bit.
    stream_->Printf("%s: %s L%s_size\n", length_prefix_symbol,
                    kSizeDirectives[kInt32SizeLog2], prefix);
    // All sizes for DWARF sections measure the size of the section data _after_
    // the size value.
    stream_->Printf(".L%s_start:\n", prefix);
    body();
    stream_->Printf(".L%s_end:\n", prefix);
  }
  void OffsetFromSymbol(intptr_t label,
                        intptr_t offset,
                        size_t size = kAddressSize) override {
    const char* symbol = label_to_name_.Lookup(label);
    ASSERT(symbol != nullptr);
    if (offset == 0) {
      PrintNamedAddress(symbol, size);
    } else {
      PrintNamedAddressWithOffset(symbol, offset, size);
    }
  }

  // No-op, we'll be using labels.
  void InitializeAbstractOrigins(intptr_t size) override {}
  void RegisterAbstractOrigin(intptr_t index) override {
    // Label for DW_AT_abstract_origin references
    stream_->Printf("Lfunc%" Pd " = .-%s\n", index, kDebugInfoLabel);
  }
  void AbstractOrigin(intptr_t index) override {
    stream_->Printf("%s Lfunc%" Pd "\n", kSizeDirectives[kInt32SizeLog2],
                    index);
  }

  // Methods for writing the assembly prologues for various DWARF sections.
  void AbbreviationsPrologue() {
#if defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
    stream_->WriteString(".section __DWARF,__debug_abbrev,regular,debug\n");
#elif defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||      \
    defined(DART_TARGET_OS_FUCHSIA)
    stream_->WriteString(".section .debug_abbrev,\"\"\n");
#else
    UNIMPLEMENTED();
#endif
  }
  void DebugInfoPrologue() {
#if defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
    stream_->WriteString(".section __DWARF,__debug_info,regular,debug\n");
#elif defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||      \
    defined(DART_TARGET_OS_FUCHSIA)
    stream_->WriteString(".section .debug_info,\"\"\n");
#else
    UNIMPLEMENTED();
#endif
    // Used to calculate abstract origin values.
    stream_->Printf("%s:\n", kDebugInfoLabel);
  }
  void LineNumberProgramPrologue() {
#if defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
    stream_->WriteString(".section __DWARF,__debug_line,regular,debug\n");
#elif defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||      \
    defined(DART_TARGET_OS_FUCHSIA)
    stream_->WriteString(".section .debug_line,\"\"\n");
#else
    UNIMPLEMENTED();
#endif
  }

 private:
  static constexpr const char* kDebugInfoLabel = ".Ldebug_info";

  void PrintNamedAddress(const char* name, size_t size) {
    auto* const directive = kSizeDirectives[Utils::ShiftForPowerOfTwo(size)];
    stream_->Printf("%s \"%s\"\n", directive, name);
  }
  void PrintNamedAddressWithOffset(const char* name,
                                   intptr_t offset,
                                   size_t size) {
    auto* const directive = kSizeDirectives[Utils::ShiftForPowerOfTwo(size)];
    stream_->Printf("%s \"%s\" + %" Pd "\n", directive, name, offset);
  }

  Zone* const zone_;
  BaseWriteStream* const stream_;
  const IntMap<const char*>& label_to_name_;
  intptr_t temp_ = 0;

  DISALLOW_COPY_AND_ASSIGN(DwarfAssemblyStream);
};

static inline Dwarf* AddDwarfIfUnstripped(
    Zone* zone,
    bool strip,
    SharedObjectWriter* writer,
    const Trie<const char>* deobfuscation_trie) {
#if defined(DART_TARGET_OS_WINDOWS)
  // PE uses PDB instead of DWARF.
  return nullptr;
#else
  if (!strip) {
    if (writer != nullptr) {
      // Reuse the existing DWARF object.
      ASSERT(writer->dwarf() != nullptr);
      return writer->dwarf();
    }
    return new (zone) Dwarf(zone, deobfuscation_trie);
  }
  return nullptr;
#endif
}

AssemblyImageWriter::AssemblyImageWriter(
    Thread* thread,
    BaseWriteStream* stream,
    const Trie<const char>* deobfuscation_trie,
    bool strip,
    SharedObjectWriter* debug_so)
    : ImageWriter(thread,
                  /*generates_assembly=*/true,
                  /*needs_unique_names=*/true,
                  deobfuscation_trie),
      assembly_stream_(stream),
      assembly_dwarf_(
          AddDwarfIfUnstripped(zone_, strip, debug_so, deobfuscation_trie)),
      debug_so_(debug_so),
      label_to_symbol_name_(zone_) {
  // Set up the label mappings for the section symbols for use in relocations.
  for (intptr_t i = 0; i < kNumProgramSections; i++) {
    auto const section = static_cast<ProgramSection>(i);

    auto const vm_name = SectionSymbol(section, /*vm=*/true);
    auto const vm_label = SectionLabel(section, /*vm=*/true);
    label_to_symbol_name_.Insert(vm_label, vm_name);

    auto const isolate_name = SectionSymbol(section, /*vm=*/false);
    auto const isolate_label = SectionLabel(section, /*vm=*/false);
    if (vm_label != isolate_label) {
      label_to_symbol_name_.Insert(isolate_label, isolate_name);
    } else {
      // Make sure the names also match.
      ASSERT_EQUAL(strcmp(vm_name, isolate_name), 0);
    }
  }
}

void AssemblyImageWriter::Finalize() {
  if (assembly_dwarf_ != nullptr) {
    DwarfAssemblyStream dwarf_stream(zone_, assembly_stream_,
                                     label_to_symbol_name_);
    dwarf_stream.AbbreviationsPrologue();
    assembly_dwarf_->WriteAbbreviations(&dwarf_stream);
    dwarf_stream.DebugInfoPrologue();
    assembly_dwarf_->WriteDebugInfo(&dwarf_stream);
    dwarf_stream.LineNumberProgramPrologue();
    assembly_dwarf_->WriteLineNumberProgram(&dwarf_stream);
  }
  if (debug_so_ != nullptr) {
    TIMELINE_DURATION(thread_, Isolate, "FinalizeDebugInfo");
    debug_so_->Finalize();
  }

#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
    defined(DART_TARGET_OS_FUCHSIA)
  // Non-executable stack.
#if defined(TARGET_ARCH_ARM)
  assembly_stream_->WriteString(".section .note.GNU-stack,\"\",%progbits\n");
#else
  assembly_stream_->WriteString(".section .note.GNU-stack,\"\",@progbits\n");
#endif
#endif

#if defined(DART_TARGET_OS_WINDOWS)
  // __declspec(dllexport)
  const char* const exported_symbols[] = {
      kVmSnapshotDataCSymbol,
      kVmSnapshotInstructionsCSymbol,
      kIsolateSnapshotDataCSymbol,
      kIsolateSnapshotInstructionsCSymbol,
  };
  assembly_stream_->WriteString(".section .drectve,\"yni\"\n");
  assembly_stream_->WriteString(".ascii \"");
  for (const char* exported_symbol : exported_symbols) {
    assembly_stream_->WriteString(" /EXPORT:");
    assembly_stream_->WriteString(exported_symbol);
  }
  assembly_stream_->WriteString("\"\n");
#endif
}

void ImageWriter::SnapshotTextObjectNamer::AddNonUniqueNameFor(
    BaseTextBuffer* buffer,
    const Object& object) {
  if (object.IsCode()) {
    const Code& code = Code::Cast(object);
    if (code.IsStubCode()) {
      buffer->AddString("stub ");
      insns_ = code.instructions();
      const char* name = StubCode::NameOfStub(insns_.EntryPoint());
      ASSERT(name != nullptr);
      buffer->AddString(name);
    } else {
      if (code.IsAllocationStubCode()) {
        buffer->AddString("new ");
      } else if (code.IsTypeTestStubCode()) {
        buffer->AddString("assert type is ");
      } else {
        ASSERT(code.IsFunctionCode());
      }
      owner_ = code.owner();
      AddNonUniqueNameFor(buffer, owner_);
    }
  } else if (object.IsClass()) {
    const char* name = Class::Cast(object).UserVisibleNameCString();
    const char* deobfuscated_name =
        ImageWriter::Deobfuscate(zone_, deobfuscation_trie_, name);
    buffer->AddString(deobfuscated_name);
  } else if (object.IsAbstractType()) {
    const AbstractType& type = AbstractType::Cast(object);
    if (deobfuscation_trie_ == nullptr) {
      // Print directly to the output buffer.
      type.PrintName(Object::kUserVisibleName, buffer);
    } else {
      // Use an intermediate buffer for deobfuscation purposes.
      ZoneTextBuffer temp_buffer(zone_);
      type.PrintName(Object::kUserVisibleName, &temp_buffer);
      const char* deobfuscated_name = ImageWriter::Deobfuscate(
          zone_, deobfuscation_trie_, temp_buffer.buffer());
      buffer->AddString(deobfuscated_name);
    }
  } else if (object.IsFunction()) {
    const Function& func = Function::Cast(object);
    NameFormattingParams params(
        {Object::kUserVisibleName, Object::NameDisambiguation::kNo});
    if (deobfuscation_trie_ == nullptr) {
      // Print directly to the output buffer.
      func.PrintName(params, buffer);
    } else {
      // Use an intermediate buffer for deobfuscation purposes.
      ZoneTextBuffer temp_buffer(zone_);
      func.PrintName(params, &temp_buffer);
      const char* deobfuscated_name = ImageWriter::Deobfuscate(
          zone_, deobfuscation_trie_, temp_buffer.buffer());
      buffer->AddString(deobfuscated_name);
    }
  } else if (object.IsCompressedStackMaps()) {
    buffer->AddString("CompressedStackMaps");
  } else if (object.IsPcDescriptors()) {
    buffer->AddString("PcDescriptors");
  } else if (object.IsCodeSourceMap()) {
    buffer->AddString("CodeSourceMap");
  } else if (object.IsString()) {
    const String& str = String::Cast(object);
    if (str.IsOneByteString()) {
      buffer->AddString("OneByteString");
    } else if (str.IsTwoByteString()) {
      buffer->AddString("TwoByteString");
    }
  } else {
    UNREACHABLE();
  }
}

void ImageWriter::SnapshotTextObjectNamer::ModifyForAssembly(
    BaseTextBuffer* buffer) {
  if (buffer->buffer()[0] == 'L') {
    // Assembler treats labels starting with `L` as local which can cause
    // some issues down the line e.g. on Mac the linker might fail to encode
    // compact unwind information because multiple functions end up being
    // treated as a single function. See https://github.com/flutter/flutter/issues/102281.
    //
    // Avoid this by prepending an underscore.
    auto* const result = OS::SCreate(zone_, "_%s", buffer->buffer());
    buffer->Clear();
    buffer->AddString(result);
  }
}

void ImageWriter::SnapshotTextObjectNamer::EnsureUniqueName(
    BaseTextBuffer* buffer) {
  auto* const pair = usage_count_.Lookup(buffer->buffer());
  if (pair == nullptr) {
    usage_count_.Insert({buffer->buffer(), 1});
  } else {
    buffer->Printf(" (#%" Pd ")", ++pair->value);
  }
}

const char* ImageWriter::SnapshotTextObjectNamer::SnapshotNameFor(
    const InstructionsData& data) {
  ZoneTextBuffer printer(zone_);
  if (data.trampoline_bytes != nullptr) {
    printer.AddString("Trampoline");
  } else if (data.trampoline_length != 0) {
    printer.AddString("Padding");
  } else {
    AddNonUniqueNameFor(&printer, *data.code_);
  }
  if (for_assembly_) {
    ModifyForAssembly(&printer);
  }
  if (create_unique_names_) {
    EnsureUniqueName(&printer);
  }
  return printer.buffer();
}

const char* ImageWriter::SnapshotTextObjectNamer::SnapshotNameFor(
    const ObjectData& data) {
  ASSERT(data.is_object());
  ZoneTextBuffer printer(zone_);
  if (data.is_original_object()) {
    const Object& obj = *data.obj;
    AddNonUniqueNameFor(&printer, obj);
#if defined(SNAPSHOT_BACKTRACE)
    // It's less useful knowing the parent of a String than other read-only
    // data objects, and this avoids us having to handle other classes
    // in AddNonUniqueNameFor.
    if (!obj.IsString()) {
      const Object& parent = *data.parent;
      if (!parent.IsNull()) {
        printer.AddString(" (");
        AddNonUniqueNameFor(&printer, parent);
        printer.AddString(")");
      }
    }
#endif
  } else {
    printer.AddString("RawBytes");
  }
  if (for_assembly_) {
    ModifyForAssembly(&printer);
  }
  if (create_unique_names_) {
    EnsureUniqueName(&printer);
  }
  return printer.buffer();
}

Trie<const char>* ImageWriter::CreateReverseObfuscationTrie(Thread* thread) {
  auto* const zone = thread->zone();
  auto* const map_array = thread->isolate_group()->obfuscation_map();
  if (map_array == nullptr) return nullptr;

  Trie<const char>* trie = nullptr;
  for (intptr_t i = 0; map_array[i] != nullptr; i += 2) {
    auto const key = map_array[i];
    auto const value = map_array[i + 1];
    ASSERT(value != nullptr);
    // Don't include identity mappings.
    if (strcmp(key, value) == 0) continue;
    // Otherwise, any value in the obfuscation map should be a valid key.
    ASSERT(Trie<const char>::IsValidKey(value));
    trie = Trie<const char>::AddString(zone, trie, value, key);
  }
  return trie;
}

const char* ImageWriter::Deobfuscate(Zone* zone,
                                     const Trie<const char>* trie,
                                     const char* cstr) {
  if (trie == nullptr) return cstr;
  TextBuffer buffer(256);
  // Used to avoid Zone-allocating strings if no deobfuscation was performed.
  bool changed = false;
  intptr_t i = 0;
  while (cstr[i] != '\0') {
    intptr_t offset;
    auto const value = trie->Lookup(cstr + i, &offset);
    if (offset == 0) {
      // The first character was an invalid key element (that isn't the null
      // terminator due to the while condition), copy it and skip to the next.
      buffer.AddChar(cstr[i++]);
    } else if (value != nullptr) {
      changed = true;
      buffer.AddString(value);
    } else {
      buffer.AddRaw(reinterpret_cast<const uint8_t*>(cstr + i), offset);
    }
    i += offset;
  }
  if (!changed) return cstr;
  return OS::SCreate(zone, "%s", buffer.buffer());
}

void AssemblyImageWriter::WriteBss(bool vm) {
  EnterSection(ProgramSection::Bss, vm, ImageWriter::kBssAlignment);
  auto const entry_count =
      vm ? BSS::kVmEntryCount : BSS::kIsolateGroupEntryCount;
  for (intptr_t i = 0; i < entry_count; i++) {
    // All bytes in the .bss section must be zero.
    WriteTargetWord(0);
  }
  ExitSection(ProgramSection::Bss, vm,
              entry_count * compiler::target::kWordSize);
}

void AssemblyImageWriter::WriteROData(NonStreamingWriteStream* clustered_stream,
                                      bool vm) {
  if (!EnterSection(ProgramSection::Data, vm, ImageWriter::kRODataAlignment)) {
    return;
  }
  // The clustered stream already has some data on it from the serializer, so
  // make sure that the read-only objects start at the appropriate alignment
  // within the stream, as we'll write the entire clustered stream to the
  // assembly output (which was aligned in EnterSection).
  const intptr_t start_position = clustered_stream->Position();
  clustered_stream->Align(ImageWriter::kRODataAlignment);
  if (profile_writer_ != nullptr) {
    // Attribute any padding needed to the artificial root.
    const intptr_t padding = clustered_stream->Position() - start_position;
    profile_writer_->AttributeBytesTo(
        V8SnapshotProfileWriter::kArtificialRootId, padding);
  }
  // First write the read-only data objects to the clustered stream.
  ImageWriter::WriteROData(clustered_stream, vm);
  // Next, write the bytes of the clustered stream (along with any symbols
  // if appropriate) to the assembly output.
  const uint8_t* bytes = clustered_stream->buffer();
  const intptr_t len = clustered_stream->bytes_written();
  intptr_t last_position = 0;
  for (const auto& symbol : *current_symbols_) {
    WriteBytes(bytes + last_position, symbol.offset - last_position);
    assembly_stream_->Printf("\"%s\":\n", symbol.name);
#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
    defined(DART_TARGET_OS_FUCHSIA)
    // Output size and type of the read-only data symbol to the assembly stream.
    assembly_stream_->Printf(".size \"%s\", %zu\n", symbol.name, symbol.size);
    assembly_stream_->Printf(".type \"%s\", %%object\n", symbol.name);
#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
    // MachO symbol tables don't include the size of the symbol, so don't bother
    // printing it to the assembly output.
#elif defined(DART_TARGET_OS_WINDOWS)
    // Windows also doesn't have a .size directive.
#else
    UNIMPLEMENTED();
#endif
    last_position = symbol.offset;
  }
  WriteBytes(bytes + last_position, len - last_position);
  ExitSection(ProgramSection::Data, vm, len);
}

bool AssemblyImageWriter::EnterSection(ProgramSection section,
                                       bool vm,
                                       intptr_t alignment,
                                       intptr_t* alignment_padding) {
  ASSERT(FLAG_precompiled_mode);
  ASSERT(current_symbols_ == nullptr);
  bool global_symbol = false;
  switch (section) {
    case ProgramSection::Text:
      if (debug_so_ != nullptr) {
        current_symbols_ =
            new (zone_) SharedObjectWriter::SymbolDataArray(zone_, 0);
      }
      assembly_stream_->WriteString(".text\n");
      global_symbol = true;
      break;
    case ProgramSection::Data:
      // We create a SymbolData array even if there is no debug_so_ because we
      // may be writing RO data symbols, and RO data is written in two steps:
      // 1. Serializing the read-only data objects to the clustered stream
      // 2. Writing the bytes of the clustered stream to the assembly output.
      // Thus, we'll need to interleave the symbols with the cluster bytes
      // during step 2.
      current_symbols_ =
          new (zone_) SharedObjectWriter::SymbolDataArray(zone_, 0);
#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
    defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_WINDOWS)
      assembly_stream_->WriteString(".section .rodata\n");
#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
      assembly_stream_->WriteString(".const\n");
#else
      UNIMPLEMENTED();
#endif
      global_symbol = true;
      break;
    case ProgramSection::Bss:
      assembly_stream_->WriteString(".bss\n");
      break;
    case ProgramSection::BuildId:
      break;
  }
  current_section_label_ = SectionLabel(section, vm);
  ASSERT(current_section_label_ > 0);
  if (global_symbol) {
    assembly_stream_->Printf(".globl %s\n", SectionSymbol(section, vm));
  }
  intptr_t padding = Align(alignment, 0, 0);
  if (alignment_padding != nullptr) {
    *alignment_padding = padding;
  }
  assembly_stream_->Printf("%s:\n", SectionSymbol(section, vm));
  return true;
}

static void AddSharedObjectSection(
    SharedObjectWriter* writer,
    ImageWriter::ProgramSection section,
    const char* symbol,
    intptr_t label,
    uint8_t* bytes,
    intptr_t size,
    SharedObjectWriter::SymbolDataArray* symbols,
    SharedObjectWriter::RelocationArray* relocations = nullptr) {
  if (writer == nullptr) return;
  switch (section) {
    case ImageWriter::ProgramSection::Text:
      writer->AddText(symbol, label, bytes, size, relocations, symbols);
      break;
    case ImageWriter::ProgramSection::Data:
      writer->AddROData(symbol, label, bytes, size, relocations, symbols);
      break;
    default:
      // Other sections are handled by the shared object writer internally.
      break;
  }
}

void AssemblyImageWriter::ExitSection(ProgramSection name,
                                      bool vm,
                                      intptr_t size) {
  // We should still be in the same section as the last EnterSection.
  ASSERT_EQUAL(current_section_label_, SectionLabel(name, vm));
#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
    defined(DART_TARGET_OS_FUCHSIA)
  // Output the size of the section symbol to the assembly stream.
  assembly_stream_->Printf(".size %s, %zu\n", SectionSymbol(name, vm), size);
  assembly_stream_->Printf(".type %s, %%object\n", SectionSymbol(name, vm));
#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
  // MachO symbol tables don't include the size of the symbol, so don't bother
  // printing it to the assembly output.
#elif defined(DART_TARGET_OS_WINDOWS)
  // Windows also doesn't have a .size directive.
#else
  UNIMPLEMENTED();
#endif

  // We need to generate a text segment of the appropriate size in the shared
  // object writer for two reasons:
  //
  // * We need unique virtual addresses for each text section in the DWARF
  //   file and that the virtual addresses for payloads within those sections
  //   do not overlap.
  //
  // * Our tools for converting DWARF stack traces back to "normal" Dart
  //   stack traces calculate an offset into the appropriate instructions
  //   section, and then add that offset to the virtual address of the
  //   corresponding segment to get the virtual address for the frame.
  //
  // Since we don't want to add the actual contents of the segment in the
  // separate debugging information, we pass nullptr for the bytes.
  AddSharedObjectSection(debug_so_, name, SectionSymbol(name, vm),
                         current_section_label_, /*bytes=*/nullptr, size,
                         current_symbols_);
  current_section_label_ = 0;
  current_symbols_ = nullptr;
}

intptr_t AssemblyImageWriter::WriteTargetWord(word value) {
  ASSERT(Utils::BitLength(value) <= compiler::target::kBitsPerWord);
  // Padding is helpful for comparing the .S with --disassemble.
  assembly_stream_->Printf("%s 0x%.*" Px "\n", kWordDirective,
                           static_cast<int>(2 * compiler::target::kWordSize),
                           value);
  return compiler::target::kWordSize;
}

intptr_t AssemblyImageWriter::Relocation(intptr_t section_offset,
                                         intptr_t source_label,
                                         intptr_t source_offset,
                                         intptr_t target_label,
                                         intptr_t target_offset) {
  // TODO(dartbug.com/43274): Remove once we generate consistent build IDs
  // between assembly snapshots and their debugging information.
  if (target_label == SectionLabel(ProgramSection::BuildId, /*vm=*/false)) {
    return WriteTargetWord(Image::kNoBuildId);
  }

  // All relocations are word-sized.
  assembly_stream_->Printf("%s ", kWordDirective);
  if (target_label == current_section_label_) {
    assembly_stream_->WriteString("(.)");
    target_offset -= section_offset;
  } else {
    const char* target_symbol = label_to_symbol_name_.Lookup(target_label);
    ASSERT(target_symbol != nullptr);
    assembly_stream_->Printf("%s", target_symbol);
  }
  if (target_offset != 0) {
    assembly_stream_->Printf(" + %" Pd "", target_offset);
  }

  if (source_label == current_section_label_) {
    assembly_stream_->WriteString(" - (.)");
    source_offset -= section_offset;
  } else {
    const char* source_symbol = label_to_symbol_name_.Lookup(source_label);
    ASSERT(source_symbol != nullptr);
    assembly_stream_->Printf(" - %s", source_symbol);
  }
  if (source_offset != 0) {
    assembly_stream_->Printf(" - %" Pd "", source_offset);
  }
  assembly_stream_->WriteString("\n");
  return compiler::target::kWordSize;
}

void AssemblyImageWriter::AddCodeSymbol(const Code& code,
                                        const char* symbol,
                                        intptr_t offset) {
  auto const label = next_label_++;
  label_to_symbol_name_.Insert(label, symbol);
  if (assembly_dwarf_ != nullptr) {
    assembly_dwarf_->AddCode(code, label);
  }
  if (debug_so_ != nullptr) {
    current_symbols_->Add({symbol,
                           SharedObjectWriter::SymbolData::Type::Function,
                           offset, code.Size(), label});
    debug_so_->dwarf()->AddCode(code, label);
  }
  assembly_stream_->Printf("\"%s\":\n", symbol);
#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_ANDROID) ||        \
    defined(DART_TARGET_OS_FUCHSIA)
  // Output the size of the code symbol to the assembly stream.
  assembly_stream_->Printf(".size \"%s\", %zu\n", symbol, code.Size());
  assembly_stream_->Printf(".type \"%s\", %%function\n", symbol);
#elif defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
  // MachO symbol tables don't include the size of the symbol, so don't bother
  // printing it to the assembly output.
#elif defined(DART_TARGET_OS_WINDOWS)
  // Windows also doesn't have a .size directive.
#else
  UNIMPLEMENTED();
#endif
}

void AssemblyImageWriter::AddDataSymbol(const char* symbol,
                                        intptr_t offset,
                                        size_t size) {
  if (!FLAG_add_readonly_data_symbols) return;
  auto const label = next_label_++;
  label_to_symbol_name_.Insert(label, symbol);
  if (debug_so_ != nullptr) {
    current_symbols_->Add({symbol, SharedObjectWriter::SymbolData::Type::Object,
                           offset, size, label});
  }
}

void AssemblyImageWriter::FrameUnwindPrologue() {
  // Creates DWARF's .debug_frame
  // CFI = Call frame information
  // CFA = Canonical frame address
  assembly_stream_->WriteString(".cfi_startproc\n");

  // Below .cfi_def_cfa defines CFA as caller's SP, while .cfi_offset R, offs
  // tells unwinder that caller's value of register R is stored at address
  // CFA+offs.

  // In the code below we emit .cfi_offset directive in the specific order:
  // PC first then FP. This should not actually matter, but we discovered
  // that LLVM code responsible for emitting compact unwind information
  // expects this specific ordering of CFI directives. If we don't
  // follow the order then LLVM fails to emit compact unwind info and emits
  // __eh_frame instead which is very large.
  // See also https://github.com/llvm/llvm-project/issues/62574 and
  // https://github.com/flutter/flutter/issues/126004.

#if defined(TARGET_ARCH_IA32)
  UNREACHABLE();
#elif defined(TARGET_ARCH_X64)
  assembly_stream_->WriteString(".cfi_def_cfa rbp, 16\n");
  assembly_stream_->WriteString(".cfi_offset rip, -8\n");
  assembly_stream_->WriteString(".cfi_offset rbp, -16\n");
#elif defined(TARGET_ARCH_ARM64)
  // If this changes, then MachOHeader::GenerateUnwindingInformation must
  // also change to generate the appropriate compact unwinding information.
  COMPILE_ASSERT(R29 == FP);
  COMPILE_ASSERT(R30 == LINK_REGISTER);
  assembly_stream_->WriteString(".cfi_def_cfa x29, 16\n");
  assembly_stream_->WriteString(".cfi_offset x30, -8\n");
  assembly_stream_->WriteString(".cfi_offset x29, -16\n");
#elif defined(TARGET_ARCH_ARM)
#if defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
  COMPILE_ASSERT(FP == R7);
  assembly_stream_->WriteString(".cfi_def_cfa r7, 8\n");
#else
  COMPILE_ASSERT(FP == R11);
  assembly_stream_->WriteString(".cfi_def_cfa r11, 8\n");
#endif
  assembly_stream_->WriteString(".cfi_offset lr, -4\n");
#if defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS)
  COMPILE_ASSERT(FP == R7);
  assembly_stream_->WriteString(".cfi_offset r7, -8\n");
#else
  COMPILE_ASSERT(FP == R11);
  assembly_stream_->WriteString(".cfi_offset r11, -8\n");
#endif
// libunwind on ARM may use .ARM.exidx instead of .debug_frame
#if !defined(DART_TARGET_OS_MACOS) && !defined(DART_TARGET_OS_MACOS_IOS)
  COMPILE_ASSERT(FP == R11);
  assembly_stream_->WriteString(".fnstart\n");
  assembly_stream_->WriteString(".save {r11, lr}\n");
  assembly_stream_->WriteString(".setfp r11, sp, #0\n");
#endif
#elif defined(TARGET_ARCH_RISCV32)
  assembly_stream_->WriteString(".cfi_def_cfa fp, 0\n");
  assembly_stream_->WriteString(".cfi_offset ra, -4\n");
  assembly_stream_->WriteString(".cfi_offset fp, -8\n");
#elif defined(TARGET_ARCH_RISCV64)
  assembly_stream_->WriteString(".cfi_def_cfa fp, 0\n");
  assembly_stream_->WriteString(".cfi_offset ra, -8\n");
  assembly_stream_->WriteString(".cfi_offset fp, -16\n");
#else
#error Unexpected architecture.
#endif
}

void AssemblyImageWriter::FrameUnwindEpilogue() {
#if defined(TARGET_ARCH_ARM)
#if !defined(DART_TARGET_OS_MACOS) && !defined(DART_TARGET_OS_MACOS_IOS)
  assembly_stream_->WriteString(".fnend\n");
#endif
#endif
  assembly_stream_->WriteString(".cfi_endproc\n");
}

intptr_t AssemblyImageWriter::WriteBytes(const void* bytes, intptr_t size) {
  ASSERT(size >= 0);
  auto const start = reinterpret_cast<const uint8_t*>(bytes);
  auto const end_of_words =
      start + Utils::RoundDown(size, compiler::target::kWordSize);
  for (auto cursor = reinterpret_cast<const compiler::target::word*>(start);
       cursor < reinterpret_cast<const compiler::target::word*>(end_of_words);
       cursor++) {
    WriteTargetWord(*cursor);
  }
  auto const end = start + size;
  if (end != end_of_words) {
    assembly_stream_->WriteString(kSizeDirectives[kInt8SizeLog2]);
    for (auto cursor = end_of_words; cursor < end; cursor++) {
      assembly_stream_->Printf("%s 0x%.2x", cursor != end_of_words ? "," : "",
                               *cursor);
    }
    assembly_stream_->WriteString("\n");
  }
  return size;
}

intptr_t AssemblyImageWriter::Align(intptr_t alignment,
                                    intptr_t offset,
                                    intptr_t position) {
  ASSERT(offset == 0);
  const intptr_t next_position = Utils::RoundUp(position, alignment);
  assembly_stream_->Printf(".balign %" Pd ", 0\n", alignment);
  return next_position - position;
}
#endif  // defined(DART_PRECOMPILER)

#if defined(DART_PRECOMPILER)
BlobImageWriter::BlobImageWriter(Thread* thread,
                                 NonStreamingWriteStream* vm_instructions,
                                 NonStreamingWriteStream* isolate_instructions,
                                 const Trie<const char>* deobfuscation_trie,
                                 SharedObjectWriter* debug_so,
                                 SharedObjectWriter* so,
                                 bool needs_unique_names)
    : ImageWriter(thread,
                  /*generates_assembly=*/false,
                  needs_unique_names,
                  deobfuscation_trie),
#else
BlobImageWriter::BlobImageWriter(Thread* thread,
                                 NonStreamingWriteStream* vm_instructions,
                                 NonStreamingWriteStream* isolate_instructions,
                                 SharedObjectWriter* debug_so,
                                 SharedObjectWriter* so,
                                 bool needs_unique_names)
    : ImageWriter(thread, /*generates_assembly=*/false, needs_unique_names),
#endif
      vm_instructions_(vm_instructions),
      isolate_instructions_(isolate_instructions),
      so_(so),
      debug_so_(debug_so) {
#if defined(DART_PRECOMPILER)
  ASSERT_EQUAL(FLAG_precompiled_mode, so_ != nullptr);
  ASSERT(debug_so_ == nullptr || debug_so_->dwarf() != nullptr);
#else
  RELEASE_ASSERT(so_ == nullptr);
  RELEASE_ASSERT(debug_so_ == nullptr);
#endif
}

void BlobImageWriter::Finalize() {
#if defined(DART_PRECOMPILER)
  if (so_ != nullptr) {
    TIMELINE_DURATION(thread_, Isolate, "FinalizeSharedObject");
    so_->Finalize();
  }
  if (debug_so_ != nullptr) {
    {
      TIMELINE_DURATION(thread_, Isolate, "FinalizeDebugInfo");
      debug_so_->Finalize();
    }
    if (so_ != nullptr) {
      so_->AssertConsistency(debug_so_);
    }
  }
#endif
}

intptr_t BlobImageWriter::WriteBytes(const void* bytes, intptr_t size) {
  current_section_stream_->WriteBytes(bytes, size);
  return size;
}

void BlobImageWriter::WriteBss(bool vm) {
#if defined(DART_PRECOMPILER)
  // We don't actually write a BSS segment, it's created as part of the
  // Finalize() method of the shared object writer.
#endif
}

void BlobImageWriter::WriteROData(NonStreamingWriteStream* clustered_stream,
                                  bool vm) {
#if defined(DART_PRECOMPILER)
  const intptr_t start_position = clustered_stream->Position();
#endif
  current_section_stream_ = ASSERT_NOTNULL(clustered_stream);
  if (!EnterSection(ProgramSection::Data, vm, ImageWriter::kRODataAlignment)) {
    return;
  }
#if defined(DART_PRECOMPILER)
  if (profile_writer_ != nullptr) {
    // Attribute any padding needed to the artificial root.
    const intptr_t padding = clustered_stream->Position() - start_position;
    profile_writer_->AttributeBytesTo(
        V8SnapshotProfileWriter::kArtificialRootId, padding);
  }
#endif
  ImageWriter::WriteROData(clustered_stream, vm);
  ExitSection(ProgramSection::Data, vm, clustered_stream->bytes_written());
}

bool BlobImageWriter::EnterSection(ProgramSection section,
                                   bool vm,
                                   intptr_t alignment,
                                   intptr_t* alignment_padding) {
#if defined(DART_PRECOMPILER)
  ASSERT_EQUAL(so_ != nullptr, FLAG_precompiled_mode);
  ASSERT(current_relocations_ == nullptr);
  ASSERT(current_symbols_ == nullptr);
#endif
  ASSERT(section == ProgramSection::Data || current_section_stream_ == nullptr);
  switch (section) {
    case ProgramSection::Text:
      current_section_stream_ =
          ASSERT_NOTNULL(vm ? vm_instructions_ : isolate_instructions_);
#if defined(DART_PRECOMPILER)
      if (so_ != nullptr || debug_so_ != nullptr) {
        current_relocations_ =
            new (zone_) SharedObjectWriter::RelocationArray(zone_, 0);
        current_symbols_ =
            new (zone_) SharedObjectWriter::SymbolDataArray(zone_, 0);
      }
#endif
      break;
    case ProgramSection::Data:
      // The stream to use is passed into WriteROData and set there.
      ASSERT(current_section_stream_ != nullptr);
#if defined(DART_PRECOMPILER)
      if (so_ != nullptr || debug_so_ != nullptr) {
        current_relocations_ =
            new (zone_) SharedObjectWriter::RelocationArray(zone_, 0);
        current_symbols_ =
            new (zone_) SharedObjectWriter::SymbolDataArray(zone_, 0);
      }
#endif
      break;
    case ProgramSection::Bss:
      // SharedObjectWriter::Finalize() creates the BSS section.
      return false;
    case ProgramSection::BuildId:
      // SharedObjectWriter::Finalize() creates the appropriate type of
      // build ID for the target format.
      return false;
  }
  intptr_t padding = current_section_stream_->Align(alignment);
  if (alignment_padding != nullptr) {
    *alignment_padding = padding;
  }
  return true;
}

void BlobImageWriter::ExitSection(ProgramSection name, bool vm, intptr_t size) {
#if defined(DART_PRECOMPILER)
  AddSharedObjectSection(so_, name, SectionSymbol(name, vm),
                         SectionLabel(name, vm),
                         current_section_stream_->buffer(), size,
                         current_symbols_, current_relocations_);
  // We create the corresponding segment in the debugging information as well,
  // since it needs the contents to create the correct build ID.
  AddSharedObjectSection(debug_so_, name, SectionSymbol(name, vm),
                         SectionLabel(name, vm),
                         current_section_stream_->buffer(), size,
                         current_symbols_, current_relocations_);
  current_relocations_ = nullptr;
  current_symbols_ = nullptr;
#endif
  current_section_stream_ = nullptr;
}

intptr_t BlobImageWriter::WriteTargetWord(word value) {
  current_section_stream_->WriteTargetWord(value);
  return compiler::target::kWordSize;
}

intptr_t BlobImageWriter::Align(intptr_t alignment,
                                intptr_t offset,
                                intptr_t position) {
  const intptr_t stream_padding =
      current_section_stream_->Align(alignment, offset);
  // Double-check that the position has the same alignment.
  ASSERT_EQUAL(Utils::RoundUp(position, alignment, offset) - position,
               stream_padding);
  return stream_padding;
}

#if defined(DART_PRECOMPILER)
intptr_t BlobImageWriter::Relocation(intptr_t section_offset,
                                     intptr_t source_label,
                                     intptr_t source_offset,
                                     intptr_t target_label,
                                     intptr_t target_offset) {
  ASSERT(FLAG_precompiled_mode);
  if (current_relocations_ != nullptr) {
    current_relocations_->Add({compiler::target::kWordSize, section_offset,
                               source_label, source_offset, target_label,
                               target_offset});
  }
  // We write break instructions so it's easy to tell if a relocation doesn't
  // get replaced appropriately.
  return WriteTargetWord(kBreakInstructionFiller);
}

void BlobImageWriter::AddCodeSymbol(const Code& code,
                                    const char* symbol,
                                    intptr_t offset) {
  const intptr_t label = next_label_++;
  if (current_symbols_ != nullptr) {
    current_symbols_->Add({symbol,
                           SharedObjectWriter::SymbolData::Type::Function,
                           offset, code.Size(), label});
  }
  if (so_ != nullptr && so_->dwarf() != nullptr) {
    so_->dwarf()->AddCode(code, label);
  }
  if (debug_so_ != nullptr) {
    debug_so_->dwarf()->AddCode(code, label);
  }
}

void BlobImageWriter::AddDataSymbol(const char* symbol,
                                    intptr_t offset,
                                    size_t size) {
  if (!FLAG_add_readonly_data_symbols) return;
  const intptr_t label = next_label_++;
  if (current_symbols_ != nullptr) {
    current_symbols_->Add({symbol, SharedObjectWriter::SymbolData::Type::Object,
                           offset, size, label});
  }
}
#endif  // defined(DART_PRECOMPILER)
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

ImageReader::ImageReader(const uint8_t* data_image,
                         const uint8_t* instructions_image)
    : data_image_(ASSERT_NOTNULL(data_image)),
      instructions_image_(ASSERT_NOTNULL(instructions_image)) {}

ApiErrorPtr ImageReader::VerifyAlignment() const {
  if (!Utils::IsAligned(data_image_, kObjectStartAlignment) ||
      !Utils::IsAligned(instructions_image_, kObjectStartAlignment)) {
    return ApiError::New(
        String::Handle(String::New("Snapshot is misaligned", Heap::kOld)),
        Heap::kOld);
  }
  return ApiError::null();
}

#if defined(DART_PRECOMPILED_RUNTIME)
uword ImageReader::GetBareInstructionsAt(uint32_t offset) const {
  ASSERT(Utils::IsAligned(offset, Instructions::kBarePayloadAlignment));
  return reinterpret_cast<uword>(instructions_image_) + offset;
}

uword ImageReader::GetBareInstructionsEnd() const {
  Image image(instructions_image_);
  return reinterpret_cast<uword>(image.object_start()) + image.object_size();
}
#endif

InstructionsPtr ImageReader::GetInstructionsAt(uint32_t offset) const {
  ASSERT(!FLAG_precompiled_mode);
  ASSERT(Utils::IsAligned(offset, kObjectAlignment));

  ObjectPtr result = UntaggedObject::FromAddr(
      reinterpret_cast<uword>(instructions_image_) + offset);
  ASSERT(result->IsInstructions());
  ASSERT(result->untag()->IsMarked());

  return Instructions::RawCast(result);
}

ObjectPtr ImageReader::GetObjectAt(uint32_t offset) const {
  ASSERT(Utils::IsAligned(offset, kObjectAlignment));

  ObjectPtr result =
      UntaggedObject::FromAddr(reinterpret_cast<uword>(data_image_) + offset);
  ASSERT(result->untag()->IsMarked());

  return result;
}

}  // namespace dart
