8#if defined(DART_HOST_OS_FUCHSIA)
29#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX)
37 void* start =
nullptr) = 0;
60 void* start =
nullptr)
override {
80 :
Mappable(), memory_(memory), size_(
size), position_(memory) {}
87 void* start =
nullptr)
override {
88 if (position > size_)
return nullptr;
91 if (
start ==
nullptr) {
94 if (memory ==
nullptr)
return nullptr;
103 size_t remainder = 0;
104 if ((position +
length) > size_) {
105 remainder = position +
length - size_;
106 length = size_ - position;
109 memset(
reinterpret_cast<uint8_t*
>(
result->address()) +
length, 0,
133 if (position > size_)
return false;
134 position_ = memory_ + position;
139 if ((position_ +
length) > (memory_ + size_))
return false;
145 const uint8_t*
const memory_;
147 const uint8_t* position_;
155#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX)
170 uint64_t elf_data_offset)
171 : mappable_(
std::move(mappable)), elf_data_offset_(elf_data_offset) {}
193 const uint8_t** vm_instrs,
194 const uint8_t** isolate_data,
195 const uint8_t** isolate_instrs);
197 const char*
error() {
return error_; }
201 bool ReadProgramTable();
203 bool ReadSectionTable();
204 bool ReadSectionStringTable();
212 const void** mapping_start);
215 std::unique_ptr<Mappable> mappable_;
216 const uint64_t elf_data_offset_;
219 const char* error_ =
nullptr;
225 std::unique_ptr<MappedMemory> program_table_mapping_;
229 std::unique_ptr<VirtualMemory> base_;
232 std::unique_ptr<MappedMemory> section_table_mapping_;
236 std::unique_ptr<MappedMemory> section_string_table_mapping_;
237 const char* section_string_table_ =
nullptr;
240 const char* dynamic_string_table_ =
nullptr;
242 uword dynamic_symbol_count_ = 0;
244#if defined(DART_HOST_OS_WINDOWS) && \
245 (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
254#define CHECK(value) \
256 ASSERT(error_ != nullptr); \
260#define ERROR(message) \
262 error_ = (message); \
266#define CHECK_ERROR(value, message) \
268 error_ = (message); \
275 if (error_ !=
nullptr) {
280 "File offset must be page-aligned.");
282 ASSERT(mappable_ !=
nullptr);
283 CHECK_ERROR(mappable_->SetPosition(elf_data_offset_),
"Invalid file offset.");
286 CHECK(ReadProgramTable());
287 CHECK(LoadSegments());
288 CHECK(ReadSectionTable());
289 CHECK(ReadSectionStringTable());
290 CHECK(ReadSections());
298#if defined(DART_HOST_OS_WINDOWS) && \
299 (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
300 for (intptr_t
i = 0;
i < dynamic_runtime_function_tables_.length();
i++) {
302 dynamic_runtime_function_tables_[
i]);
310 program_table_mapping_.reset();
311 section_table_mapping_.reset();
312 section_string_table_mapping_.reset();
315bool LoadedElf::ReadHeader() {
317 "Could not read ELF file.");
320 "Expected little-endian ELF object.");
323 "Can only load dynamic libraries.");
325#if defined(TARGET_ARCH_IA32)
327#elif defined(TARGET_ARCH_X64)
329 "Architecture mismatch.");
330#elif defined(TARGET_ARCH_ARM)
332#elif defined(TARGET_ARCH_ARM64)
334 "Architecture mismatch.");
335#elif defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
338#error Unsupported architecture architecture.
342 "Unexpected ELF version.");
344 "Unexpected header size.");
347 "Unexpected program header size.");
350 "Unexpected section header size.");
355bool LoadedElf::ReadProgramTable() {
357 const uword file_length =
359 program_table_mapping_.reset(
360 MapFilePiece(file_start, file_length,
361 reinterpret_cast<const void**
>(&program_table_)));
363 "Could not mmap the program table.");
367bool LoadedElf::ReadSectionTable() {
369 const uword file_length =
371 section_table_mapping_.reset(
372 MapFilePiece(file_start, file_length,
373 reinterpret_cast<const void**
>(§ion_table_)));
375 "Could not mmap the section table.");
379bool LoadedElf::ReadSectionStringTable() {
382 section_string_table_mapping_.reset(
384 reinterpret_cast<const void**
>(§ion_string_table_)));
385 CHECK_ERROR(section_string_table_mapping_ !=
nullptr,
386 "Could not mmap the section string table.");
390bool LoadedElf::LoadSegments() {
392 uword total_memory = 0;
403 "Alignment must be a power of two.");
409 "dart-compiled-image"));
410 CHECK_ERROR(base_ !=
nullptr,
"Could not reserve virtual memory.");
419 file_offset =
header.file_offset;
421 (memory_offset % PageSize()) == (file_offset % PageSize()),
422 "Difference between file and memory offset must be page-aligned.");
424 const intptr_t adjustment =
header.memory_offset % PageSize();
426 void*
const memory_start =
427 static_cast<char*
>(base_->address()) + memory_offset - adjustment;
428 const uword file_start = elf_data_offset_ + file_offset - adjustment;
439 ERROR(
"Unsupported segment flag set.");
442#if defined(DART_HOST_OS_FUCHSIA)
453 "Could not advance file position.");
455 "Could not read file.");
460 "Could not unmap reservation.");
463 std::unique_ptr<MappedMemory> memory(
464 mappable_->Map(map_type, file_start,
length, memory_start));
465 CHECK_ERROR(memory !=
nullptr,
"Could not map segment.");
467 "Mapping not at requested address.");
468#if defined(DART_HOST_OS_WINDOWS) && \
469 (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
473 void* ptable =
nullptr;
476 dynamic_runtime_function_tables_.Add(ptable);
484bool LoadedElf::ReadSections() {
487 const char*
const name = section_string_table_ +
header.name;
488 if (strcmp(
name,
".dynstr") == 0) {
490 dynamic_string_table_ =
491 static_cast<const char*
>(base_->address()) +
header.memory_offset;
492 }
else if (strcmp(
name,
".dynsym") == 0) {
495 base_->start() +
header.memory_offset);
500 CHECK_ERROR(dynamic_string_table_ !=
nullptr,
"Couldn't find .dynstr.");
501 CHECK_ERROR(dynamic_symbol_table_ !=
nullptr,
"Couldn't find .dynsym.");
506 const uint8_t** vm_instrs,
507 const uint8_t** isolate_data,
508 const uint8_t** isolate_instrs) {
509 if (error_ !=
nullptr) {
514 for (
uword i = 1;
i < dynamic_symbol_count_; ++
i) {
516 const char*
name = dynamic_string_table_ +
sym.name;
517 const uint8_t**
output =
nullptr;
530 *
output =
reinterpret_cast<const uint8_t*
>(base_->start() +
sym.value);
534 CHECK_ERROR(isolate_data ==
nullptr || *isolate_data !=
nullptr,
535 "Could not find isolate snapshot data.");
536 CHECK_ERROR(isolate_instrs ==
nullptr || *isolate_instrs !=
nullptr,
537 "Could not find isolate instructions.");
543 const void** mem_start) {
544 const uword adjustment = (elf_data_offset_ + file_start) % PageSize();
545 const uword mapping_offset = elf_data_offset_ + file_start - adjustment;
546 const uword mapping_length =
547 Utils::RoundUp(elf_data_offset_ + file_start + file_length, PageSize()) -
552 if (mapping !=
nullptr) {
553 *mem_start =
reinterpret_cast<uint8_t*
>(mapping->
start() +
554 (file_start % PageSize()));
566#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX)
568 uint64_t file_offset,
571 const uint8_t** vm_snapshot_instrs,
572 const uint8_t** vm_isolate_data,
573 const uint8_t** vm_isolate_instrs) {
574 std::unique_ptr<Mappable> mappable(Mappable::FromFD(fd));
575 std::unique_ptr<LoadedElf> elf(
576 new LoadedElf(std::move(mappable), file_offset));
580 vm_isolate_data, vm_isolate_instrs)) {
581 *
error = elf->error();
589#if !defined(DART_HOST_OS_FUCHSIA)
591 uint64_t file_offset,
594 const uint8_t** vm_snapshot_instrs,
595 const uint8_t** vm_isolate_data,
596 const uint8_t** vm_isolate_instrs) {
597 std::unique_ptr<Mappable> mappable(Mappable::FromPath(filename));
598 if (mappable ==
nullptr) {
599 *
error =
"Couldn't open file.";
602 std::unique_ptr<LoadedElf> elf(
603 new LoadedElf(std::move(mappable), file_offset));
607 vm_isolate_data, vm_isolate_instrs)) {
608 *
error = elf->error();
617 const uint8_t* snapshot,
618 uint64_t snapshot_size,
621 const uint8_t** vm_snapshot_instrs,
622 const uint8_t** vm_isolate_data,
623 const uint8_t** vm_isolate_instrs) {
624 std::unique_ptr<Mappable> mappable(
625 Mappable::FromMemory(snapshot, snapshot_size));
626 if (mappable ==
nullptr) {
627 *
error =
"Couldn't open file.";
630 std::unique_ptr<LoadedElf> elf(
635 vm_isolate_data, vm_isolate_instrs)) {
636 *
error = elf->error();
644 delete reinterpret_cast<LoadedElf*
>(loaded);
static constexpr T Maximum(T x, T y)
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
static constexpr bool IsPowerOfTwo(T x)
MappedMemory * Map(MapType type, int64_t position, int64_t length, void *start=nullptr)
bool ReadFully(void *buffer, int64_t num_bytes)
static File * Open(Namespace *namespc, const char *path, FileOpenMode mode)
bool SetPosition(int64_t position)
static File * OpenFD(int fd)
static VirtualMemory * Allocate(intptr_t size, bool is_executable, const char *name)
static void Protect(void *address, intptr_t size, Protection mode)
static intptr_t PageSize()
bool SetPosition(uint64_t position) override
bool ReadFully(void *dest, int64_t length) override
MappedMemory * Map(File::MapType type, uint64_t position, uint64_t length, void *start=nullptr) override
LoadedElf(std::unique_ptr< Mappable > mappable, uint64_t elf_data_offset)
bool ResolveSymbols(const uint8_t **vm_data, const uint8_t **vm_instrs, const uint8_t **isolate_data, const uint8_t **isolate_instrs)
static Mappable * FromMemory(const uint8_t *memory, size_t size)
virtual bool ReadFully(void *dest, int64_t length)=0
virtual bool SetPosition(uint64_t position)=0
virtual MappedMemory * Map(File::MapType type, uint64_t position, uint64_t length, void *start=nullptr)=0
static Mappable * FromPath(const char *path)
~MemoryMappable() override
MemoryMappable(const uint8_t *memory, size_t size)
MappedMemory * Map(File::MapType type, uint64_t position, uint64_t length, void *start=nullptr) override
bool ReadFully(void *dest, int64_t length) override
bool SetPosition(uint64_t position) override
#define kIsolateSnapshotDataAsmSymbol
#define kIsolateSnapshotInstructionsAsmSymbol
#define kVmSnapshotDataAsmSymbol
#define kVmSnapshotInstructionsAsmSymbol
const uint8_t uint32_t uint32_t GError ** error
const uint8_t * vm_snapshot_data
static constexpr intptr_t PF_R
static constexpr intptr_t PF_X
static constexpr intptr_t ET_DYN
static constexpr intptr_t EM_X86_64
static constexpr intptr_t EM_386
static constexpr intptr_t EM_RISCV
static constexpr intptr_t EM_AARCH64
static constexpr intptr_t PF_W
static constexpr intptr_t ELFDATA2LSB
static constexpr intptr_t EI_DATA
static constexpr intptr_t EM_ARM
static constexpr intptr_t EV_CURRENT
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
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 mode
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 CHECK_ERROR(value, message)
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)