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

#include "bin/snapshot_utils.h"

#include "bin/dartutils.h"
#include "bin/dfe.h"
#include "bin/elf_loader.h"
#include "bin/error_exit.h"
#include "bin/file.h"
#include "bin/platform.h"
#include "include/dart_api.h"
#if defined(DART_TARGET_OS_MACOS)
#include <platform/mach_o.h>
#endif
#if defined(DART_TARGET_OS_WINDOWS)
#include <platform/pe.h>
#endif
#include "platform/utils.h"

#define LOG_SECTION_BOUNDARIES false

namespace dart {
namespace bin {

static constexpr int64_t kAppSnapshotHeaderSize = 2 * kInt64Size;
// The largest possible page size among the platforms we support (Linux ARM64).
static constexpr int64_t kAppSnapshotPageSize = 64 * KB;

static const char kMachOAppSnapshotNoteName[] DART_UNUSED = "__dart_app_snap";

#if !defined(DART_PRECOMPILED_RUNTIME)
class DummySnapshot : public AppSnapshot {
 public:
  explicit DummySnapshot(DartUtils::MagicNumber num) : AppSnapshot(num) {}

  ~DummySnapshot() {}

  void SetBuffers(const uint8_t** vm_data_buffer,
                  const uint8_t** vm_instructions_buffer,
                  const uint8_t** isolate_data_buffer,
                  const uint8_t** isolate_instructions_buffer) {
    UNREACHABLE();
  }

 private:
};
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

class MappedAppSnapshot : public AppSnapshot {
 public:
  MappedAppSnapshot(MappedMemory* vm_snapshot_data,
                    MappedMemory* vm_snapshot_instructions,
                    MappedMemory* isolate_snapshot_data,
                    MappedMemory* isolate_snapshot_instructions)
      : AppSnapshot(DartUtils::kAppJITMagicNumber),
        vm_data_mapping_(vm_snapshot_data),
        vm_instructions_mapping_(vm_snapshot_instructions),
        isolate_data_mapping_(isolate_snapshot_data),
        isolate_instructions_mapping_(isolate_snapshot_instructions) {}

  ~MappedAppSnapshot() {
    delete vm_data_mapping_;
    delete vm_instructions_mapping_;
    delete isolate_data_mapping_;
    delete isolate_instructions_mapping_;
  }

  void SetBuffers(const uint8_t** vm_data_buffer,
                  const uint8_t** vm_instructions_buffer,
                  const uint8_t** isolate_data_buffer,
                  const uint8_t** isolate_instructions_buffer) {
    if (vm_data_mapping_ != nullptr) {
      *vm_data_buffer =
          reinterpret_cast<const uint8_t*>(vm_data_mapping_->address());
    }
    if (vm_instructions_mapping_ != nullptr) {
      *vm_instructions_buffer =
          reinterpret_cast<const uint8_t*>(vm_instructions_mapping_->address());
    }
    if (isolate_data_mapping_ != nullptr) {
      *isolate_data_buffer =
          reinterpret_cast<const uint8_t*>(isolate_data_mapping_->address());
    }
    if (isolate_instructions_mapping_ != nullptr) {
      *isolate_instructions_buffer = reinterpret_cast<const uint8_t*>(
          isolate_instructions_mapping_->address());
    }
  }

 private:
  MappedMemory* vm_data_mapping_;
  MappedMemory* vm_instructions_mapping_;
  MappedMemory* isolate_data_mapping_;
  MappedMemory* isolate_instructions_mapping_;
};

static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name,
                                            File* file) {
  if ((file->Length() - file->Position()) < kAppSnapshotHeaderSize) {
    return nullptr;
  }

  int64_t header[2];
  ASSERT(sizeof(header) == kAppSnapshotHeaderSize);
  if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) {
    return nullptr;
  }
  int64_t isolate_data_size = header[0];
  int64_t isolate_data_position =
      Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
  int64_t isolate_instructions_size = header[1];
  int64_t isolate_instructions_position =
      isolate_data_position + isolate_data_size;
  if (isolate_instructions_size != 0) {
    isolate_instructions_position =
        Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize);
  }

  MappedMemory* isolate_data_mapping = nullptr;
  if (isolate_data_size != 0) {
    isolate_data_mapping =
        file->Map(File::kReadOnly, isolate_data_position, isolate_data_size);
    if (isolate_data_mapping == nullptr) {
      FATAL("Failed to memory map snapshot: %s\n", script_name);
    }
  }

  MappedMemory* isolate_instr_mapping = nullptr;
  if (isolate_instructions_size != 0) {
    isolate_instr_mapping =
        file->Map(File::kReadExecute, isolate_instructions_position,
                  isolate_instructions_size);
    if (isolate_instr_mapping == nullptr) {
      FATAL("Failed to memory map snapshot: %s\n", script_name);
    }
  }

  auto app_snapshot = new MappedAppSnapshot(
      nullptr, nullptr, isolate_data_mapping, isolate_instr_mapping);
  return app_snapshot;
}

#if defined(DART_PRECOMPILED_RUNTIME)
class ElfAppSnapshot : public AppSnapshot {
 public:
  ElfAppSnapshot(Dart_LoadedElf* elf,
                 const uint8_t* vm_snapshot_data,
                 const uint8_t* vm_snapshot_instructions,
                 const uint8_t* isolate_snapshot_data,
                 const uint8_t* isolate_snapshot_instructions)
      : AppSnapshot{DartUtils::kAotELFMagicNumber},
        elf_(elf),
        vm_snapshot_data_(vm_snapshot_data),
        vm_snapshot_instructions_(vm_snapshot_instructions),
        isolate_snapshot_data_(isolate_snapshot_data),
        isolate_snapshot_instructions_(isolate_snapshot_instructions) {}

  virtual ~ElfAppSnapshot() { Dart_UnloadELF(elf_); }

  void SetBuffers(const uint8_t** vm_data_buffer,
                  const uint8_t** vm_instructions_buffer,
                  const uint8_t** isolate_data_buffer,
                  const uint8_t** isolate_instructions_buffer) {
    *vm_data_buffer = vm_snapshot_data_;
    *vm_instructions_buffer = vm_snapshot_instructions_;
    *isolate_data_buffer = isolate_snapshot_data_;
    *isolate_instructions_buffer = isolate_snapshot_instructions_;
  }

 private:
  Dart_LoadedElf* elf_;
  const uint8_t* vm_snapshot_data_;
  const uint8_t* vm_snapshot_instructions_;
  const uint8_t* isolate_snapshot_data_;
  const uint8_t* isolate_snapshot_instructions_;
};

static AppSnapshot* TryReadAppSnapshotElf(
    const char* script_name,
    uint64_t file_offset,
    bool force_load_elf_from_memory = false) {
  const char* error = nullptr;
  const uint8_t *vm_data_buffer = nullptr, *vm_instructions_buffer = nullptr,
                *isolate_data_buffer = nullptr,
                *isolate_instructions_buffer = nullptr;
  Dart_LoadedElf* handle = nullptr;
#if !defined(DART_HOST_OS_FUCHSIA)
  if (force_load_elf_from_memory) {
#endif
    File* const file =
        File::Open(/*namespc=*/nullptr, script_name, File::kRead);
    if (file == nullptr) return nullptr;
    MappedMemory* memory = file->Map(File::kReadOnly, /*position=*/0,
                                     /*length=*/file->Length());
    if (memory == nullptr) return nullptr;
    const uint8_t* address =
        reinterpret_cast<const uint8_t*>(memory->address());
    handle =
        Dart_LoadELF_Memory(address + file_offset, file->Length(), &error,
                            &vm_data_buffer, &vm_instructions_buffer,
                            &isolate_data_buffer, &isolate_instructions_buffer);
    delete memory;
    file->Release();
#if !defined(DART_HOST_OS_FUCHSIA)
  } else {
    handle = Dart_LoadELF(script_name, file_offset, &error, &vm_data_buffer,
                          &vm_instructions_buffer, &isolate_data_buffer,
                          &isolate_instructions_buffer);
  }
#endif
  if (handle == nullptr) {
    Syslog::PrintErr("Loading failed: %s\n", error);
    return nullptr;
  }
  return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
                            isolate_data_buffer, isolate_instructions_buffer);
}

#if defined(DART_TARGET_OS_MACOS)
AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElfFromMachO(
    const char* container_path) {
  // Ensure file is actually MachO-formatted.
  if (!IsMachOFormattedBinary(container_path)) {
    Syslog::PrintErr("Expected a Mach-O binary.\n");
    return nullptr;
  }

  File* file = File::Open(nullptr, container_path, File::kRead);
  if (file == nullptr) {
    return nullptr;
  }
  RefCntReleaseScope<File> rs(file);

  // Read in the Mach-O header. Note that the 64-bit header is the same layout
  // as the 32-bit header, just with an extra field for alignment, so we can
  // safely load a 32-bit header to get all the information we need.
  mach_o::mach_header header;
  file->ReadFully(&header, sizeof(header));

  if (header.magic == mach_o::MH_CIGAM || header.magic == mach_o::MH_CIGAM_64) {
    Syslog::PrintErr(
        "Expected a host endian header but found a byte-swapped header.\n");
    return nullptr;
  }

  if (header.magic == mach_o::MH_MAGIC_64) {
    // Set the file position as if we had read a 64-bit header.
    file->SetPosition(sizeof(mach_o::mach_header_64));
  }

  // Now we search through the load commands to find our snapshot note, which
  // has a data_owner field of kMachOAppSnapshotNoteName.
  for (uint32_t i = 0; i < header.ncmds; ++i) {
    mach_o::load_command command;
    file->ReadFully(&command, sizeof(mach_o::load_command));

    file->SetPosition(file->Position() - sizeof(command));
    if (command.cmd != mach_o::LC_NOTE) {
      file->SetPosition(file->Position() + command.cmdsize);
      continue;
    }

    mach_o::note_command note;
    file->ReadFully(&note, sizeof(note));

    if (strcmp(note.data_owner, kMachOAppSnapshotNoteName) != 0) {
      file->SetPosition(file->Position() + command.cmdsize);
      continue;
    }

    // A note with the correct name was found, so we assume that the
    // file contents for that note contains an ELF snapshot.
    return TryReadAppSnapshotElf(container_path, note.offset);
  }

  return nullptr;
}
#endif  // defined(DART_TARGET_OS_MACOS)

#if defined(DART_TARGET_OS_WINDOWS)
// Keep in sync with CoffSectionTable._snapshotSectionName from
// pkg/dart2native/lib/dart2native_pe.dart.
static const char kSnapshotSectionName[] = "snapshot";
// Ignore the null terminator, as it won't be present if the string length is
// exactly pe::kCoffSectionNameSize.
static_assert(sizeof(kSnapshotSectionName) - 1 <= pe::kCoffSectionNameSize,
              "Section name of snapshot too large");

AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElfFromPE(
    const char* container_path) {
  File* const file = File::Open(nullptr, container_path, File::kRead);
  if (file == nullptr) {
    return nullptr;
  }
  RefCntReleaseScope<File> rs(file);

  // Ensure file is actually PE-formatted.
  if (!IsPEFormattedBinary(container_path)) {
    Syslog::PrintErr(
        "Attempted load target was not formatted as expected: "
        "expected PE32 or PE32+ image file.\n");
    return nullptr;
  }

  // Parse the offset into the PE contents (i.e., skipping the MS-DOS stub).
  uint32_t pe_offset;
  file->SetPosition(pe::kPEOffsetOffset);
  file->ReadFully(&pe_offset, sizeof(pe_offset));

  // Skip past the magic bytes to the COFF file header and COFF optional header.
  const intptr_t coff_offset = pe_offset + sizeof(pe::kPEMagic);
  file->SetPosition(coff_offset);
  pe::coff_file_header file_header;
  file->ReadFully(&file_header, sizeof(file_header));
  // The optional header follows directly after the file header.
  pe::coff_optional_header opt_header;
  file->ReadFully(&opt_header, sizeof(opt_header));

  // Skip to the section table.
  const intptr_t coff_symbol_table_offset =
      coff_offset + sizeof(file_header) + file_header.optional_header_size;
  file->SetPosition(coff_symbol_table_offset);
  for (intptr_t i = 0; i < file_header.num_sections; i++) {
    pe::coff_section_header section_header;
    file->ReadFully(&section_header, sizeof(section_header));
    if (strncmp(section_header.name, kSnapshotSectionName,
                pe::kCoffSectionNameSize) == 0) {
      // We have to do the loading manually even though currently the snapshot
      // data is at the end of the file because the file alignment for
      // PE sections can be less than the page size, and TryReadAppSnapshotElf
      // won't work if the file offset isn't page-aligned.
      const char* error = nullptr;
      const uint8_t* vm_data_buffer = nullptr;
      const uint8_t* vm_instructions_buffer = nullptr;
      const uint8_t* isolate_data_buffer = nullptr;
      const uint8_t* isolate_instructions_buffer = nullptr;

      const intptr_t offset = section_header.file_offset;
      const intptr_t size = section_header.file_size;

      std::unique_ptr<uint8_t[]> snapshot(new uint8_t[size]);
      file->SetPosition(offset);
      file->ReadFully(snapshot.get(), sizeof(uint8_t) * size);

      Dart_LoadedElf* const handle =
          Dart_LoadELF_Memory(snapshot.get(), size, &error, &vm_data_buffer,
                              &vm_instructions_buffer, &isolate_data_buffer,
                              &isolate_instructions_buffer);

      if (handle == nullptr) {
        Syslog::PrintErr("Loading failed: %s\n", error);
        return nullptr;
      }

      return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
                                isolate_data_buffer,
                                isolate_instructions_buffer);
    }
  }

  return nullptr;
}
#endif  // defined(DART_TARGET_OS_WINDOWS)

AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElf(
    const char* container_path) {
#if defined(DART_TARGET_OS_MACOS)
  if (IsMachOFormattedBinary(container_path)) {
    return TryReadAppendedAppSnapshotElfFromMachO(container_path);
  }
#elif defined(DART_TARGET_OS_WINDOWS)
  if (IsPEFormattedBinary(container_path)) {
    return TryReadAppendedAppSnapshotElfFromPE(container_path);
  }
#endif

  File* file = File::Open(nullptr, container_path, File::kRead);
  if (file == nullptr) {
    return nullptr;
  }
  RefCntReleaseScope<File> rs(file);

  // Check for payload appended at the end of the container file.
  // If header is found, jump to payload offset.
  int64_t appended_header[2];
  if (!file->SetPosition(file->Length() - sizeof(appended_header))) {
    return nullptr;
  }
  if (!file->ReadFully(&appended_header, sizeof(appended_header))) {
    return nullptr;
  }
  // Length is always encoded as Little Endian.
  const uint64_t appended_offset =
      Utils::LittleEndianToHost64(appended_header[0]);
  if (memcmp(&appended_header[1], appjit_magic_number.bytes,
             appjit_magic_number.length) != 0 ||
      appended_offset <= 0) {
    return nullptr;
  }

  return TryReadAppSnapshotElf(container_path, appended_offset);
}

class DylibAppSnapshot : public AppSnapshot {
 public:
  DylibAppSnapshot(void* library,
                   const uint8_t* vm_snapshot_data,
                   const uint8_t* vm_snapshot_instructions,
                   const uint8_t* isolate_snapshot_data,
                   const uint8_t* isolate_snapshot_instructions)
      : AppSnapshot(DartUtils::kAotELFMagicNumber),
        library_(library),
        vm_snapshot_data_(vm_snapshot_data),
        vm_snapshot_instructions_(vm_snapshot_instructions),
        isolate_snapshot_data_(isolate_snapshot_data),
        isolate_snapshot_instructions_(isolate_snapshot_instructions) {}

  ~DylibAppSnapshot() { Utils::UnloadDynamicLibrary(library_); }

  void SetBuffers(const uint8_t** vm_data_buffer,
                  const uint8_t** vm_instructions_buffer,
                  const uint8_t** isolate_data_buffer,
                  const uint8_t** isolate_instructions_buffer) {
    *vm_data_buffer = vm_snapshot_data_;
    *vm_instructions_buffer = vm_snapshot_instructions_;
    *isolate_data_buffer = isolate_snapshot_data_;
    *isolate_instructions_buffer = isolate_snapshot_instructions_;
  }

 private:
  void* library_;
  const uint8_t* vm_snapshot_data_;
  const uint8_t* vm_snapshot_instructions_;
  const uint8_t* isolate_snapshot_data_;
  const uint8_t* isolate_snapshot_instructions_;
};

static AppSnapshot* TryReadAppSnapshotDynamicLibrary(const char* script_name) {
  void* library = Utils::LoadDynamicLibrary(script_name);
  if (library == nullptr) {
    return nullptr;
  }

  const uint8_t* vm_data_buffer = reinterpret_cast<const uint8_t*>(
      Utils::ResolveSymbolInDynamicLibrary(library, kVmSnapshotDataCSymbol));

  const uint8_t* vm_instructions_buffer =
      reinterpret_cast<const uint8_t*>(Utils::ResolveSymbolInDynamicLibrary(
          library, kVmSnapshotInstructionsCSymbol));

  const uint8_t* isolate_data_buffer =
      reinterpret_cast<const uint8_t*>(Utils::ResolveSymbolInDynamicLibrary(
          library, kIsolateSnapshotDataCSymbol));
  if (isolate_data_buffer == nullptr) {
    FATAL("Failed to resolve symbol '%s'\n", kIsolateSnapshotDataCSymbol);
  }

  const uint8_t* isolate_instructions_buffer =
      reinterpret_cast<const uint8_t*>(Utils::ResolveSymbolInDynamicLibrary(
          library, kIsolateSnapshotInstructionsCSymbol));
  if (isolate_instructions_buffer == nullptr) {
    FATAL("Failed to resolve symbol '%s'\n",
          kIsolateSnapshotInstructionsCSymbol);
  }

  return new DylibAppSnapshot(library, vm_data_buffer, vm_instructions_buffer,
                              isolate_data_buffer, isolate_instructions_buffer);
}

#endif  // defined(DART_PRECOMPILED_RUNTIME)

#if defined(DART_TARGET_OS_MACOS)
bool Snapshot::IsMachOFormattedBinary(const char* filename) {
  File* file = File::Open(nullptr, filename, File::kRead);
  if (file == nullptr) {
    return false;
  }
  RefCntReleaseScope<File> rs(file);

  const uint64_t size = file->Length();
  // Parse the first 4 bytes and check the magic numbers.
  uint32_t magic;
  if (size < sizeof(magic)) {
    // The file isn't long enough to contain the magic bytes.
    return false;
  }
  file->SetPosition(0);
  file->ReadFully(&magic, sizeof(magic));

  // Depending on the magic numbers, check that the size of the file is
  // large enough for either a 32-bit or 64-bit header.
  switch (magic) {
    case mach_o::MH_MAGIC:
    case mach_o::MH_CIGAM:
      return size >= sizeof(mach_o::mach_header);
    case mach_o::MH_MAGIC_64:
    case mach_o::MH_CIGAM_64:
      return size >= sizeof(mach_o::mach_header_64);
    default:
      // Not a Mach-O formatted file.
      return false;
  }
}
#endif  // defined(DART_TARGET_OS_MACOS)

#if defined(DART_TARGET_OS_WINDOWS)
bool Snapshot::IsPEFormattedBinary(const char* filename) {
  File* file = File::Open(nullptr, filename, File::kRead);
  if (file == nullptr) {
    return false;
  }
  RefCntReleaseScope<File> rs(file);

  // Parse the PE offset.
  uint32_t pe_offset;
  // Ensure the file is long enough to contain the PE offset.
  if (file->Length() <
      static_cast<intptr_t>(pe::kPEOffsetOffset + sizeof(pe_offset))) {
    return false;
  }
  file->SetPosition(pe::kPEOffsetOffset);
  file->Read(&pe_offset, sizeof(pe_offset));

  // Ensure the file is long enough to contain the PE magic bytes.
  if (file->Length() <
      static_cast<intptr_t>(pe_offset + sizeof(pe::kPEMagic))) {
    return false;
  }
  // Check the magic bytes.
  file->SetPosition(pe_offset);
  for (size_t i = 0; i < sizeof(pe::kPEMagic); i++) {
    char c;
    file->Read(&c, sizeof(c));
    if (c != pe::kPEMagic[i]) {
      return false;
    }
  }

  // Check that there is a coff optional header.
  pe::coff_file_header file_header;
  pe::coff_optional_header opt_header;
  file->Read(&file_header, sizeof(file_header));
  if (file_header.optional_header_size < sizeof(opt_header)) {
    return false;
  }
  file->Read(&opt_header, sizeof(opt_header));
  // Check the magic bytes in the coff optional header.
  if (opt_header.magic != pe::kPE32Magic &&
      opt_header.magic != pe::kPE32PlusMagic) {
    return false;
  }

  return true;
}
#endif  // defined(DART_TARGET_OS_WINDOWS)

AppSnapshot* Snapshot::TryReadAppSnapshot(const char* script_uri,
                                          bool force_load_elf_from_memory,
                                          bool decode_uri) {
  CStringUniquePtr decoded_path(nullptr);
  const char* script_name = nullptr;
  if (decode_uri) {
    decoded_path = File::UriToPath(script_uri);
    if (decoded_path == nullptr) {
      return nullptr;
    }
    script_name = decoded_path.get();
  } else {
    script_name = script_uri;
  }
  if (File::GetType(nullptr, script_name, true) != File::kIsFile) {
    // If 'script_name' refers to a pipe, don't read to check for an app
    // snapshot since we cannot rewind if it isn't (and couldn't mmap it in
    // anyway if it was).
    return nullptr;
  }
  File* file = File::Open(nullptr, script_name, File::kRead);
  if (file == nullptr) {
    return nullptr;
  }
  RefCntReleaseScope<File> rs(file);
  if ((file->Length() - file->Position()) < DartUtils::kMaxMagicNumberSize) {
    return nullptr;
  }

  uint8_t header[DartUtils::kMaxMagicNumberSize];
  ASSERT(sizeof(header) == DartUtils::kMaxMagicNumberSize);
  if (!file->ReadFully(&header, DartUtils::kMaxMagicNumberSize)) {
    return nullptr;
  }
  DartUtils::MagicNumber magic_number =
      DartUtils::SniffForMagicNumber(header, sizeof(header));
  if (magic_number == DartUtils::kAppJITMagicNumber) {
    // Return the JIT snapshot.
    return TryReadAppSnapshotBlobs(script_name, file);
  }
#if defined(DART_PRECOMPILED_RUNTIME)
  if (!DartUtils::IsAotMagicNumber(magic_number)) {
    return nullptr;
  }

  // For testing AOT with the standalone embedder, we also support loading
  // from a dynamic library to simulate what happens on iOS.

#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_MACOS)
  // On Linux and OSX, resolve the script path before passing into dlopen()
  // since dlopen will not search the filesystem for paths like 'libtest.so'.
  CStringUniquePtr absolute_path(realpath(script_name, nullptr));
  script_name = absolute_path.get();
#endif

  AppSnapshot* snapshot = nullptr;
  if (!force_load_elf_from_memory) {
    snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
    if (snapshot != nullptr) {
      return snapshot;
    }
  }
  return TryReadAppSnapshotElf(script_name, /*file_offset=*/0,
                               force_load_elf_from_memory);
#else
  // We create a dummy snapshot object just to remember the type which
  // has already been identified by sniffing the magic number.
  return new DummySnapshot(magic_number);
#endif  // defined(DART_PRECOMPILED_RUNTIME)

  return nullptr;
}

#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
static void WriteSnapshotFile(const char* filename,
                              const uint8_t* buffer,
                              const intptr_t size) {
  File* file = File::Open(nullptr, filename, File::kWriteTruncate);
  if (file == nullptr) {
    ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n",
              filename);
  }

  if (!file->WriteFully(buffer, size)) {
    ErrorExit(kErrorExitCode, "Unable to write file %s for writing snapshot\n",
              filename);
  }
  file->Release();
}
#endif

static bool WriteInt64(File* file, int64_t size) {
  return file->WriteFully(&size, sizeof(size));
}

void Snapshot::WriteAppSnapshot(const char* filename,
                                uint8_t* isolate_data_buffer,
                                intptr_t isolate_data_size,
                                uint8_t* isolate_instructions_buffer,
                                intptr_t isolate_instructions_size) {
  File* file = File::Open(nullptr, filename, File::kWriteTruncate);
  if (file == nullptr) {
    ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
  }

  file->WriteFully(appjit_magic_number.bytes, appjit_magic_number.length);
  WriteInt64(file, isolate_data_size);
  WriteInt64(file, isolate_instructions_size);
  ASSERT(file->Position() ==
         (kAppSnapshotHeaderSize + DartUtils::kMaxMagicNumberSize));

  file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
  if (LOG_SECTION_BOUNDARIES) {
    Syslog::PrintErr("%" Px64 ": Isolate Data\n", file->Position());
  }
  if (!file->WriteFully(isolate_data_buffer, isolate_data_size)) {
    ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
  }

  if (isolate_instructions_size != 0) {
    file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
    if (LOG_SECTION_BOUNDARIES) {
      Syslog::PrintErr("%" Px64 ": Isolate Instructions\n", file->Position());
    }
    if (!file->WriteFully(isolate_instructions_buffer,
                          isolate_instructions_size)) {
      ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
                filename);
    }
  }

  file->Flush();
  file->Release();
}

void Snapshot::GenerateKernel(const char* snapshot_filename,
                              const char* script_name,
                              const char* package_config) {
#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
  ASSERT(Dart_CurrentIsolate() == nullptr);

  uint8_t* kernel_buffer = nullptr;
  intptr_t kernel_buffer_size = 0;
  dfe.ReadScript(script_name, nullptr, &kernel_buffer, &kernel_buffer_size);
  if (kernel_buffer != nullptr) {
    WriteSnapshotFile(snapshot_filename, kernel_buffer, kernel_buffer_size);
    free(kernel_buffer);
  } else {
    Dart_KernelCompilationResult result =
        dfe.CompileScript(script_name, /*incremental*/ false, package_config,
                          /*snapshot=*/true, /*embedd_sources=*/true);
    if (result.status != Dart_KernelCompilationStatus_Ok) {
      Syslog::PrintErr("%s\n", result.error);
      Platform::Exit(kCompilationErrorExitCode);
    }
    WriteSnapshotFile(snapshot_filename, result.kernel, result.kernel_size);
    free(result.kernel);
  }
#else
  UNREACHABLE();
#endif  // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
}

void Snapshot::GenerateAppJIT(const char* snapshot_filename) {
#if defined(TARGET_ARCH_IA32)
  // Snapshots with code are not supported on IA32.
  uint8_t* isolate_buffer = nullptr;
  intptr_t isolate_size = 0;

  Dart_Handle result = Dart_CreateSnapshot(nullptr, nullptr, &isolate_buffer,
                                           &isolate_size, /*is_core=*/false);
  if (Dart_IsError(result)) {
    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
  }

  WriteAppSnapshot(snapshot_filename, isolate_buffer, isolate_size, nullptr, 0);
#else
  uint8_t* isolate_data_buffer = nullptr;
  intptr_t isolate_data_size = 0;
  uint8_t* isolate_instructions_buffer = nullptr;
  intptr_t isolate_instructions_size = 0;
  Dart_Handle result = Dart_CreateAppJITSnapshotAsBlobs(
      &isolate_data_buffer, &isolate_data_size, &isolate_instructions_buffer,
      &isolate_instructions_size);
  if (Dart_IsError(result)) {
    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
  }
  WriteAppSnapshot(snapshot_filename, isolate_data_buffer, isolate_data_size,
                   isolate_instructions_buffer, isolate_instructions_size);
#endif
}

static void StreamingWriteCallback(void* callback_data,
                                   const uint8_t* buffer,
                                   intptr_t size) {
  File* file = reinterpret_cast<File*>(callback_data);
  if (!file->WriteFully(buffer, size)) {
    ErrorExit(kErrorExitCode, "Unable to write snapshot file\n");
  }
}

void Snapshot::GenerateAppAOTAsAssembly(const char* snapshot_filename) {
  File* file = File::Open(nullptr, snapshot_filename, File::kWriteTruncate);
  RefCntReleaseScope<File> rs(file);
  if (file == nullptr) {
    ErrorExit(kErrorExitCode, "Unable to open file %s for writing snapshot\n",
              snapshot_filename);
  }
  Dart_Handle result = Dart_CreateAppAOTSnapshotAsAssembly(
      StreamingWriteCallback, file, /*strip=*/false,
      /*debug_callback_data=*/nullptr);
  if (Dart_IsError(result)) {
    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
  }
}

}  // namespace bin
}  // namespace dart
