#ifndef ELF_SECTION_HEADER_HPP #define ELF_SECTION_HEADER_HPP #include "format.hpp" #include #include #include #include namespace elf { template constexpr auto inline section_header_size = std::numeric_limits::max(); template<> constexpr auto inline section_header_size = 40uz; template<> constexpr auto inline section_header_size = 64uz; template struct section_header { using format_uint = std::conditional_t; enum struct header_type : std::uint32_t { null = 0, ///< Is inactive program_data = 1, ///< Contains program data symbol_table = 2, ///< Contains a symbol table string_table = 3, ///< Contains a string table relocation_entries_with_addends = 4, ///< Contains relocation information with addends hash_table = 5, ///< Contains a symbol hash table dynamic_linking_entries = 6, ///< Contains dynamic linking information notes = 7, ///< Contains additional notes about the object file no_content = 8, ///< Contains no data relocation_entries_without_addends = 9, ///< Contains relocation information without addends reserved = 10, ///< Reserved for future use dynamic_linker_symbol_table = 11, ///< Contains the dynamic linker symbol table init_array = 14, ///< Contains an array of constructor pointers fini_array = 15, ///< Contains an array of destructor pointers preinit_array = 16, ///< Contains an array of pre-constructor pointers group_table = 17, ///< Defines a section group extended_section_header_indices = 18, ///< Contains extended section header indices }; enum struct header_flags : format_uint { writeable = 0x1, ///< Contains writable data allocated = 0x2, ///< Occupies memory during execution executable = 0x4, ///< Contains executable instructions mergeable = 0x10, ///< Contained data may be merged for deduplication strings = 0x20, ///< Contains null-terminated strings info_link = 0x40, ///< Contains the section header index of linked section link_order = 0x80, ///< Must respect linking location relative to linked section os_specific = 0x100, ///< Must be handled in an OS specific way group_member = 0x200, ///< Is a member of a section group thread_local_storage = 0x400, ///< Contains thread local storage data compressed = 0x800, ///< Is compressed }; //! Check if the section is allocated [[nodiscard]] constexpr auto allocated() const noexcept -> bool { return std::to_underlying(flags) & std::to_underlying(header_flags::allocated); } //! Check if the section is executable [[nodiscard]] constexpr auto executable() const noexcept -> bool { return std::to_underlying(flags) & std::to_underlying(header_flags::executable); } //! Check if the section is writeable [[nodiscard]] constexpr auto writable() const noexcept -> bool { return std::to_underlying(flags) & std::to_underlying(header_flags::writeable); } std::uint32_t name_offset; ///< Offset into the section header string table, defining the section name header_type type; ///< Type of this section header_flags flags; ///< Flags of this section format_uint virtual_load_address; ///< Virtual address where this section is loaded format_uint file_offset; ///< Offset of the start of this section's data in the file format_uint size; ///< Size of this section in memory std::uint32_t linked_section; ///< Index of a section this section is linked to std::uint32_t extra_info; ///< Additional information for this section (type and flag dependent) format_uint alignment; ///< Alignment requirement of this section in memory format_uint entry_size; ///< Size of the entries inside this section (if any) }; static_assert(sizeof(section_header) == section_header_size); static_assert(sizeof(section_header) == section_header_size); } // namespace elf #endif