| // Copyright (c) 2019, 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. | |
| #ifndef RUNTIME_PLATFORM_ELF_H_ | |
| #define RUNTIME_PLATFORM_ELF_H_ | |
| #include "platform/globals.h" | |
| namespace dart { | |
| namespace elf { | |
| #pragma pack(push, 1) | |
| static constexpr uint8_t ELFMAG[] = {'\x7f', 'E', 'L', 'F'}; | |
| struct ElfHeader { | |
| uint8_t ident[16]; | |
| uint16_t type; | |
| uint16_t machine; | |
| uint32_t version; | |
| #if defined(TARGET_ARCH_IS_32_BIT) | |
| uint32_t entry_point; | |
| uint32_t program_table_offset; | |
| uint32_t section_table_offset; | |
| #else | |
| uint64_t entry_point; | |
| uint64_t program_table_offset; | |
| uint64_t section_table_offset; | |
| #endif | |
| uint32_t flags; | |
| uint16_t header_size; | |
| uint16_t program_table_entry_size; | |
| uint16_t num_program_headers; | |
| uint16_t section_table_entry_size; | |
| uint16_t num_section_headers; | |
| uint16_t shstrtab_section_index; | |
| }; | |
| enum class ProgramHeaderType : uint32_t { | |
| PT_NULL = 0, | |
| PT_LOAD = 1, | |
| PT_DYNAMIC = 2, | |
| PT_NOTE = 4, | |
| PT_PHDR = 6, | |
| PT_GNU_STACK = 0x6474e551, | |
| PT_GNU_PROPERTY = 0x6474e553, | |
| }; | |
| struct ProgramHeader { | |
| #if defined(TARGET_ARCH_IS_32_BIT) | |
| ProgramHeaderType type; | |
| uint32_t file_offset; | |
| uint32_t memory_offset; | |
| uint32_t physical_memory_offset; | |
| uint32_t file_size; | |
| uint32_t memory_size; | |
| uint32_t flags; | |
| uint32_t alignment; | |
| #else | |
| ProgramHeaderType type; | |
| uint32_t flags; | |
| uint64_t file_offset; | |
| uint64_t memory_offset; | |
| uint64_t physical_memory_offset; | |
| uint64_t file_size; | |
| uint64_t memory_size; | |
| uint64_t alignment; | |
| #endif | |
| }; | |
| enum class SectionHeaderType : uint32_t { | |
| SHT_NULL = 0, | |
| SHT_PROGBITS = 1, | |
| SHT_SYMTAB = 2, | |
| SHT_STRTAB = 3, | |
| SHT_HASH = 5, | |
| SHT_NOTE = 7, | |
| SHT_NOBITS = 8, | |
| SHT_DYNAMIC = 6, | |
| SHT_DYNSYM = 11, | |
| }; | |
| struct SectionHeader { | |
| #if defined(TARGET_ARCH_IS_32_BIT) | |
| uint32_t name; | |
| SectionHeaderType type; | |
| uint32_t flags; | |
| uint32_t memory_offset; | |
| uint32_t file_offset; | |
| uint32_t file_size; | |
| uint32_t link; | |
| uint32_t info; | |
| uint32_t alignment; | |
| uint32_t entry_size; | |
| #else | |
| uint32_t name; | |
| SectionHeaderType type; | |
| uint64_t flags; | |
| uint64_t memory_offset; | |
| uint64_t file_offset; | |
| uint64_t file_size; | |
| uint32_t link; | |
| uint32_t info; | |
| uint64_t alignment; | |
| uint64_t entry_size; | |
| #endif | |
| }; | |
| struct Symbol { | |
| #if defined(TARGET_ARCH_IS_32_BIT) | |
| uint32_t name; | |
| uint32_t value; | |
| uint32_t size; | |
| uint8_t info; | |
| uint8_t other; // Reserved by ELF. | |
| uint16_t section; | |
| #else | |
| uint32_t name; | |
| uint8_t info; | |
| uint8_t other; // Reserved by ELF. | |
| uint16_t section; | |
| uint64_t value; | |
| uint64_t size; | |
| #endif | |
| }; | |
| enum class DynamicEntryType : uint32_t { | |
| DT_NULL = 0, | |
| DT_HASH = 4, | |
| DT_STRTAB = 5, | |
| DT_SYMTAB = 6, | |
| DT_STRSZ = 10, | |
| DT_SYMENT = 11, | |
| }; | |
| struct DynamicEntry { | |
| #if defined(TARGET_ARCH_IS_32_BIT) | |
| uint32_t tag; | |
| uint32_t value; | |
| #else | |
| uint64_t tag; | |
| uint64_t value; | |
| #endif | |
| }; | |
| enum class NoteType : uint32_t { | |
| NT_GNU_BUILD_ID = 3, | |
| NT_GNU_PROPERTY_TYPE_0 = 5, | |
| }; | |
| struct Note { | |
| uint32_t name_size; | |
| uint32_t description_size; | |
| NoteType type; | |
| uint8_t data[]; | |
| }; | |
| #pragma pack(pop) | |
| static constexpr intptr_t ELFCLASS32 = 1; | |
| static constexpr intptr_t ELFCLASS64 = 2; | |
| static constexpr intptr_t EI_DATA = 5; | |
| static constexpr intptr_t ELFDATA2LSB = 1; | |
| static constexpr intptr_t ELFOSABI_SYSV = 0; | |
| static constexpr intptr_t ET_DYN = 3; | |
| static constexpr intptr_t EF_ARM_ABI_FLOAT_HARD = 0x00000400; | |
| static constexpr intptr_t EF_ARM_ABI_FLOAT_SOFT = 0x00000200; | |
| static constexpr intptr_t EF_ARM_ABI = 0x05000000; | |
| static constexpr intptr_t EF_RISCV_RVC = 0x1; | |
| static constexpr intptr_t EF_RISCV_FLOAT_ABI_DOUBLE = 0x4; | |
| static constexpr intptr_t EM_386 = 3; | |
| static constexpr intptr_t EM_ARM = 40; | |
| static constexpr intptr_t EM_X86_64 = 62; | |
| static constexpr intptr_t EM_AARCH64 = 183; | |
| static constexpr intptr_t EM_RISCV = 243; | |
| static constexpr intptr_t EV_CURRENT = 1; | |
| static constexpr intptr_t PF_X = 1; | |
| static constexpr intptr_t PF_W = 2; | |
| static constexpr intptr_t PF_R = 4; | |
| static constexpr intptr_t SHF_WRITE = 0x1; | |
| static constexpr intptr_t SHF_ALLOC = 0x2; | |
| static constexpr intptr_t SHF_EXECINSTR = 0x4; | |
| static constexpr intptr_t SHN_UNDEF = 0; | |
| static constexpr intptr_t STN_UNDEF = 0; | |
| static constexpr intptr_t STB_LOCAL = 0; | |
| static constexpr intptr_t STB_GLOBAL = 1; | |
| static constexpr intptr_t STT_NOTYPE = 0; | |
| static constexpr intptr_t STT_OBJECT = 1; // I.e., data. | |
| static constexpr intptr_t STT_FUNC = 2; | |
| static constexpr intptr_t STT_SECTION = 3; | |
| static constexpr const char ELF_NOTE_GNU[] = "GNU"; | |
| #define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 | |
| #define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0) | |
| #define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1) | |
| #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 | |
| #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) | |
| #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) | |
| #define GNU_PROPERTY_AARCH64_FEATURE_1_GCS (1U << 2) | |
| // Creates symbol info from the given STB and STT values. | |
| constexpr decltype(Symbol::info) SymbolInfo(intptr_t binding, intptr_t type) { | |
| // Take the low nibble of each value in case, though the upper bits should | |
| // all be zero as long as STB/STT constants are used. | |
| return (binding & 0xf) << 4 | (type & 0xf); | |
| } | |
| // Retrieves the STB binding value for the given symbol info. | |
| constexpr intptr_t SymbolBinding(const decltype(Symbol::info) info) { | |
| return (info >> 4) & 0xf; | |
| } | |
| // Retrieves the STT type value for the given symbol info. | |
| constexpr intptr_t SymbolType(const decltype(Symbol::info) info) { | |
| return info & 0xf; | |
| } | |
| } // namespace elf | |
| } // namespace dart | |
| #endif // RUNTIME_PLATFORM_ELF_H_ |