16#if defined(DART_TARGET_OS_MACOS)
19#if defined(DART_TARGET_OS_WINDOWS)
24#define LOG_SECTION_BOUNDARIES false
32static const char kMachOAppSnapshotNoteName[]
DART_UNUSED =
"__dart_app_snap";
34#if !defined(DART_PRECOMPILED_RUNTIME)
42 const uint8_t** vm_instructions_buffer,
43 const uint8_t** isolate_data_buffer,
44 const uint8_t** isolate_instructions_buffer) {
65 delete vm_data_mapping_;
66 delete vm_instructions_mapping_;
67 delete isolate_data_mapping_;
68 delete isolate_instructions_mapping_;
72 const uint8_t** vm_instructions_buffer,
73 const uint8_t** isolate_data_buffer,
74 const uint8_t** isolate_instructions_buffer) {
75 if (vm_data_mapping_ !=
nullptr) {
77 reinterpret_cast<const uint8_t*
>(vm_data_mapping_->
address());
79 if (vm_instructions_mapping_ !=
nullptr) {
80 *vm_instructions_buffer =
81 reinterpret_cast<const uint8_t*
>(vm_instructions_mapping_->
address());
83 if (isolate_data_mapping_ !=
nullptr) {
84 *isolate_data_buffer =
85 reinterpret_cast<const uint8_t*
>(isolate_data_mapping_->
address());
87 if (isolate_instructions_mapping_ !=
nullptr) {
88 *isolate_instructions_buffer =
reinterpret_cast<const uint8_t*
>(
89 isolate_instructions_mapping_->
address());
111 int64_t vm_data_size =
header[0];
112 int64_t vm_data_position =
114 int64_t vm_instructions_size =
header[1];
115 int64_t vm_instructions_position = vm_data_position + vm_data_size;
116 if (vm_instructions_size != 0) {
117 vm_instructions_position =
120 int64_t isolate_data_size =
header[2];
123 int64_t isolate_instructions_size =
header[3];
124 int64_t isolate_instructions_position =
125 isolate_data_position + isolate_data_size;
126 if (isolate_instructions_size != 0) {
127 isolate_instructions_position =
132 if (vm_data_size != 0) {
135 if (vm_data_mapping ==
nullptr) {
136 FATAL(
"Failed to memory map snapshot: %s\n", script_name);
141 if (vm_instructions_size != 0) {
143 vm_instructions_size);
144 if (vm_instr_mapping ==
nullptr) {
145 FATAL(
"Failed to memory map snapshot: %s\n", script_name);
150 if (isolate_data_size != 0) {
151 isolate_data_mapping =
153 if (isolate_data_mapping ==
nullptr) {
154 FATAL(
"Failed to memory map snapshot: %s\n", script_name);
159 if (isolate_instructions_size != 0) {
160 isolate_instr_mapping =
162 isolate_instructions_size);
163 if (isolate_instr_mapping ==
nullptr) {
164 FATAL(
"Failed to memory map snapshot: %s\n", script_name);
170 isolate_data_mapping, isolate_instr_mapping);
174#if defined(DART_PRECOMPILED_RUNTIME)
175class ElfAppSnapshot :
public AppSnapshot {
178 const uint8_t* vm_snapshot_data,
179 const uint8_t* vm_snapshot_instructions,
180 const uint8_t* isolate_snapshot_data,
181 const uint8_t* isolate_snapshot_instructions)
182 : AppSnapshot{DartUtils::kAotELFMagicNumber},
184 vm_snapshot_data_(vm_snapshot_data),
185 vm_snapshot_instructions_(vm_snapshot_instructions),
186 isolate_snapshot_data_(isolate_snapshot_data),
187 isolate_snapshot_instructions_(isolate_snapshot_instructions) {}
191 void SetBuffers(
const uint8_t** vm_data_buffer,
192 const uint8_t** vm_instructions_buffer,
193 const uint8_t** isolate_data_buffer,
194 const uint8_t** isolate_instructions_buffer) {
195 *vm_data_buffer = vm_snapshot_data_;
196 *vm_instructions_buffer = vm_snapshot_instructions_;
197 *isolate_data_buffer = isolate_snapshot_data_;
198 *isolate_instructions_buffer = isolate_snapshot_instructions_;
203 const uint8_t* vm_snapshot_data_;
204 const uint8_t* vm_snapshot_instructions_;
205 const uint8_t* isolate_snapshot_data_;
206 const uint8_t* isolate_snapshot_instructions_;
209static AppSnapshot* TryReadAppSnapshotElf(
210 const char* script_name,
211 uint64_t file_offset,
212 bool force_load_elf_from_memory =
false) {
213 const char*
error =
nullptr;
214 const uint8_t *vm_data_buffer =
nullptr, *vm_instructions_buffer =
nullptr,
215 *isolate_data_buffer =
nullptr,
216 *isolate_instructions_buffer =
nullptr;
218#if !defined(DART_HOST_OS_FUCHSIA)
219 if (force_load_elf_from_memory) {
223 if (file ==
nullptr)
return nullptr;
226 if (memory ==
nullptr)
return nullptr;
227 const uint8_t* address =
228 reinterpret_cast<const uint8_t*
>(memory->address());
231 &vm_data_buffer, &vm_instructions_buffer,
232 &isolate_data_buffer, &isolate_instructions_buffer);
235#if !defined(DART_HOST_OS_FUCHSIA)
238 &vm_instructions_buffer, &isolate_data_buffer,
239 &isolate_instructions_buffer);
242 if (handle ==
nullptr) {
246 return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
247 isolate_data_buffer, isolate_instructions_buffer);
250#if defined(DART_TARGET_OS_MACOS)
251AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElfFromMachO(
252 const char* container_path) {
254 if (!IsMachOFormattedBinary(container_path)) {
260 if (file ==
nullptr) {
263 RefCntReleaseScope<File> rs(file);
268 mach_o::mach_header
header;
273 "Expected a host endian header but found a byte-swapped header.\n");
279 file->SetPosition(
sizeof(mach_o::mach_header_64));
284 for (uint32_t i = 0; i <
header.ncmds; ++i) {
286 file->ReadFully(&command,
sizeof(mach_o::load_command));
288 file->SetPosition(
file->Position() -
sizeof(command));
294 mach_o::note_command note;
295 file->ReadFully(¬e,
sizeof(note));
297 if (strcmp(note.data_owner, kMachOAppSnapshotNoteName) != 0) {
304 return TryReadAppSnapshotElf(container_path, note.offset);
311#if defined(DART_TARGET_OS_WINDOWS)
314static const char kSnapshotSectionName[] =
"snapshot";
318 "Section name of snapshot too large");
320AppSnapshot* Snapshot::TryReadAppendedAppSnapshotElfFromPE(
321 const char* container_path) {
323 if (file ==
nullptr) {
326 RefCntReleaseScope<File> rs(file);
329 if (!IsPEFormattedBinary(container_path)) {
331 "Attempted load target was not formatted as expected: "
332 "expected PE32 or PE32+ image file.\n");
339 file->ReadFully(&pe_offset,
sizeof(pe_offset));
342 const intptr_t coff_offset = pe_offset +
sizeof(
pe::kPEMagic);
343 file->SetPosition(coff_offset);
344 pe::coff_file_header file_header;
345 file->ReadFully(&file_header,
sizeof(file_header));
347 pe::coff_optional_header opt_header;
348 file->ReadFully(&opt_header,
sizeof(opt_header));
351 const intptr_t coff_symbol_table_offset =
352 coff_offset +
sizeof(file_header) + file_header.optional_header_size;
353 file->SetPosition(coff_symbol_table_offset);
354 for (intptr_t i = 0; i < file_header.num_sections; i++) {
355 pe::coff_section_header section_header;
356 file->ReadFully(§ion_header,
sizeof(section_header));
357 if (strncmp(section_header.name, kSnapshotSectionName,
363 const char*
error =
nullptr;
364 const uint8_t* vm_data_buffer =
nullptr;
365 const uint8_t* vm_instructions_buffer =
nullptr;
366 const uint8_t* isolate_data_buffer =
nullptr;
367 const uint8_t* isolate_instructions_buffer =
nullptr;
369 const intptr_t
offset = section_header.file_offset;
370 const intptr_t
size = section_header.file_size;
372 std::unique_ptr<uint8_t[]> snapshot(
new uint8_t[size]);
374 file->ReadFully(snapshot.get(),
sizeof(uint8_t) * size);
378 &vm_instructions_buffer, &isolate_data_buffer,
379 &isolate_instructions_buffer);
381 if (handle ==
nullptr) {
386 return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
388 isolate_instructions_buffer);
397 const char* container_path) {
398#if defined(DART_TARGET_OS_MACOS)
399 if (IsMachOFormattedBinary(container_path)) {
400 return TryReadAppendedAppSnapshotElfFromMachO(container_path);
402#elif defined(DART_TARGET_OS_WINDOWS)
403 if (IsPEFormattedBinary(container_path)) {
404 return TryReadAppendedAppSnapshotElfFromPE(container_path);
409 if (file ==
nullptr) {
412 RefCntReleaseScope<File> rs(file);
416 int64_t appended_header[2];
417 if (!
file->SetPosition(
file->Length() -
sizeof(appended_header))) {
420 if (!
file->ReadFully(&appended_header,
sizeof(appended_header))) {
424 const uint64_t appended_offset =
428 appended_offset <= 0) {
432 return TryReadAppSnapshotElf(container_path, appended_offset);
435class DylibAppSnapshot :
public AppSnapshot {
437 DylibAppSnapshot(
void* library,
438 const uint8_t* vm_snapshot_data,
439 const uint8_t* vm_snapshot_instructions,
440 const uint8_t* isolate_snapshot_data,
441 const uint8_t* isolate_snapshot_instructions)
442 : AppSnapshot(DartUtils::kAotELFMagicNumber),
449 ~DylibAppSnapshot() { Utils::UnloadDynamicLibrary(library_); }
451 void SetBuffers(
const uint8_t** vm_data_buffer,
452 const uint8_t** vm_instructions_buffer,
453 const uint8_t** isolate_data_buffer,
454 const uint8_t** isolate_instructions_buffer) {
455 *vm_data_buffer = vm_snapshot_data_;
456 *vm_instructions_buffer = vm_snapshot_instructions_;
457 *isolate_data_buffer = isolate_snapshot_data_;
458 *isolate_instructions_buffer = isolate_snapshot_instructions_;
463 const uint8_t* vm_snapshot_data_;
464 const uint8_t* vm_snapshot_instructions_;
465 const uint8_t* isolate_snapshot_data_;
466 const uint8_t* isolate_snapshot_instructions_;
469static AppSnapshot* TryReadAppSnapshotDynamicLibrary(
const char* script_name) {
471 if (library ==
nullptr) {
475 const uint8_t* vm_data_buffer =
reinterpret_cast<const uint8_t*
>(
478 const uint8_t* vm_instructions_buffer =
482 const uint8_t* isolate_data_buffer =
485 if (isolate_data_buffer ==
nullptr) {
489 const uint8_t* isolate_instructions_buffer =
492 if (isolate_instructions_buffer ==
nullptr) {
493 FATAL(
"Failed to resolve symbol '%s'\n",
497 return new DylibAppSnapshot(library, vm_data_buffer, vm_instructions_buffer,
498 isolate_data_buffer, isolate_instructions_buffer);
503#if defined(DART_TARGET_OS_MACOS)
504bool Snapshot::IsMachOFormattedBinary(
const char* filename) {
506 if (file ==
nullptr) {
509 RefCntReleaseScope<File> rs(file);
511 const uint64_t
size =
file->Length();
514 if (size <
sizeof(magic)) {
518 file->SetPosition(0);
519 file->ReadFully(&magic,
sizeof(magic));
526 return size >=
sizeof(mach_o::mach_header);
529 return size >=
sizeof(mach_o::mach_header_64);
537#if defined(DART_TARGET_OS_WINDOWS)
538bool Snapshot::IsPEFormattedBinary(
const char* filename) {
540 if (file ==
nullptr) {
543 RefCntReleaseScope<File> rs(file);
553 file->Read(&pe_offset,
sizeof(pe_offset));
557 static_cast<intptr_t
>(pe_offset +
sizeof(
pe::kPEMagic))) {
561 file->SetPosition(pe_offset);
564 file->Read(&c,
sizeof(c));
571 pe::coff_file_header file_header;
572 pe::coff_optional_header opt_header;
573 file->Read(&file_header,
sizeof(file_header));
574 if (file_header.optional_header_size <
sizeof(opt_header)) {
577 file->Read(&opt_header,
sizeof(opt_header));
589 bool force_load_elf_from_memory,
592 const char* script_name =
nullptr;
595 if (decoded_path ==
nullptr) {
598 script_name = decoded_path.get();
600 script_name = script_uri;
609 if (file ==
nullptr) {
628#if defined(DART_PRECOMPILED_RUNTIME)
636#if defined(DART_TARGET_OS_LINUX) || defined(DART_TARGET_OS_MACOS)
639 std::unique_ptr<char,
decltype(std::free)*> absolute_path{
640 realpath(script_name,
nullptr), std::free};
641 script_name = absolute_path.get();
645 if (!force_load_elf_from_memory) {
646 snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
647 if (snapshot !=
nullptr) {
651 return TryReadAppSnapshotElf(script_name, 0,
652 force_load_elf_from_memory);
662#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
665 const intptr_t size) {
667 if (file ==
nullptr) {
672 if (!file->WriteFully(
buffer, size)) {
681 return file->WriteFully(&size,
sizeof(size));
685 uint8_t* vm_data_buffer,
686 intptr_t vm_data_size,
687 uint8_t* vm_instructions_buffer,
688 intptr_t vm_instructions_size,
689 uint8_t* isolate_data_buffer,
690 intptr_t isolate_data_size,
691 uint8_t* isolate_instructions_buffer,
692 intptr_t isolate_instructions_size) {
694 if (file ==
nullptr) {
703 ASSERT(file->Position() ==
710 if (!file->WriteFully(vm_data_buffer, vm_data_size)) {
714 if (vm_instructions_size != 0) {
719 if (!file->WriteFully(vm_instructions_buffer, vm_instructions_size)) {
729 if (!file->WriteFully(isolate_data_buffer, isolate_data_size)) {
733 if (isolate_instructions_size != 0) {
738 if (!file->WriteFully(isolate_instructions_buffer,
739 isolate_instructions_size)) {
750 const char* script_name,
751 const char* package_config) {
752#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
755 uint8_t* kernel_buffer =
nullptr;
756 intptr_t kernel_buffer_size = 0;
757 dfe.
ReadScript(script_name,
nullptr, &kernel_buffer, &kernel_buffer_size);
758 if (kernel_buffer !=
nullptr) {
778#if defined(TARGET_ARCH_IA32)
780 uint8_t* isolate_buffer =
nullptr;
781 intptr_t isolate_size = 0;
784 &isolate_size,
false);
790 isolate_size,
nullptr, 0);
792 uint8_t* isolate_data_buffer =
nullptr;
793 intptr_t isolate_data_size = 0;
794 uint8_t* isolate_instructions_buffer =
nullptr;
795 intptr_t isolate_instructions_size = 0;
797 &isolate_data_buffer, &isolate_data_size, &isolate_instructions_buffer,
798 &isolate_instructions_size);
803 isolate_data_buffer, isolate_data_size,
804 isolate_instructions_buffer, isolate_instructions_size);
811 File* file =
reinterpret_cast<File*
>(callback_data);
812 if (!file->WriteFully(
buffer, size)) {
820 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)
std::unique_ptr< char, decltype(std::free) * > CStringUniquePtr
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
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 Utils::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 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)
static void WriteAppSnapshot(const char *filename, uint8_t *vm_data_buffer, intptr_t vm_data_size, uint8_t *vm_instructions_buffer, intptr_t vm_instructions_size, uint8_t *isolate_data_buffer, intptr_t isolate_data_size, uint8_t *isolate_instructions_buffer, intptr_t isolate_instructions_size)
@ Dart_KernelCompilationStatus_Ok
struct _Dart_Handle * Dart_Handle
#define kIsolateSnapshotDataCSymbol
#define kIsolateSnapshotInstructionsCSymbol
#define kVmSnapshotDataCSymbol
#define kVmSnapshotInstructionsCSymbol
static const uint8_t buffer[]
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)
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)