16#if defined(DART_TARGET_OS_MACOS)
19#if defined(DART_TARGET_OS_WINDOWS)
24#define LOG_SECTION_BOUNDARIES false
33static const char kMachOAppSnapshotNoteName[]
DART_UNUSED =
"__dart_app_snap";
35#if !defined(DART_PRECOMPILED_RUNTIME)
43 const uint8_t** vm_instructions_buffer,
44 const uint8_t** isolate_data_buffer,
45 const uint8_t** isolate_instructions_buffer) {
66 delete vm_data_mapping_;
67 delete vm_instructions_mapping_;
68 delete isolate_data_mapping_;
69 delete isolate_instructions_mapping_;
73 const uint8_t** vm_instructions_buffer,
74 const uint8_t** isolate_data_buffer,
75 const uint8_t** isolate_instructions_buffer) {
76 if (vm_data_mapping_ !=
nullptr) {
78 reinterpret_cast<const uint8_t*
>(vm_data_mapping_->
address());
80 if (vm_instructions_mapping_ !=
nullptr) {
81 *vm_instructions_buffer =
82 reinterpret_cast<const uint8_t*
>(vm_instructions_mapping_->
address());
84 if (isolate_data_mapping_ !=
nullptr) {
85 *isolate_data_buffer =
86 reinterpret_cast<const uint8_t*
>(isolate_data_mapping_->
address());
88 if (isolate_instructions_mapping_ !=
nullptr) {
89 *isolate_instructions_buffer =
reinterpret_cast<const uint8_t*
>(
90 isolate_instructions_mapping_->
address());
112 int64_t isolate_data_size =
header[0];
113 int64_t isolate_data_position =
115 int64_t isolate_instructions_size =
header[1];
116 int64_t isolate_instructions_position =
117 isolate_data_position + isolate_data_size;
118 if (isolate_instructions_size != 0) {
119 isolate_instructions_position =
124 if (isolate_data_size != 0) {
125 isolate_data_mapping =
127 if (isolate_data_mapping ==
nullptr) {
128 FATAL(
"Failed to memory map snapshot: %s\n", script_name);
133 if (isolate_instructions_size != 0) {
134 isolate_instr_mapping =
136 isolate_instructions_size);
137 if (isolate_instr_mapping ==
nullptr) {
138 FATAL(
"Failed to memory map snapshot: %s\n", script_name);
143 nullptr,
nullptr, isolate_data_mapping, isolate_instr_mapping);
147#if defined(DART_PRECOMPILED_RUNTIME)
148class ElfAppSnapshot :
public AppSnapshot {
155 : AppSnapshot{DartUtils::kAotELFMagicNumber},
164 void SetBuffers(
const uint8_t** vm_data_buffer,
165 const uint8_t** vm_instructions_buffer,
166 const uint8_t** isolate_data_buffer,
167 const uint8_t** isolate_instructions_buffer) {
168 *vm_data_buffer = vm_snapshot_data_;
169 *vm_instructions_buffer = vm_snapshot_instructions_;
170 *isolate_data_buffer = isolate_snapshot_data_;
171 *isolate_instructions_buffer = isolate_snapshot_instructions_;
176 const uint8_t* vm_snapshot_data_;
177 const uint8_t* vm_snapshot_instructions_;
178 const uint8_t* isolate_snapshot_data_;
179 const uint8_t* isolate_snapshot_instructions_;
182static AppSnapshot* TryReadAppSnapshotElf(
183 const char* script_name,
184 uint64_t file_offset,
185 bool force_load_elf_from_memory =
false) {
186 const char*
error =
nullptr;
187 const uint8_t *vm_data_buffer =
nullptr, *vm_instructions_buffer =
nullptr,
188 *isolate_data_buffer =
nullptr,
189 *isolate_instructions_buffer =
nullptr;
191#if !defined(DART_HOST_OS_FUCHSIA)
192 if (force_load_elf_from_memory) {
196 if (
file ==
nullptr)
return nullptr;
199 if (memory ==
nullptr)
return nullptr;
200 const uint8_t* address =
201 reinterpret_cast<const uint8_t*
>(memory->address());
204 &vm_data_buffer, &vm_instructions_buffer,
205 &isolate_data_buffer, &isolate_instructions_buffer);
208#if !defined(DART_HOST_OS_FUCHSIA)
211 &vm_instructions_buffer, &isolate_data_buffer,
212 &isolate_instructions_buffer);
215 if (handle ==
nullptr) {
219 return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
220 isolate_data_buffer, isolate_instructions_buffer);
223#if defined(DART_TARGET_OS_MACOS)
224AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElfFromMachO(
225 const char* container_path) {
227 if (!IsMachOFormattedBinary(container_path)) {
233 if (
file ==
nullptr) {
236 RefCntReleaseScope<File> rs(
file);
241 mach_o::mach_header
header;
246 "Expected a host endian header but found a byte-swapped header.\n");
252 file->SetPosition(
sizeof(mach_o::mach_header_64));
257 for (uint32_t
i = 0;
i <
header.ncmds; ++
i) {
259 file->ReadFully(&
command,
sizeof(mach_o::load_command));
267 mach_o::note_command note;
268 file->ReadFully(¬e,
sizeof(note));
270 if (strcmp(note.data_owner, kMachOAppSnapshotNoteName) != 0) {
277 return TryReadAppSnapshotElf(container_path, note.offset);
284#if defined(DART_TARGET_OS_WINDOWS)
287static const char kSnapshotSectionName[] =
"snapshot";
291 "Section name of snapshot too large");
293AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElfFromPE(
294 const char* container_path) {
296 if (
file ==
nullptr) {
299 RefCntReleaseScope<File> rs(
file);
302 if (!IsPEFormattedBinary(container_path)) {
304 "Attempted load target was not formatted as expected: "
305 "expected PE32 or PE32+ image file.\n");
312 file->ReadFully(&pe_offset,
sizeof(pe_offset));
315 const intptr_t coff_offset = pe_offset +
sizeof(
pe::kPEMagic);
316 file->SetPosition(coff_offset);
317 pe::coff_file_header file_header;
318 file->ReadFully(&file_header,
sizeof(file_header));
320 pe::coff_optional_header opt_header;
321 file->ReadFully(&opt_header,
sizeof(opt_header));
324 const intptr_t coff_symbol_table_offset =
325 coff_offset +
sizeof(file_header) + file_header.optional_header_size;
326 file->SetPosition(coff_symbol_table_offset);
327 for (intptr_t
i = 0;
i < file_header.num_sections;
i++) {
328 pe::coff_section_header section_header;
329 file->ReadFully(§ion_header,
sizeof(section_header));
330 if (strncmp(section_header.name, kSnapshotSectionName,
336 const char*
error =
nullptr;
337 const uint8_t* vm_data_buffer =
nullptr;
338 const uint8_t* vm_instructions_buffer =
nullptr;
339 const uint8_t* isolate_data_buffer =
nullptr;
340 const uint8_t* isolate_instructions_buffer =
nullptr;
342 const intptr_t
offset = section_header.file_offset;
343 const intptr_t
size = section_header.file_size;
345 std::unique_ptr<uint8_t[]> snapshot(
new uint8_t[
size]);
347 file->ReadFully(snapshot.get(),
sizeof(uint8_t) *
size);
351 &vm_instructions_buffer, &isolate_data_buffer,
352 &isolate_instructions_buffer);
354 if (handle ==
nullptr) {
359 return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
361 isolate_instructions_buffer);
370 const char* container_path) {
371#if defined(DART_TARGET_OS_MACOS)
372 if (IsMachOFormattedBinary(container_path)) {
373 return TryReadAppendedAppSnapshotElfFromMachO(container_path);
375#elif defined(DART_TARGET_OS_WINDOWS)
376 if (IsPEFormattedBinary(container_path)) {
377 return TryReadAppendedAppSnapshotElfFromPE(container_path);
382 if (
file ==
nullptr) {
385 RefCntReleaseScope<File> rs(
file);
389 int64_t appended_header[2];
390 if (!
file->SetPosition(
file->Length() -
sizeof(appended_header))) {
393 if (!
file->ReadFully(&appended_header,
sizeof(appended_header))) {
397 const uint64_t appended_offset =
401 appended_offset <= 0) {
405 return TryReadAppSnapshotElf(container_path, appended_offset);
408class DylibAppSnapshot :
public AppSnapshot {
410 DylibAppSnapshot(
void* library,
415 : AppSnapshot(DartUtils::kAotELFMagicNumber),
424 void SetBuffers(
const uint8_t** vm_data_buffer,
425 const uint8_t** vm_instructions_buffer,
426 const uint8_t** isolate_data_buffer,
427 const uint8_t** isolate_instructions_buffer) {
428 *vm_data_buffer = vm_snapshot_data_;
429 *vm_instructions_buffer = vm_snapshot_instructions_;
430 *isolate_data_buffer = isolate_snapshot_data_;
431 *isolate_instructions_buffer = isolate_snapshot_instructions_;
436 const uint8_t* vm_snapshot_data_;
437 const uint8_t* vm_snapshot_instructions_;
438 const uint8_t* isolate_snapshot_data_;
439 const uint8_t* isolate_snapshot_instructions_;
442static AppSnapshot* TryReadAppSnapshotDynamicLibrary(
const char* script_name) {
444 if (library ==
nullptr) {
448 const uint8_t* vm_data_buffer =
reinterpret_cast<const uint8_t*
>(
451 const uint8_t* vm_instructions_buffer =
455 const uint8_t* isolate_data_buffer =
458 if (isolate_data_buffer ==
nullptr) {
462 const uint8_t* isolate_instructions_buffer =
465 if (isolate_instructions_buffer ==
nullptr) {
466 FATAL(
"Failed to resolve symbol '%s'\n",
470 return new DylibAppSnapshot(library, vm_data_buffer, vm_instructions_buffer,
471 isolate_data_buffer, isolate_instructions_buffer);
476#if defined(DART_TARGET_OS_MACOS)
477bool Snapshot::IsMachOFormattedBinary(
const char* filename) {
479 if (
file ==
nullptr) {
482 RefCntReleaseScope<File> rs(
file);
484 const uint64_t
size =
file->Length();
491 file->SetPosition(0);
499 return size >=
sizeof(mach_o::mach_header);
502 return size >=
sizeof(mach_o::mach_header_64);
510#if defined(DART_TARGET_OS_WINDOWS)
511bool Snapshot::IsPEFormattedBinary(
const char* filename) {
513 if (
file ==
nullptr) {
516 RefCntReleaseScope<File> rs(
file);
526 file->Read(&pe_offset,
sizeof(pe_offset));
530 static_cast<intptr_t
>(pe_offset +
sizeof(
pe::kPEMagic))) {
534 file->SetPosition(pe_offset);
537 file->Read(&c,
sizeof(c));
544 pe::coff_file_header file_header;
545 pe::coff_optional_header opt_header;
546 file->Read(&file_header,
sizeof(file_header));
547 if (file_header.optional_header_size <
sizeof(opt_header)) {
550 file->Read(&opt_header,
sizeof(opt_header));
562 bool force_load_elf_from_memory,
565 const char* script_name =
nullptr;
568 if (decoded_path ==
nullptr) {
571 script_name = decoded_path.get();
573 script_name = script_uri;
582 if (
file ==
nullptr) {
601#if defined(DART_PRECOMPILED_RUNTIME)
609#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_MACOS)
613 script_name = absolute_path.get();
617 if (!force_load_elf_from_memory) {
618 snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
619 if (snapshot !=
nullptr) {
623 return TryReadAppSnapshotElf(script_name, 0,
624 force_load_elf_from_memory);
634#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
637 const intptr_t
size) {
639 if (
file ==
nullptr) {
657 uint8_t* isolate_data_buffer,
658 intptr_t isolate_data_size,
659 uint8_t* isolate_instructions_buffer,
660 intptr_t isolate_instructions_size) {
662 if (
file ==
nullptr) {
676 if (!
file->WriteFully(isolate_data_buffer, isolate_data_size)) {
680 if (isolate_instructions_size != 0) {
685 if (!
file->WriteFully(isolate_instructions_buffer,
686 isolate_instructions_size)) {
697 const char* script_name,
698 const char* package_config) {
699#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
702 uint8_t* kernel_buffer =
nullptr;
703 intptr_t kernel_buffer_size = 0;
704 dfe.
ReadScript(script_name,
nullptr, &kernel_buffer, &kernel_buffer_size);
705 if (kernel_buffer !=
nullptr) {
725#if defined(TARGET_ARCH_IA32)
727 uint8_t* isolate_buffer =
nullptr;
728 intptr_t isolate_size = 0;
731 &isolate_size,
false);
736 WriteAppSnapshot(snapshot_filename, isolate_buffer, isolate_size,
nullptr, 0);
738 uint8_t* isolate_data_buffer =
nullptr;
739 intptr_t isolate_data_size = 0;
740 uint8_t* isolate_instructions_buffer =
nullptr;
741 intptr_t isolate_instructions_size = 0;
743 &isolate_data_buffer, &isolate_data_size, &isolate_instructions_buffer,
744 &isolate_instructions_size);
749 isolate_instructions_buffer, isolate_instructions_size);
765 if (
file ==
nullptr) {
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void * LoadDynamicLibrary(const char *library_path, char **error=nullptr)
static uint64_t LittleEndianToHost64(uint64_t le_value)
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
static void UnloadDynamicLibrary(void *library_handle, char **error=nullptr)
static void * ResolveSymbolInDynamicLibrary(void *library_handle, const char *symbol, char **error=nullptr)
Dart_KernelCompilationResult CompileScript(const char *script_uri, bool incremental, const char *package_config, bool for_snapshot, bool embedd_sources)
void ReadScript(const char *script_uri, const AppSnapshot *app_snapshot, uint8_t **kernel_buffer, intptr_t *kernel_buffer_size, bool decode_uri=true, std::shared_ptr< uint8_t > *kernel_blob_ptr=nullptr)
static MagicNumber SniffForMagicNumber(const char *filename)
static bool IsAotMagicNumber(MagicNumber number)
static constexpr int64_t kMaxMagicNumberSize
DummySnapshot(DartUtils::MagicNumber num)
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)
static CStringUniquePtr UriToPath(const char *uri)
static File * Open(Namespace *namespc, const char *path, FileOpenMode mode)
static Type GetType(Namespace *namespc, const char *path, bool follow_links)
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)
MappedAppSnapshot(MappedMemory *vm_snapshot_data, MappedMemory *vm_snapshot_instructions, MappedMemory *isolate_snapshot_data, MappedMemory *isolate_snapshot_instructions)
static void WriteAppSnapshot(const char *filename, uint8_t *isolate_data_buffer, intptr_t isolate_data_size, uint8_t *isolate_instructions_buffer, intptr_t isolate_instructions_size)
static void GenerateAppAOTAsAssembly(const char *snapshot_filename)
static AppSnapshot * TryReadAppSnapshot(const char *script_uri, bool force_load_elf_from_memory=false, bool decode_uri=true)
static AppSnapshot * TryReadAppendedAppSnapshotElf(const char *container_path)
static void GenerateKernel(const char *snapshot_filename, const char *script_name, const char *package_config)
static void GenerateAppJIT(const char *snapshot_filename)
@ Dart_KernelCompilationStatus_Ok
struct _Dart_Handle * Dart_Handle
#define kIsolateSnapshotDataCSymbol
#define kIsolateSnapshotInstructionsCSymbol
#define kVmSnapshotDataCSymbol
#define kVmSnapshotInstructionsCSymbol
const uint8_t uint32_t uint32_t GError ** error
constexpr int kCompilationErrorExitCode
const uint8_t * isolate_snapshot_data
MagicNumberData appjit_magic_number
static constexpr int64_t kAppSnapshotPageSize
const uint8_t * vm_snapshot_data
const uint8_t * vm_snapshot_instructions
static constexpr int64_t kAppSnapshotHeaderSize
static void StreamingWriteCallback(void *callback_data, const uint8_t *buffer, intptr_t size)
static AppSnapshot * TryReadAppSnapshotBlobs(const char *script_name, File *file)
constexpr int kErrorExitCode
static const char kMachOAppSnapshotNoteName[] DART_UNUSED
void ErrorExit(int exit_code, const char *format,...)
static void WriteSnapshotFile(const char *filename, const uint8_t *buffer, const intptr_t size)
static bool WriteInt64(File *file, int64_t size)
const uint8_t * isolate_snapshot_instructions
static constexpr uint32_t MH_CIGAM
static constexpr uint32_t MH_CIGAM_64
static constexpr uint32_t MH_MAGIC_64
static constexpr uint32_t MH_MAGIC
static constexpr uint32_t LC_NOTE
static const char kPEMagic[]
static constexpr intptr_t kPEOffsetOffset
static constexpr uint16_t kPE32Magic
static constexpr intptr_t kCoffSectionNameSize
static constexpr uint16_t kPE32PlusMagic
constexpr intptr_t kInt64Size
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_CreateAppJITSnapshotAsBlobs(uint8_t **isolate_snapshot_data_buffer, intptr_t *isolate_snapshot_data_size, uint8_t **isolate_snapshot_instructions_buffer, intptr_t *isolate_snapshot_instructions_size)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate()
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback, void *callback_data, bool strip, void *debug_callback_data)
DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t **vm_snapshot_data_buffer, intptr_t *vm_snapshot_data_size, uint8_t **isolate_snapshot_data_buffer, intptr_t *isolate_snapshot_data_size, bool is_core)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static const char header[]
#define LOG_SECTION_BOUNDARIES
const uint8_t bytes[kMaxLength]
DART_EXPORT Dart_LoadedElf * Dart_LoadELF_Memory(const uint8_t *snapshot, uint64_t snapshot_size, const char **error, const uint8_t **vm_snapshot_data, const uint8_t **vm_snapshot_instrs, const uint8_t **vm_isolate_data, const uint8_t **vm_isolate_instrs)
Please see documentation for Dart_LoadElf_Fd.
DART_EXPORT Dart_LoadedElf * Dart_LoadELF(const char *filename, uint64_t file_offset, const char **error, const uint8_t **vm_snapshot_data, const uint8_t **vm_snapshot_instrs, const uint8_t **vm_isolate_data, const uint8_t **vm_isolate_instrs)
Please see documentation for Dart_LoadElf_Fd.
DART_EXPORT void Dart_UnloadELF(Dart_LoadedElf *loaded)