Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
elf_loader.cc
Go to the documentation of this file.
1// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "bin/elf_loader.h"
6
7#include "platform/globals.h"
8#if defined(DART_HOST_OS_FUCHSIA)
9#include <sys/mman.h>
10#endif
11
12#include <memory>
13#include <utility>
14
15#include "bin/file.h"
16#include "bin/virtual_memory.h"
17#include "platform/elf.h"
18
20
21namespace dart {
22namespace bin {
23
24namespace elf {
25
26class Mappable {
27 public:
28 static Mappable* FromPath(const char* path);
29#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX)
30 static Mappable* FromFD(int fd);
31#endif
32 static Mappable* FromMemory(const uint8_t* memory, size_t size);
33
35 uint64_t position,
36 uint64_t length,
37 void* start = nullptr) = 0;
38
39 virtual bool SetPosition(uint64_t position) = 0;
40 virtual bool ReadFully(void* dest, int64_t length) = 0;
41
42 virtual ~Mappable() {}
43
44 protected:
46
47 private:
49};
50
51class FileMappable : public Mappable {
52 public:
53 explicit FileMappable(File* file) : Mappable(), file_(file) {}
54
55 ~FileMappable() override { file_->Release(); }
56
58 uint64_t position,
59 uint64_t length,
60 void* start = nullptr) override {
61 return file_->Map(type, position, length, start);
62 }
63
64 bool SetPosition(uint64_t position) override {
65 return file_->SetPosition(position);
66 }
67
68 bool ReadFully(void* dest, int64_t length) override {
69 return file_->ReadFully(dest, length);
70 }
71
72 private:
73 File* const file_;
75};
76
77class MemoryMappable : public Mappable {
78 public:
79 MemoryMappable(const uint8_t* memory, size_t size)
80 : Mappable(), memory_(memory), size_(size), position_(memory) {}
81
82 ~MemoryMappable() override {}
83
85 uint64_t position,
86 uint64_t length,
87 void* start = nullptr) override {
88 if (position > size_) return nullptr;
89 MappedMemory* result = nullptr;
91 if (start == nullptr) {
92 auto* memory = VirtualMemory::Allocate(
93 map_size, type == File::kReadExecute, "dart-compiled-image");
94 if (memory == nullptr) return nullptr;
95 result = new MappedMemory(memory->address(), memory->size());
96 memory->release();
97 delete memory;
98 } else {
99 result = new MappedMemory(start, map_size,
100 /*should_unmap=*/false);
101 }
102
103 size_t remainder = 0;
104 if ((position + length) > size_) {
105 remainder = position + length - size_;
106 length = size_ - position;
107 }
108 memcpy(result->address(), memory_ + position, length); // NOLINT
109 memset(reinterpret_cast<uint8_t*>(result->address()) + length, 0,
110 remainder);
111
112 auto mode = VirtualMemory::kReadOnly;
113 switch (type) {
116 break;
117 case File::kReadWrite:
119 break;
120 case File::kReadOnly:
122 break;
123 default:
124 UNREACHABLE();
125 }
126
127 VirtualMemory::Protect(result->address(), result->size(), mode);
128
129 return result;
130 }
131
132 bool SetPosition(uint64_t position) override {
133 if (position > size_) return false;
134 position_ = memory_ + position;
135 return true;
136 }
137
138 bool ReadFully(void* dest, int64_t length) override {
139 if ((position_ + length) > (memory_ + size_)) return false;
140 memcpy(dest, position_, length);
141 return true;
142 }
143
144 private:
145 const uint8_t* const memory_;
146 const size_t size_;
147 const uint8_t* position_;
149};
150
151Mappable* Mappable::FromPath(const char* path) {
152 return new FileMappable(File::Open(/*namespc=*/nullptr, path, File::kRead));
153}
154
155#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX)
156Mappable* Mappable::FromFD(int fd) {
157 return new FileMappable(File::OpenFD(fd));
158}
159#endif
160
161Mappable* Mappable::FromMemory(const uint8_t* memory, size_t size) {
162 return new MemoryMappable(memory, size);
163}
164
165/// A loader for a subset of ELF which may be used to load objects produced by
166/// Dart_CreateAppAOTSnapshotAsElf.
168 public:
169 explicit LoadedElf(std::unique_ptr<Mappable> mappable,
170 uint64_t elf_data_offset)
171 : mappable_(std::move(mappable)), elf_data_offset_(elf_data_offset) {}
172
173 ~LoadedElf();
174
175 /// Loads the ELF object into memory. Returns whether the load was successful.
176 /// On failure, the error may be retrieved by 'error()'.
177 bool Load();
178
179 /// Reads Dart-specific symbols from the loaded ELF.
180 ///
181 /// Stores the address of the corresponding symbol in each non-null output
182 /// parameter.
183 ///
184 /// Fails if any output parameter is non-null but points to null and the
185 /// corresponding symbol was not found, or if the dynamic symbol table could
186 /// not be decoded.
187 ///
188 /// Has the side effect of initializing the relocated addresses for the text
189 /// sections corresponding to non-null output parameters in the BSS segment.
190 ///
191 /// On failure, the error may be retrieved by 'error()'.
192 bool ResolveSymbols(const uint8_t** vm_data,
193 const uint8_t** vm_instrs,
194 const uint8_t** isolate_data,
195 const uint8_t** isolate_instrs);
196
197 const char* error() { return error_; }
198
199 private:
200 bool ReadHeader();
201 bool ReadProgramTable();
202 bool LoadSegments();
203 bool ReadSectionTable();
204 bool ReadSectionStringTable();
205 bool ReadSections();
206
207 static uword PageSize() { return VirtualMemory::PageSize(); }
208
209 // Unlike File::Map, allows non-aligned 'start' and 'length'.
210 MappedMemory* MapFilePiece(uword start,
212 const void** mapping_start);
213
214 // Initialized on a successful Load().
215 std::unique_ptr<Mappable> mappable_;
216 const uint64_t elf_data_offset_;
217
218 // Initialized on error.
219 const char* error_ = nullptr;
220
221 // Initialized by ReadHeader().
222 dart::elf::ElfHeader header_;
223
224 // Initialized by ReadProgramTable().
225 std::unique_ptr<MappedMemory> program_table_mapping_;
226 const dart::elf::ProgramHeader* program_table_ = nullptr;
227
228 // Initialized by LoadSegments().
229 std::unique_ptr<VirtualMemory> base_;
230
231 // Initialized by ReadSectionTable().
232 std::unique_ptr<MappedMemory> section_table_mapping_;
233 const dart::elf::SectionHeader* section_table_ = nullptr;
234
235 // Initialized by ReadSectionStringTable().
236 std::unique_ptr<MappedMemory> section_string_table_mapping_;
237 const char* section_string_table_ = nullptr;
238
239 // Initialized by ReadSections().
240 const char* dynamic_string_table_ = nullptr;
241 const dart::elf::Symbol* dynamic_symbol_table_ = nullptr;
242 uword dynamic_symbol_count_ = 0;
243
244#if defined(DART_HOST_OS_WINDOWS) && \
245 (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
246 // Dynamic table for looking up unwinding exceptions info.
247 // Initialized by LoadSegments as we load executable segment.
248 MallocGrowableArray<void*> dynamic_runtime_function_tables_;
249#endif
250
252};
253
254#define CHECK(value) \
255 if (!(value)) { \
256 ASSERT(error_ != nullptr); \
257 return false; \
258 }
259
260#define ERROR(message) \
261 { \
262 error_ = (message); \
263 return false; \
264 }
265
266#define CHECK_ERROR(value, message) \
267 if (!(value)) { \
268 error_ = (message); \
269 return false; \
270 }
271
274
275 if (error_ != nullptr) {
276 return false;
277 }
278
279 CHECK_ERROR(Utils::IsAligned(elf_data_offset_, PageSize()),
280 "File offset must be page-aligned.");
281
282 ASSERT(mappable_ != nullptr);
283 CHECK_ERROR(mappable_->SetPosition(elf_data_offset_), "Invalid file offset.");
284
285 CHECK(ReadHeader());
286 CHECK(ReadProgramTable());
287 CHECK(LoadSegments());
288 CHECK(ReadSectionTable());
289 CHECK(ReadSectionStringTable());
290 CHECK(ReadSections());
291
292 mappable_.reset();
293
294 return true;
295}
296
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]);
303 }
304#endif
305
306 // Unmap the image.
307 base_.reset();
308
309 // Explicitly destroy all the mappings before closing the file.
310 program_table_mapping_.reset();
311 section_table_mapping_.reset();
312 section_string_table_mapping_.reset();
313}
314
315bool LoadedElf::ReadHeader() {
316 CHECK_ERROR(mappable_->ReadFully(&header_, sizeof(dart::elf::ElfHeader)),
317 "Could not read ELF file.");
318
320 "Expected little-endian ELF object.");
321
323 "Can only load dynamic libraries.");
324
325#if defined(TARGET_ARCH_IA32)
326 CHECK_ERROR(header_.machine == dart::elf::EM_386, "Architecture mismatch.");
327#elif defined(TARGET_ARCH_X64)
329 "Architecture mismatch.");
330#elif defined(TARGET_ARCH_ARM)
331 CHECK_ERROR(header_.machine == dart::elf::EM_ARM, "Architecture mismatch.");
332#elif defined(TARGET_ARCH_ARM64)
334 "Architecture mismatch.");
335#elif defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
336 CHECK_ERROR(header_.machine == dart::elf::EM_RISCV, "Architecture mismatch.");
337#else
338#error Unsupported architecture architecture.
339#endif
340
342 "Unexpected ELF version.");
344 "Unexpected header size.");
347 "Unexpected program header size.");
350 "Unexpected section header size.");
351
352 return true;
353}
354
355bool LoadedElf::ReadProgramTable() {
356 const uword file_start = header_.program_table_offset;
357 const uword file_length =
359 program_table_mapping_.reset(
360 MapFilePiece(file_start, file_length,
361 reinterpret_cast<const void**>(&program_table_)));
362 CHECK_ERROR(program_table_mapping_ != nullptr,
363 "Could not mmap the program table.");
364 return true;
365}
366
367bool LoadedElf::ReadSectionTable() {
368 const uword file_start = header_.section_table_offset;
369 const uword file_length =
371 section_table_mapping_.reset(
372 MapFilePiece(file_start, file_length,
373 reinterpret_cast<const void**>(&section_table_)));
374 CHECK_ERROR(section_table_mapping_ != nullptr,
375 "Could not mmap the section table.");
376 return true;
377}
378
379bool LoadedElf::ReadSectionStringTable() {
381 section_table_[header_.shstrtab_section_index];
382 section_string_table_mapping_.reset(
383 MapFilePiece(header.file_offset, header.file_size,
384 reinterpret_cast<const void**>(&section_string_table_)));
385 CHECK_ERROR(section_string_table_mapping_ != nullptr,
386 "Could not mmap the section string table.");
387 return true;
388}
389
390bool LoadedElf::LoadSegments() {
391 // Calculate the total amount of virtual memory needed.
392 uword total_memory = 0;
393 for (uword i = 0; i < header_.num_program_headers; ++i) {
394 const dart::elf::ProgramHeader header = program_table_[i];
395
396 // Only PT_LOAD segments need to be loaded.
397 if (header.type != dart::elf::ProgramHeaderType::PT_LOAD) continue;
398
399 total_memory = Utils::Maximum(
400 static_cast<uword>(header.memory_offset + header.memory_size),
401 total_memory);
403 "Alignment must be a power of two.");
404 }
405 total_memory = Utils::RoundUp(total_memory, PageSize());
406
407 base_.reset(VirtualMemory::Allocate(total_memory,
408 /*is_executable=*/false,
409 "dart-compiled-image"));
410 CHECK_ERROR(base_ != nullptr, "Could not reserve virtual memory.");
411
412 for (uword i = 0; i < header_.num_program_headers; ++i) {
413 const dart::elf::ProgramHeader header = program_table_[i];
414
415 // Only PT_LOAD segments need to be loaded.
416 if (header.type != dart::elf::ProgramHeaderType::PT_LOAD) continue;
417
418 const uword memory_offset = header.memory_offset,
419 file_offset = header.file_offset;
421 (memory_offset % PageSize()) == (file_offset % PageSize()),
422 "Difference between file and memory offset must be page-aligned.");
423
424 const intptr_t adjustment = header.memory_offset % PageSize();
425
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;
429 const uword length = header.memory_size + adjustment;
430
432 if (header.flags == (dart::elf::PF_R | dart::elf::PF_W)) {
433 map_type = File::kReadWrite;
434 } else if (header.flags == (dart::elf::PF_R | dart::elf::PF_X)) {
435 map_type = File::kReadExecute;
436 } else if (header.flags == dart::elf::PF_R) {
437 map_type = File::kReadOnly;
438 } else {
439 ERROR("Unsupported segment flag set.");
440 }
441
442#if defined(DART_HOST_OS_FUCHSIA)
443 // mmap is less flexible on Fuchsia than on Linux and Darwin, in (at least)
444 // two important ways:
445 //
446 // 1. We cannot map a file opened as RX into an RW mapping, even if the
447 // mode is MAP_PRIVATE (which implies copy-on-write).
448 // 2. We cannot atomically replace an existing anonymous mapping with a
449 // file mapping: we must first unmap the existing mapping.
450
451 if (map_type == File::kReadWrite) {
452 CHECK_ERROR(mappable_->SetPosition(file_start),
453 "Could not advance file position.");
454 CHECK_ERROR(mappable_->ReadFully(memory_start, length),
455 "Could not read file.");
456 continue;
457 }
458
459 CHECK_ERROR(munmap(memory_start, length) == 0,
460 "Could not unmap reservation.");
461#endif
462
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.");
466 CHECK_ERROR(memory->address() == memory_start,
467 "Mapping not at requested address.");
468#if defined(DART_HOST_OS_WINDOWS) && \
469 (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
470 // For executable pages register unwinding information that should be
471 // present on the page.
472 if (map_type == File::kReadExecute) {
473 void* ptable = nullptr;
475 length, &ptable);
476 dynamic_runtime_function_tables_.Add(ptable);
477 }
478#endif
479 }
480
481 return true;
482}
483
484bool LoadedElf::ReadSections() {
485 for (uword i = 0; i < header_.num_section_headers; ++i) {
486 const dart::elf::SectionHeader header = section_table_[i];
487 const char* const name = section_string_table_ + header.name;
488 if (strcmp(name, ".dynstr") == 0) {
489 CHECK_ERROR(header.memory_offset != 0, ".dynstr must be loaded.");
490 dynamic_string_table_ =
491 static_cast<const char*>(base_->address()) + header.memory_offset;
492 } else if (strcmp(name, ".dynsym") == 0) {
493 CHECK_ERROR(header.memory_offset != 0, ".dynsym must be loaded.");
494 dynamic_symbol_table_ = reinterpret_cast<const dart::elf::Symbol*>(
495 base_->start() + header.memory_offset);
496 dynamic_symbol_count_ = header.file_size / sizeof(dart::elf::Symbol);
497 }
498 }
499
500 CHECK_ERROR(dynamic_string_table_ != nullptr, "Couldn't find .dynstr.");
501 CHECK_ERROR(dynamic_symbol_table_ != nullptr, "Couldn't find .dynsym.");
502 return true;
503}
504
505bool LoadedElf::ResolveSymbols(const uint8_t** vm_data,
506 const uint8_t** vm_instrs,
507 const uint8_t** isolate_data,
508 const uint8_t** isolate_instrs) {
509 if (error_ != nullptr) {
510 return false;
511 }
512
513 // The first entry of the symbol table is reserved.
514 for (uword i = 1; i < dynamic_symbol_count_; ++i) {
515 const dart::elf::Symbol sym = dynamic_symbol_table_[i];
516 const char* name = dynamic_string_table_ + sym.name;
517 const uint8_t** output = nullptr;
518
519 if (strcmp(name, kVmSnapshotDataAsmSymbol) == 0) {
520 output = vm_data;
521 } else if (strcmp(name, kVmSnapshotInstructionsAsmSymbol) == 0) {
522 output = vm_instrs;
523 } else if (strcmp(name, kIsolateSnapshotDataAsmSymbol) == 0) {
524 output = isolate_data;
525 } else if (strcmp(name, kIsolateSnapshotInstructionsAsmSymbol) == 0) {
526 output = isolate_instrs;
527 }
528
529 if (output != nullptr) {
530 *output = reinterpret_cast<const uint8_t*>(base_->start() + sym.value);
531 }
532 }
533
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.");
538 return true;
539}
540
541MappedMemory* LoadedElf::MapFilePiece(uword file_start,
542 uword file_length,
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()) -
548 mapping_offset;
549 MappedMemory* const mapping =
550 mappable_->Map(bin::File::kReadOnly, mapping_offset, mapping_length);
551
552 if (mapping != nullptr) {
553 *mem_start = reinterpret_cast<uint8_t*>(mapping->start() +
554 (file_start % PageSize()));
555 }
556
557 return mapping;
558}
559
560} // namespace elf
561} // namespace bin
562} // namespace dart
563
564using namespace dart::bin::elf; // NOLINT
565
566#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_LINUX)
567DART_EXPORT Dart_LoadedElf* Dart_LoadELF_Fd(int fd,
568 uint64_t file_offset,
569 const char** error,
570 const uint8_t** vm_snapshot_data,
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));
577
578 if (!elf->Load() ||
579 !elf->ResolveSymbols(vm_snapshot_data, vm_snapshot_instrs,
580 vm_isolate_data, vm_isolate_instrs)) {
581 *error = elf->error();
582 return nullptr;
583 }
584
585 return reinterpret_cast<Dart_LoadedElf*>(elf.release());
586}
587#endif
588
589#if !defined(DART_HOST_OS_FUCHSIA)
591 uint64_t file_offset,
592 const char** error,
593 const uint8_t** vm_snapshot_data,
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.";
600 return nullptr;
601 }
602 std::unique_ptr<LoadedElf> elf(
603 new LoadedElf(std::move(mappable), file_offset));
604
605 if (!elf->Load() ||
606 !elf->ResolveSymbols(vm_snapshot_data, vm_snapshot_instrs,
607 vm_isolate_data, vm_isolate_instrs)) {
608 *error = elf->error();
609 return nullptr;
610 }
611
612 return reinterpret_cast<Dart_LoadedElf*>(elf.release());
613}
614#endif
615
617 const uint8_t* snapshot,
618 uint64_t snapshot_size,
619 const char** error,
620 const uint8_t** vm_snapshot_data,
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.";
628 return nullptr;
629 }
630 std::unique_ptr<LoadedElf> elf(
631 new LoadedElf(std::move(mappable), /*file_offset=*/0));
632
633 if (!elf->Load() ||
634 !elf->ResolveSymbols(vm_snapshot_data, vm_snapshot_instrs,
635 vm_isolate_data, vm_isolate_instrs)) {
636 *error = elf->error();
637 return nullptr;
638 }
639
640 return reinterpret_cast<Dart_LoadedElf*>(elf.release());
641}
642
644 delete reinterpret_cast<LoadedElf*>(loaded);
645}
#define UNREACHABLE()
Definition assert.h:248
static void RegisterExecutableMemory(void *start, intptr_t size, void **pp_dynamic_table)
static void UnregisterDynamicTable(void *p_dynamic_table)
static constexpr T Maximum(T x, T y)
Definition utils.h:26
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:105
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77
static constexpr bool IsPowerOfTwo(T x)
Definition utils.h:61
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)
uword start() const
Definition file.h:36
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
Definition elf_loader.cc:64
bool ReadFully(void *dest, int64_t length) override
Definition elf_loader.cc:68
MappedMemory * Map(File::MapType type, uint64_t position, uint64_t length, void *start=nullptr) override
Definition elf_loader.cc:57
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(const uint8_t *memory, size_t size)
Definition elf_loader.cc:79
MappedMemory * Map(File::MapType type, uint64_t position, uint64_t length, void *start=nullptr) override
Definition elf_loader.cc:84
bool ReadFully(void *dest, int64_t length) override
bool SetPosition(uint64_t position) override
#define kIsolateSnapshotDataAsmSymbol
Definition dart_api.h:3910
#define kIsolateSnapshotInstructionsAsmSymbol
Definition dart_api.h:3911
#define kVmSnapshotDataAsmSymbol
Definition dart_api.h:3907
#define kVmSnapshotInstructionsAsmSymbol
Definition dart_api.h:3908
#define ASSERT(E)
#define DART_EXPORT
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
size_t length
static constexpr intptr_t PF_R
Definition elf.h:181
static constexpr intptr_t PF_X
Definition elf.h:179
static constexpr intptr_t ET_DYN
Definition elf.h:165
static constexpr intptr_t EM_X86_64
Definition elf.h:173
static constexpr intptr_t EM_386
Definition elf.h:171
static constexpr intptr_t EM_RISCV
Definition elf.h:175
static constexpr intptr_t EM_AARCH64
Definition elf.h:174
static constexpr intptr_t PF_W
Definition elf.h:180
static constexpr intptr_t ELFDATA2LSB
Definition elf.h:161
static constexpr intptr_t EI_DATA
Definition elf.h:160
static constexpr intptr_t EM_ARM
Definition elf.h:172
static constexpr intptr_t EV_CURRENT
Definition elf.h:177
const char *const name
uintptr_t uword
Definition globals.h:501
Definition ref_ptr.h:256
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
static const char header[]
Definition skpbench.cpp:88
uint16_t shstrtab_section_index
Definition elf.h:35
uint8_t ident[16]
Definition elf.h:16
uint16_t machine
Definition elf.h:18
uint16_t program_table_entry_size
Definition elf.h:31
uint64_t section_table_offset
Definition elf.h:27
uint16_t num_section_headers
Definition elf.h:34
uint16_t num_program_headers
Definition elf.h:32
uint16_t header_size
Definition elf.h:30
uint16_t type
Definition elf.h:17
uint64_t program_table_offset
Definition elf.h:26
uint32_t version
Definition elf.h:19
uint16_t section_table_entry_size
Definition elf.h:33
uint64_t memory_offset
Definition elf.h:61
#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.
#define CHECK(value)
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.
#define ERROR(message)
DART_EXPORT void Dart_UnloadELF(Dart_LoadedElf *loaded)