// 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, }; 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, }; 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"; // 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_