#ifndef ELF_SECTION_HEADER_HPP #define ELF_SECTION_HEADER_HPP #include "format.hpp" #include #include #include #include #include namespace elf { //! The platform dependent header size. //! //! The size of a section header table in ELF is dependent on the bitness of the platform the file is designed for. //! This constant allows compile-time parametrization of objects and functions for a specific architecture. template constexpr auto inline section_header_size = std::numeric_limits::max(); //! @copydoc elf::section_header_size //! //! @note This specialization provides the section header size for 32-bit ELF files. template<> constexpr auto inline section_header_size = 40uz; //! @copydoc elf::section_header_size //! //! @note This specialization provides the section header size for 64-bit ELF files. template<> constexpr auto inline section_header_size = 64uz; //! An ELF section header table entry. //! //! In the ELF, the section header table describes the layout and properties of the sections present in the loadable //! files. This information is used to map and load data from the file according to their use. template struct section_header { //! A platform dependent unsigned integer. //! //! The size of certain fields in a section header of the ELF is dependent on the bitness of the target platform, //! accounting for the differing sizes of 32 and 64 bit section header table entries. using format_uint = std::conditional_t; //! The type of the section described by this header. 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 }; //! The properties of the section describe by this header. enum struct header_flags : format_uint { writable = 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 writable [[nodiscard]] constexpr auto writable() const noexcept -> bool { return std::to_underlying(flags) & std::to_underlying(header_flags::writable); } 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