From cba0a738231a1f8a15aef7b538838c7b721c84ed Mon Sep 17 00:00:00 2001 From: Serge Lamikhov-Center Date: Fri, 3 Jan 2025 23:40:19 +0200 Subject: [PATCH] Add AI generated comments for classes and methods --- elfio/elf_types.hpp | 268 +++++++++++++++++++++++++++---------- elfio/elfio.hpp | 183 ++++++++++++++++++++++--- elfio/elfio_array.hpp | 95 ++++++++----- elfio/elfio_dump.hpp | 17 +++ elfio/elfio_dynamic.hpp | 19 ++- elfio/elfio_header.hpp | 47 ++++++- elfio/elfio_modinfo.hpp | 48 ++++++- elfio/elfio_note.hpp | 27 +++- elfio/elfio_relocation.hpp | 127 ++++++++++++++++++ elfio/elfio_section.hpp | 268 ++++++++++++++++++++++++++++++------- elfio/elfio_segment.hpp | 163 +++++++++++++++++++--- elfio/elfio_strings.hpp | 20 ++- elfio/elfio_symbols.hpp | 154 ++++++++++++++++++++- elfio/elfio_utils.hpp | 113 ++++++++++++---- elfio/elfio_version.hpp | 3 + elfio/elfio_versym.hpp | 61 ++++++++- tests/ELFIOTest.cpp | 8 +- 17 files changed, 1371 insertions(+), 250 deletions(-) diff --git a/elfio/elf_types.hpp b/elfio/elf_types.hpp index 23a7e273..3a6850aa 100644 --- a/elfio/elf_types.hpp +++ b/elfio/elf_types.hpp @@ -1179,113 +1179,189 @@ constexpr Elf_Word AT_L3_CACHESIZE = 46; // ELF file header struct Elf32_Ehdr { + // Identification bytes unsigned char e_ident[EI_NIDENT]; - Elf_Half e_type; - Elf_Half e_machine; - Elf_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf_Word e_flags; - Elf_Half e_ehsize; - Elf_Half e_phentsize; - Elf_Half e_phnum; - Elf_Half e_shentsize; - Elf_Half e_shnum; - Elf_Half e_shstrndx; + // Object file type + Elf_Half e_type; + // Architecture + Elf_Half e_machine; + // Object file version + Elf_Word e_version; + // Entry point virtual address + Elf32_Addr e_entry; + // Program header table file offset + Elf32_Off e_phoff; + // Section header table file offset + Elf32_Off e_shoff; + // Processor-specific flags + Elf_Word e_flags; + // ELF header size in bytes + Elf_Half e_ehsize; + // Program header table entry size + Elf_Half e_phentsize; + // Program header table entry count + Elf_Half e_phnum; + // Section header table entry size + Elf_Half e_shentsize; + // Section header table entry count + Elf_Half e_shnum; + // Section header string table index + Elf_Half e_shstrndx; }; struct Elf64_Ehdr { + // Identification bytes unsigned char e_ident[EI_NIDENT]; - Elf_Half e_type; - Elf_Half e_machine; - Elf_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf_Word e_flags; - Elf_Half e_ehsize; - Elf_Half e_phentsize; - Elf_Half e_phnum; - Elf_Half e_shentsize; - Elf_Half e_shnum; - Elf_Half e_shstrndx; + // Object file type + Elf_Half e_type; + // Architecture + Elf_Half e_machine; + // Object file version + Elf_Word e_version; + // Entry point virtual address + Elf64_Addr e_entry; + // Program header table file offset + Elf64_Off e_phoff; + // Section header table file offset + Elf64_Off e_shoff; + // Processor-specific flags + Elf_Word e_flags; + // ELF header size in bytes + Elf_Half e_ehsize; + // Program header table entry size + Elf_Half e_phentsize; + // Program header table entry count + Elf_Half e_phnum; + // Section header table entry size + Elf_Half e_shentsize; + // Section header table entry count + Elf_Half e_shnum; + // Section header string table index + Elf_Half e_shstrndx; }; // Section header struct Elf32_Shdr { - Elf_Word sh_name; - Elf_Word sh_type; - Elf_Word sh_flags; + // Section name (string table index) + Elf_Word sh_name; + // Section type + Elf_Word sh_type; + // Section flags + Elf_Word sh_flags; + // Section virtual address at execution Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf_Word sh_size; - Elf_Word sh_link; - Elf_Word sh_info; - Elf_Word sh_addralign; - Elf_Word sh_entsize; + // Section file offset + Elf32_Off sh_offset; + // Section size in bytes + Elf_Word sh_size; + // Link to another section + Elf_Word sh_link; + // Additional section information + Elf_Word sh_info; + // Section alignment + Elf_Word sh_addralign; + // Entry size if section holds table + Elf_Word sh_entsize; }; struct Elf64_Shdr { - Elf_Word sh_name; - Elf_Word sh_type; - Elf_Xword sh_flags; + // Section name (string table index) + Elf_Word sh_name; + // Section type + Elf_Word sh_type; + // Section flags + Elf_Xword sh_flags; + // Section virtual address at execution Elf64_Addr sh_addr; - Elf64_Off sh_offset; - Elf_Xword sh_size; - Elf_Word sh_link; - Elf_Word sh_info; - Elf_Xword sh_addralign; - Elf_Xword sh_entsize; + // Section file offset + Elf64_Off sh_offset; + // Section size in bytes + Elf_Xword sh_size; + // Link to another section + Elf_Word sh_link; + // Additional section information + Elf_Word sh_info; + // Section alignment + Elf_Xword sh_addralign; + // Entry size if section holds table + Elf_Xword sh_entsize; }; // Segment header struct Elf32_Phdr { - Elf_Word p_type; - Elf32_Off p_offset; + // Segment type + Elf_Word p_type; + // Segment file offset + Elf32_Off p_offset; + // Segment virtual address at execution Elf32_Addr p_vaddr; + // Segment physical address Elf32_Addr p_paddr; - Elf_Word p_filesz; - Elf_Word p_memsz; - Elf_Word p_flags; - Elf_Word p_align; + // Segment size in file + Elf_Word p_filesz; + // Segment size in memory + Elf_Word p_memsz; + // Segment flags + Elf_Word p_flags; + // Segment alignment + Elf_Word p_align; }; struct Elf64_Phdr { - Elf_Word p_type; - Elf_Word p_flags; - Elf64_Off p_offset; + // Segment type + Elf_Word p_type; + // Segment flags + Elf_Word p_flags; + // Segment file offset + Elf64_Off p_offset; + // Segment virtual address at execution Elf64_Addr p_vaddr; + // Segment physical address Elf64_Addr p_paddr; - Elf_Xword p_filesz; - Elf_Xword p_memsz; - Elf_Xword p_align; + // Segment size in file + Elf_Xword p_filesz; + // Segment size in memory + Elf_Xword p_memsz; + // Segment alignment + Elf_Xword p_align; }; // Symbol table entry struct Elf32_Sym { - Elf_Word st_name; - Elf32_Addr st_value; - Elf_Word st_size; + // Symbol name (string table index) + Elf_Word st_name; + // Symbol value + Elf32_Addr st_value; + // Symbol size + Elf_Word st_size; + // Symbol type and binding attributes unsigned char st_info; + // Symbol visibility unsigned char st_other; - Elf_Half st_shndx; + // Section index + Elf_Half st_shndx; }; struct Elf64_Sym { - Elf_Word st_name; + // Symbol name (string table index) + Elf_Word st_name; + // Symbol type and binding attributes unsigned char st_info; + // Symbol visibility unsigned char st_other; - Elf_Half st_shndx; - Elf64_Addr st_value; - Elf_Xword st_size; + // Section index + Elf_Half st_shndx; + // Symbol value + Elf64_Addr st_value; + // Symbol size + Elf_Xword st_size; }; #define ELF_ST_BIND( i ) ( ( i ) >> 4 ) @@ -1297,27 +1373,37 @@ struct Elf64_Sym // Relocation entries struct Elf32_Rel { + // Location to apply the relocation action Elf32_Addr r_offset; - Elf_Word r_info; + // Relocation type and symbol index + Elf_Word r_info; }; struct Elf32_Rela { + // Location to apply the relocation action Elf32_Addr r_offset; - Elf_Word r_info; - Elf_Sword r_addend; + // Relocation type and symbol index + Elf_Word r_info; + // Constant addend used to compute the value + Elf_Sword r_addend; }; struct Elf64_Rel { + // Location to apply the relocation action Elf64_Addr r_offset; - Elf_Xword r_info; + // Relocation type and symbol index + Elf_Xword r_info; }; struct Elf64_Rela { + // Location to apply the relocation action Elf64_Addr r_offset; - Elf_Xword r_info; + // Relocation type and symbol index + Elf_Xword r_info; + // Constant addend used to compute the value Elf_Sxword r_addend; }; @@ -1333,54 +1419,79 @@ struct Elf64_Rela // Dynamic structure struct Elf32_Dyn { + // Dynamic entry type Elf_Sword d_tag; union { - Elf_Word d_val; + // Integer value + Elf_Word d_val; + // Address value Elf32_Addr d_ptr; } d_un; }; struct Elf64_Dyn { + // Dynamic entry type Elf_Sxword d_tag; union { - Elf_Xword d_val; + // Integer value + Elf_Xword d_val; + // Address value Elf64_Addr d_ptr; } d_un; }; struct Elfxx_Verdef { + // Version revision Elf_Half vd_version; + // Version information flags Elf_Half vd_flags; + // Version index Elf_Half vd_ndx; + // Number of associated aux entries Elf_Half vd_cnt; + // Version name hash value Elf_Word vd_hash; + // Offset to verdaux array Elf_Word vd_aux; + // Offset to next verdef entry Elf_Word vd_next; }; struct Elfxx_Verdaux { + // Version or dependency name Elf_Word vda_name; + // Offset to next verdaux entry Elf_Word vda_next; }; struct Elfxx_Verneed { + // Version of structure Elf_Half vn_version; + // Number of associated aux entries Elf_Half vn_cnt; + // Offset to file name string Elf_Word vn_file; + // Offset to vernaux array Elf_Word vn_aux; + // Offset to next verneed entry Elf_Word vn_next; }; struct Elfxx_Vernaux { + // Hash value of dependency name Elf_Word vna_hash; + // Dependency information flags Elf_Half vna_flags; + // Dependency index Elf_Half vna_other; + // Dependency name string offset Elf_Word vna_name; + // Offset to next vernaux entry Elf_Word vna_next; }; @@ -1400,35 +1511,46 @@ struct Elfxx_Vernaux // The main purpose is also for ELF injectors. struct Elf32_auxv { + // Entry type uint32_t a_type; // Entry type union { + // Integer value, usually a pointer uint32_t a_val; // Integer value, usually a pointer } a_un; }; struct Elf64_auxv { + // Entry type uint64_t a_type; // Entry type union { + // Integer value, usually a pointer uint64_t a_val; // Integer value, usually a pointer } a_un; }; struct Elf32_Chdr { + // The compression algorithm used Elf32_Word ch_type; // The compression algorithm used + // The size, in bytes, of the uncompressed section data Elf32_Word ch_size; //The size, in bytes, of the uncompressed section data + // The address alignment of the uncompressed section data Elf32_Word ch_addralign; // The address alignment of the uncompressed section data }; struct Elf64_Chdr { - Elf64_Word ch_type; //The compression algorithm used + //The compression algorithm used + Elf64_Word ch_type; //The compression algorithm used + // Reserved Elf64_Word ch_reserved; // Reserved - Elf_Xword ch_size; //The size, in bytes, of the uncompressed section data + //The size, in bytes, of the uncompressed section data + Elf_Xword ch_size; //The size, in bytes, of the uncompressed section data + //The address alignment of the uncompressed section data Elf_Xword ch_addralign; //The address alignment of the uncompressed section data }; diff --git a/elfio/elfio.hpp b/elfio/elfio.hpp index 2db86d77..119951b0 100644 --- a/elfio/elfio.hpp +++ b/elfio/elfio.hpp @@ -59,15 +59,21 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +//! \class elfio +//! \brief The elfio class represents an ELF file and provides methods to manipulate it. class elfio { public: //------------------------------------------------------------------------------ + //! \brief Default constructor elfio() noexcept : sections( this ), segments( this ) { create( ELFCLASS32, ELFDATA2LSB ); } + //------------------------------------------------------------------------------ + //! \brief Constructor with compression interface + //! \param compression Pointer to the compression interface explicit elfio( compression_interface* compression ) noexcept : sections( this ), segments( this ), compression( std::shared_ptr( compression ) ) @@ -75,6 +81,9 @@ class elfio elfio(); } + //------------------------------------------------------------------------------ + //! \brief Move constructor + //! \param other The other elfio object to move from elfio( elfio&& other ) noexcept : sections( this ), segments( this ), current_file_pos( other.current_file_pos ) @@ -92,6 +101,10 @@ class elfio other.compression = nullptr; } + //------------------------------------------------------------------------------ + //! \brief Move assignment operator + //! \param other The other elfio object to move from + //! \return Reference to this object elfio& operator=( elfio&& other ) noexcept { if ( this != &other ) { @@ -113,13 +126,15 @@ class elfio } //------------------------------------------------------------------------------ - // clang-format off + //! \brief Delete copy constructor and copy assignment operator elfio( const elfio& ) = delete; elfio& operator=( const elfio& ) = delete; ~elfio() = default; - // clang-format on //------------------------------------------------------------------------------ + //! \brief Create a new ELF file with the specified class and encoding + //! \param file_class The class of the ELF file (ELFCLASS32 or ELFCLASS64) + //! \param encoding The encoding of the ELF file (ELFDATA2LSB or ELFDATA2MSB) void create( unsigned char file_class, unsigned char encoding ) { sections_.clear(); @@ -129,12 +144,19 @@ class elfio create_mandatory_sections(); } + //------------------------------------------------------------------------------ + //! \brief Set address translation + //! \param addr_trans Vector of address translations void set_address_translation( std::vector& addr_trans ) { addr_translator.set_address_translation( addr_trans ); } //------------------------------------------------------------------------------ + //! \brief Load an ELF file from a file + //! \param file_name The name of the file to load + //! \param is_lazy Whether to load the file lazily + //! \return True if successful, false otherwise bool load( const std::string& file_name, bool is_lazy = false ) { pstream = std::make_unique(); @@ -157,6 +179,10 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Load an ELF file from a stream + //! \param stream The input stream to load from + //! \param is_lazy Whether to load the file lazily + //! \return True if successful, false otherwise bool load( std::istream& stream, bool is_lazy = false ) { sections_.clear(); @@ -199,6 +225,9 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Save the ELF file to a file + //! \param file_name The name of the file to save to + //! \return True if successful, false otherwise bool save( const std::string& file_name ) { std::ofstream stream; @@ -211,6 +240,9 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Save the ELF file to a stream + //! \param stream The output stream to save to + //! \return True if successful, false otherwise bool save( std::ostream& stream ) { if ( !stream || header == nullptr ) { @@ -267,9 +299,14 @@ class elfio ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index ); //------------------------------------------------------------------------------ + //! \brief Get the endianness convertor + //! \return Reference to the endianness convertor const endianness_convertor& get_convertor() const { return convertor; } //------------------------------------------------------------------------------ + //! \brief Get the default entry size for a section type + //! \param section_type The type of the section + //! \return The default entry size for the section type Elf_Xword get_default_entry_size( Elf_Word section_type ) const { switch ( section_type ) { @@ -307,9 +344,8 @@ class elfio } //------------------------------------------------------------------------------ - //! returns an empty string if no problems are detected, - //! or a string containing an error message if problems are found, - //! with one error per line. + //! \brief Validate the ELF file + //! \return An empty string if no problems are detected, or a string containing an error message if problems are found, with one error per line. std::string validate() const { // clang-format off @@ -372,6 +408,10 @@ class elfio private: //------------------------------------------------------------------------------ + //! \brief Check if an offset is within a section + //! \param offset The offset to check + //! \param sec Pointer to the section + //! \return True if the offset is within the section, false otherwise static bool is_offset_in_section( Elf64_Off offset, const section* sec ) { return ( offset >= sec->get_offset() ) && @@ -379,12 +419,19 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Get the virtual address of an offset within a section + //! \param offset The offset within the section + //! \param sec Pointer to the section + //! \return The virtual address of the offset within the section static Elf64_Addr get_virtual_addr( Elf64_Off offset, const section* sec ) { return sec->get_address() + offset - sec->get_offset(); } //------------------------------------------------------------------------------ + //! \brief Find the section that contains a given offset + //! \param offset The offset to find + //! \return Pointer to the section that contains the offset, or nullptr if not found const section* find_prog_section_for_offset( Elf64_Off offset ) const { for ( const auto& sec : sections ) { @@ -397,6 +444,10 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Create an ELF header + //! \param file_class The class of the ELF file (ELFCLASS32 or ELFCLASS64) + //! \param encoding The encoding of the ELF file (ELFDATA2LSB or ELFDATA2MSB) + //! \return Unique pointer to the created ELF header std::unique_ptr create_header( unsigned char file_class, unsigned char encoding ) { @@ -420,6 +471,8 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Create a new section + //! \return Pointer to the created section section* create_section() { if ( auto file_class = get_class(); file_class == ELFCLASS64 ) { @@ -444,6 +497,8 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Create a new segment + //! \return Pointer to the created segment segment* create_segment() { if ( auto file_class = header->get_class(); file_class == ELFCLASS64 ) { @@ -468,6 +523,7 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Create mandatory sections void create_mandatory_sections() { // Create null section without calling to 'add_section' as no string @@ -484,6 +540,10 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Load sections from a stream + //! \param stream The input stream to load from + //! \param is_lazy Whether to load the sections lazily + //! \return True if successful, false otherwise bool load_sections( std::istream& stream, bool is_lazy ) { unsigned char file_class = header->get_class(); @@ -525,9 +585,14 @@ class elfio } //------------------------------------------------------------------------------ - //! Checks whether the addresses of the section entirely fall within the given segment. + //! \brief Checks whether the addresses of the section entirely fall within the given segment. //! It doesn't matter if the addresses are memory addresses, or file offsets, //! they just need to be in the same address space + //! \param sect_begin The beginning address of the section + //! \param sect_size The size of the section + //! \param seg_begin The beginning address of the segment + //! \param seg_end The end address of the segment + //! \return True if the section is within the segment, false otherwise static bool is_sect_in_seg( Elf64_Off sect_begin, Elf_Xword sect_size, Elf64_Off seg_begin, @@ -542,6 +607,10 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Load segments from a stream + //! \param stream The input stream to load from + //! \param is_lazy Whether to load the segments lazily + //! \return True if successful, false otherwise bool load_segments( std::istream& stream, bool is_lazy ) { unsigned char file_class = header->get_class(); @@ -618,12 +687,18 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Save the ELF header to a stream + //! \param stream The output stream to save to + //! \return True if successful, false otherwise bool save_header( std::ostream& stream ) const { return header->save( stream ); } //------------------------------------------------------------------------------ + //! \brief Save the sections to a stream + //! \param stream The output stream to save to + //! \return True if successful, false otherwise bool save_sections( std::ostream& stream ) const { for ( const auto& sec : sections_ ) { @@ -639,6 +714,9 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Save the segments to a stream + //! \param stream The output stream to save to + //! \return True if successful, false otherwise bool save_segments( std::ostream& stream ) const { for ( const auto& seg : segments_ ) { @@ -654,6 +732,9 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Check if a section is without a segment + //! \param section_index The index of the section + //! \return True if the section is without a segment, false otherwise bool is_section_without_segment( unsigned int section_index ) const { bool found = false; @@ -669,6 +750,10 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Check if a segment is a subsequence of another segment + //! \param seg1 Pointer to the first segment + //! \param seg2 Pointer to the second segment + //! \return True if seg1 is a subsequence of seg2, false otherwise static bool is_subsequence_of( const segment* seg1, const segment* seg2 ) { // Return 'true' if sections of seg1 are a subset of sections in seg2 @@ -685,6 +770,8 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Get ordered segments + //! \return Vector of ordered segments std::vector get_ordered_segments() const { std::vector res; @@ -731,6 +818,8 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Layout sections without segments + //! \return True if successful, false otherwise bool layout_sections_without_segments() { for ( unsigned int i = 0; i < sections_.size(); ++i ) { @@ -759,6 +848,7 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Calculate segment alignment void calc_segment_alignment() const { for ( const auto& seg : segments_ ) { @@ -772,6 +862,8 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Layout segments and their sections + //! \return True if successful, false otherwise bool layout_segments_and_their_sections() { std::vector worklist; @@ -841,6 +933,8 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Layout the section table + //! \return True if successful, false otherwise bool layout_section_table() { // Simply place the section table at the end for now @@ -851,6 +945,13 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Write segment data + //! \param seg Pointer to the segment + //! \param section_generated Vector of section generated flags + //! \param segment_memory Reference to the segment memory size + //! \param segment_filesize Reference to the segment file size + //! \param seg_start_pos The start position of the segment + //! \return True if successful, false otherwise bool write_segment_data( const segment* seg, std::vector& section_generated, Elf_Xword& segment_memory, @@ -944,20 +1045,29 @@ class elfio //------------------------------------------------------------------------------ public: + //! \class Sections + //! \brief The Sections class provides methods to manipulate sections in an ELF file. friend class Sections; class Sections { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param parent Pointer to the parent elfio object explicit Sections( elfio* parent ) : parent( parent ) {} //------------------------------------------------------------------------------ + //! \brief Get the number of sections + //! \return The number of sections Elf_Half size() const { return static_cast( parent->sections_.size() ); } //------------------------------------------------------------------------------ + //! \brief Get a section by index + //! \param index The index of the section + //! \return Pointer to the section, or nullptr if not found section* operator[]( unsigned int index ) const { section* sec = nullptr; @@ -970,6 +1080,9 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Get a section by name + //! \param name The name of the section + //! \return Pointer to the section, or nullptr if not found section* operator[]( const std::string_view& name ) const { section* sec = nullptr; @@ -985,6 +1098,9 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Add a new section + //! \param name The name of the section + //! \return Pointer to the created section section* add( const std::string& name ) const { section* new_section = parent->create_section(); @@ -1000,24 +1116,32 @@ class elfio } //------------------------------------------------------------------------------ + //! \brief Get an iterator to the beginning of the sections + //! \return Iterator to the beginning of the sections std::vector>::iterator begin() { return parent->sections_.begin(); } //------------------------------------------------------------------------------ + //! \brief Get an iterator to the end of the sections + //! \return Iterator to the end of the sections std::vector>::iterator end() { return parent->sections_.end(); } //------------------------------------------------------------------------------ + //! \brief Get a const iterator to the beginning of the sections + //! \return Const iterator to the beginning of the sections std::vector>::const_iterator begin() const { return parent->sections_.cbegin(); } //------------------------------------------------------------------------------ + //! \brief Get a const iterator to the end of the sections + //! \return Const iterator to the end of the sections std::vector>::const_iterator end() const { return parent->sections_.cend(); @@ -1025,52 +1149,71 @@ class elfio //------------------------------------------------------------------------------ private: - elfio* parent; + elfio* parent; //!< Pointer to the parent elfio object }; - Sections sections; + Sections sections; //!< Sections object //------------------------------------------------------------------------------ + //! \class Segments + //! \brief The Segments class provides methods to manipulate segments in an ELF file. friend class Segments; class Segments { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param parent Pointer to the parent elfio object explicit Segments( elfio* parent ) : parent( parent ) {} //------------------------------------------------------------------------------ + //! \brief Get the number of segments + //! \return The number of segments Elf_Half size() const { return static_cast( parent->segments_.size() ); } //------------------------------------------------------------------------------ + //! \brief Get a segment by index + //! \param index The index of the segment + //! \return Pointer to the segment, or nullptr if not found segment* operator[]( unsigned int index ) const { return parent->segments_[index].get(); } //------------------------------------------------------------------------------ + //! \brief Add a new segment + //! \return Pointer to the created segment segment* add() { return parent->create_segment(); } //------------------------------------------------------------------------------ + //! \brief Get an iterator to the beginning of the segments + //! \return Iterator to the beginning of the segments std::vector>::iterator begin() { return parent->segments_.begin(); } //------------------------------------------------------------------------------ + //! \brief Get an iterator to the end of the segments + //! \return Iterator to the end of the segments std::vector>::iterator end() { return parent->segments_.end(); } //------------------------------------------------------------------------------ + //! \brief Get a const iterator to the beginning of the segments + //! \return Const iterator to the beginning of the segments std::vector>::const_iterator begin() const { return parent->segments_.cbegin(); } //------------------------------------------------------------------------------ + //! \brief Get a const iterator to the end of the segments + //! \return Const iterator to the end of the segments std::vector>::const_iterator end() const { return parent->segments_.cend(); @@ -1078,21 +1221,23 @@ class elfio //------------------------------------------------------------------------------ private: - elfio* parent; + elfio* parent; //!< Pointer to the parent elfio object }; - Segments segments; + Segments segments; //!< Segments object //------------------------------------------------------------------------------ private: - std::unique_ptr pstream = nullptr; - std::unique_ptr header = nullptr; - std::vector> sections_; - std::vector> segments_; - endianness_convertor convertor; - address_translator addr_translator; - std::shared_ptr compression = nullptr; - - Elf_Xword current_file_pos = 0; + std::unique_ptr pstream = + nullptr; //!< Pointer to the input stream + std::unique_ptr header = nullptr; //!< Pointer to the ELF header + std::vector> sections_; //!< Vector of sections + std::vector> segments_; //!< Vector of segments + endianness_convertor convertor; //!< Endianness convertor + address_translator addr_translator; //!< Address translator + std::shared_ptr compression = + nullptr; //!< Pointer to the compression interface + + Elf_Xword current_file_pos = 0; //!< Current file position }; } // namespace ELFIO diff --git a/elfio/elfio_array.hpp b/elfio/elfio_array.hpp index 0ca302d4..d15f2dde 100644 --- a/elfio/elfio_array.hpp +++ b/elfio/elfio_array.hpp @@ -28,55 +28,86 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +// Template class for accessing array sections template class array_section_accessor_template { public: //------------------------------------------------------------------------------ + // Constructor explicit array_section_accessor_template( const elfio& elf_file, - S* section ) - : elf_file( elf_file ), array_section( section ) - { - } + S* section ); //------------------------------------------------------------------------------ - Elf_Xword get_entries_num() const - { - Elf_Xword entry_size = sizeof( T ); - return array_section->get_size() / entry_size; - } + // Returns the number of entries in the array section + Elf_Xword get_entries_num() const; //------------------------------------------------------------------------------ - bool get_entry( Elf_Xword index, Elf64_Addr& address ) const - { - if ( index >= get_entries_num() ) { // Is index valid - return false; - } - - const endianness_convertor& convertor = elf_file.get_convertor(); - - const T temp = *reinterpret_cast( array_section->get_data() + - index * sizeof( T ) ); - address = convertor( temp ); - - return true; - } + // Retrieves an entry from the array section + bool get_entry( Elf_Xword index, Elf64_Addr& address ) const; //------------------------------------------------------------------------------ - void add_entry( Elf64_Addr address ) - { - const endianness_convertor& convertor = elf_file.get_convertor(); - - T temp = convertor( (T)address ); - array_section->append_data( reinterpret_cast( &temp ), - sizeof( temp ) ); - } + // Adds an entry to the array section + void add_entry( Elf64_Addr address ); private: //------------------------------------------------------------------------------ + // Reference to the ELF file const elfio& elf_file; - S* array_section; + //------------------------------------------------------------------------------ + // Pointer to the array section + S* array_section; }; +//------------------------------------------------------------------------------ +// Constructor +template +array_section_accessor_template::array_section_accessor_template( + const elfio& elf_file, S* section ) + : elf_file( elf_file ), array_section( section ) +{ +} + +//------------------------------------------------------------------------------ +// Returns the number of entries in the array section +template +Elf_Xword array_section_accessor_template::get_entries_num() const +{ + Elf_Xword entry_size = sizeof( T ); + return array_section->get_size() / entry_size; +} + +//------------------------------------------------------------------------------ +// Retrieves an entry from the array section +template +bool array_section_accessor_template::get_entry( + Elf_Xword index, Elf64_Addr& address ) const +{ + if ( index >= get_entries_num() ) { // Is index valid + return false; + } + + const endianness_convertor& convertor = elf_file.get_convertor(); + + const T temp = *reinterpret_cast( array_section->get_data() + + index * sizeof( T ) ); + address = convertor( temp ); + + return true; +} + +//------------------------------------------------------------------------------ +// Adds an entry to the array section +template +void array_section_accessor_template::add_entry( Elf64_Addr address ) +{ + const endianness_convertor& convertor = elf_file.get_convertor(); + + T temp = convertor( (T)address ); + array_section->append_data( reinterpret_cast( &temp ), + sizeof( temp ) ); +} + +// Type aliases for array section accessors template using array_section_accessor = array_section_accessor_template; template diff --git a/elfio/elfio_dump.hpp b/elfio/elfio_dump.hpp index 1b4aa753..15e5f45e 100644 --- a/elfio/elfio_dump.hpp +++ b/elfio/elfio_dump.hpp @@ -672,6 +672,7 @@ static const struct note_tag_t static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; //------------------------------------------------------------------------------ +// Class representing the ELF dump functionality class dump { #define DUMP_DEC_FORMAT( width ) \ @@ -685,6 +686,7 @@ class dump public: //------------------------------------------------------------------------------ + // Dumps the ELF header information static void header( std::ostream& out, const elfio& reader ) { if ( !reader.get_header_size() ) { @@ -713,6 +715,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the section headers information static void section_headers( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.sections.size(); @@ -748,6 +751,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps a single section header information static void section_header( std::ostream& out, Elf_Half no, const section* sec, @@ -792,6 +796,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the segment headers information static void segment_headers( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.segments.size(); @@ -836,6 +841,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps a single segment header information static void segment_header( std::ostream& out, Elf_Half no, const segment* seg, @@ -874,6 +880,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the symbol tables information static void symbol_tables( std::ostream& out, const elfio& reader ) { for ( const auto& sec : reader.sections ) { // For all sections @@ -918,6 +925,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps a single symbol table entry information static void symbol_table( std::ostream& out, Elf_Xword no, const std::string& name, @@ -954,6 +962,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the notes information static void notes( std::ostream& out, const elfio& reader ) { for ( const auto& sec : reader.sections ) { // For all sections @@ -1018,6 +1027,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps a single note information static void note( std::ostream& out, int no, Elf_Word type, @@ -1065,6 +1075,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the module information static void modinfo( std::ostream& out, const elfio& reader ) { for ( const auto& sec : reader.sections ) { // For all sections @@ -1088,6 +1099,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the dynamic tags information static void dynamic_tags( std::ostream& out, const elfio& reader ) { for ( const auto& sec : reader.sections ) { // For all sections @@ -1118,6 +1130,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps a single dynamic tag information static void dynamic_tag( std::ostream& out, Elf_Xword no, Elf_Xword tag, @@ -1137,6 +1150,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the section data static void section_data( std::ostream& out, const section* sec ) { std::ios_base::fmtflags original_flags = out.flags(); @@ -1169,6 +1183,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps all sections data static void section_datas( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.sections.size(); @@ -1191,6 +1206,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps the segment data static void segment_data( std::ostream& out, Elf_Half no, const segment* seg ) { @@ -1224,6 +1240,7 @@ class dump } //------------------------------------------------------------------------------ + // Dumps all segments data static void segment_datas( std::ostream& out, const elfio& reader ) { Elf_Half n = reader.segments.size(); diff --git a/elfio/elfio_dynamic.hpp b/elfio/elfio_dynamic.hpp index 6d9b7060..3fbf6f5f 100644 --- a/elfio/elfio_dynamic.hpp +++ b/elfio/elfio_dynamic.hpp @@ -28,10 +28,12 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +// Template class for accessing dynamic sections template class dynamic_section_accessor_template { public: //------------------------------------------------------------------------------ + // Constructor explicit dynamic_section_accessor_template( const elfio& elf_file, S* section ) : elf_file( elf_file ), dynamic_section( section ), entries_num( 0 ) @@ -39,6 +41,7 @@ template class dynamic_section_accessor_template } //------------------------------------------------------------------------------ + // Returns the number of entries in the dynamic section Elf_Xword get_entries_num() const { size_t needed_entry_size = -1; @@ -70,6 +73,7 @@ template class dynamic_section_accessor_template } //------------------------------------------------------------------------------ + // Retrieves an entry from the dynamic section bool get_entry( Elf_Xword index, Elf_Xword& tag, Elf_Xword& value, @@ -106,6 +110,7 @@ template class dynamic_section_accessor_template } //------------------------------------------------------------------------------ + // Adds an entry to the dynamic section void add_entry( Elf_Xword tag, Elf_Xword value ) { if ( elf_file.get_class() == ELFCLASS32 ) { @@ -117,6 +122,7 @@ template class dynamic_section_accessor_template } //------------------------------------------------------------------------------ + // Adds an entry with a string value to the dynamic section void add_entry( Elf_Xword tag, const std::string& str ) { string_section_accessor strsec( @@ -125,15 +131,16 @@ template class dynamic_section_accessor_template add_entry( tag, value ); } - //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ + // Returns the index of the string table Elf_Half get_string_table_index() const { return (Elf_Half)dynamic_section->get_link(); } //------------------------------------------------------------------------------ + // Retrieves a generic entry from the dynamic section template void generic_get_entry_dyn( Elf_Xword index, Elf_Xword& tag, @@ -200,6 +207,7 @@ template class dynamic_section_accessor_template } //------------------------------------------------------------------------------ + // Adds a generic entry to the dynamic section template void generic_add_entry_dyn( Elf_Xword tag, Elf_Xword value ) { @@ -258,13 +266,16 @@ template class dynamic_section_accessor_template sizeof( entry ) ); } - //------------------------------------------------------------------------------ private: - const elfio& elf_file; - S* dynamic_section; + // Reference to the ELF file + const elfio& elf_file; + // Pointer to the dynamic section + S* dynamic_section; + // Number of entries in the dynamic section mutable Elf_Xword entries_num; }; +// Type aliases for dynamic section accessors using dynamic_section_accessor = dynamic_section_accessor_template
; using const_dynamic_section_accessor = dynamic_section_accessor_template; diff --git a/elfio/elfio_header.hpp b/elfio/elfio_header.hpp index 2694a304..0734f243 100644 --- a/elfio/elfio_header.hpp +++ b/elfio/elfio_header.hpp @@ -27,12 +27,30 @@ THE SOFTWARE. namespace ELFIO { +/** + * @class elf_header + * @brief Abstract base class for ELF header. + */ class elf_header { public: + /** + * @brief Virtual destructor. + */ virtual ~elf_header() = default; - virtual bool load( std::istream& stream ) = 0; + /** + * @brief Load ELF header from stream. + * @param stream Input stream. + * @return True if successful, false otherwise. + */ + virtual bool load( std::istream& stream ) = 0; + + /** + * @brief Save ELF header to stream. + * @param stream Output stream. + * @return True if successful, false otherwise. + */ virtual bool save( std::ostream& stream ) const = 0; // ELF header functions @@ -57,6 +75,10 @@ class elf_header ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); }; +/** + * @struct elf_header_impl_types + * @brief Template specialization for ELF header implementation types. + */ template struct elf_header_impl_types; template <> struct elf_header_impl_types { @@ -71,10 +93,19 @@ template <> struct elf_header_impl_types static const unsigned char file_class = ELFCLASS64; }; +/** + * @class elf_header_impl + * @brief Template class for ELF header implementation. + */ template class elf_header_impl : public elf_header { public: - //------------------------------------------------------------------------------ + /** + * @brief Constructor. + * @param convertor Endianness convertor. + * @param encoding Encoding type. + * @param translator Address translator. + */ elf_header_impl( endianness_convertor* convertor, unsigned char encoding, const address_translator* translator ) @@ -99,7 +130,11 @@ template class elf_header_impl : public elf_header header.e_shentsize = ( *convertor )( header.e_shentsize ); } - //------------------------------------------------------------------------------ + /** + * @brief Load ELF header from stream. + * @param stream Input stream. + * @return True if successful, false otherwise. + */ bool load( std::istream& stream ) override { stream.seekg( ( *translator )[0] ); @@ -108,7 +143,11 @@ template class elf_header_impl : public elf_header return ( stream.gcount() == sizeof( header ) ); } - //------------------------------------------------------------------------------ + /** + * @brief Save ELF header to stream. + * @param stream Output stream. + * @return True if successful, false otherwise. + */ bool save( std::ostream& stream ) const override { stream.seekp( ( *translator )[0] ); diff --git a/elfio/elfio_modinfo.hpp b/elfio/elfio_modinfo.hpp index e3a74e19..ee7fe2d4 100644 --- a/elfio/elfio_modinfo.hpp +++ b/elfio/elfio_modinfo.hpp @@ -29,10 +29,21 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +/** + * @class modinfo_section_accessor_template + * @brief A template class to access modinfo section. + * + * @tparam S The section type. + */ template class modinfo_section_accessor_template { public: //------------------------------------------------------------------------------ + /** + * @brief Construct a new modinfo section accessor template object. + * + * @param section The section to be accessed. + */ explicit modinfo_section_accessor_template( S* section ) : modinfo_section( section ) { @@ -40,9 +51,23 @@ template class modinfo_section_accessor_template } //------------------------------------------------------------------------------ + /** + * @brief Get the number of attributes. + * + * @return Elf_Word The number of attributes. + */ Elf_Word get_attribute_num() const { return (Elf_Word)content.size(); } //------------------------------------------------------------------------------ + /** + * @brief Get the attribute by index. + * + * @param no The index of the attribute. + * @param field The field name of the attribute. + * @param value The value of the attribute. + * @return true If the attribute is found. + * @return false If the attribute is not found. + */ bool get_attribute( Elf_Word no, std::string& field, std::string& value ) const { @@ -56,6 +81,14 @@ template class modinfo_section_accessor_template } //------------------------------------------------------------------------------ + /** + * @brief Get the attribute by field name. + * + * @param field_name The field name of the attribute. + * @param value The value of the attribute. + * @return true If the attribute is found. + * @return false If the attribute is not found. + */ bool get_attribute( const std::string_view& field_name, std::string& value ) const { @@ -70,6 +103,13 @@ template class modinfo_section_accessor_template } //------------------------------------------------------------------------------ + /** + * @brief Add a new attribute. + * + * @param field The field name of the attribute. + * @param value The value of the attribute. + * @return Elf_Word The position of the new attribute. + */ Elf_Word add_attribute( const std::string& field, const std::string& value ) { Elf_Word current_position = 0; @@ -89,6 +129,9 @@ template class modinfo_section_accessor_template //------------------------------------------------------------------------------ private: + /** + * @brief Process the section to extract attributes. + */ void process_section() { const char* pdata = modinfo_section->get_data(); @@ -111,8 +154,9 @@ template class modinfo_section_accessor_template //------------------------------------------------------------------------------ private: - S* modinfo_section; - std::vector> content; + S* modinfo_section; ///< The section to be accessed. + std::vector> + content; ///< The list of attributes. }; using modinfo_section_accessor = modinfo_section_accessor_template
; diff --git a/elfio/elfio_note.hpp b/elfio/elfio_note.hpp index 760601a2..4f26559b 100644 --- a/elfio/elfio_note.hpp +++ b/elfio/elfio_note.hpp @@ -38,11 +38,16 @@ namespace ELFIO { //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ +//! \class note_section_accessor_template +//! \brief Class for accessing note section data template class note_section_accessor_template { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param elf_file Reference to the ELF file + //! \param section Pointer to the section explicit note_section_accessor_template( const elfio& elf_file, S* section ) : elf_file( elf_file ), notes( section ) { @@ -50,12 +55,21 @@ class note_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get the number of notes + //! \return Number of notes Elf_Word get_notes_num() const { return (Elf_Word)note_start_positions.size(); } //------------------------------------------------------------------------------ + //! \brief Get a note + //! \param index Index of the note + //! \param type Type of the note + //! \param name Name of the note + //! \param desc Pointer to the descriptor + //! \param descSize Size of the descriptor + //! \return True if successful, false otherwise bool get_note( Elf_Word index, Elf_Word& type, std::string& name, @@ -94,6 +108,11 @@ class note_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add a note + //! \param type Type of the note + //! \param name Name of the note + //! \param desc Pointer to the descriptor + //! \param descSize Size of the descriptor void add_note( Elf_Word type, const std::string& name, const char* desc, @@ -129,6 +148,7 @@ class note_section_accessor_template private: //------------------------------------------------------------------------------ + //! \brief Process the section to extract note start positions void process_section() { const endianness_convertor& convertor = elf_file.get_convertor(); @@ -165,9 +185,10 @@ class note_section_accessor_template //------------------------------------------------------------------------------ private: - const elfio& elf_file; - S* notes; - std::vector note_start_positions; + const elfio& elf_file; //!< Reference to the ELF file + S* notes; //!< Pointer to the section or segment + std::vector + note_start_positions; //!< Vector of note start positions }; using note_section_accessor = diff --git a/elfio/elfio_relocation.hpp b/elfio/elfio_relocation.hpp index 5ac7f609..fdd58a06 100644 --- a/elfio/elfio_relocation.hpp +++ b/elfio/elfio_relocation.hpp @@ -28,10 +28,18 @@ namespace ELFIO { template struct get_sym_and_type; template <> struct get_sym_and_type { + //------------------------------------------------------------------------------ + //! \brief Get the symbol from the relocation info + //! \param info Relocation info + //! \return Symbol static int get_r_sym( Elf_Xword info ) { return ELF32_R_SYM( (Elf_Word)info ); } + //------------------------------------------------------------------------------ + //! \brief Get the type from the relocation info + //! \param info Relocation info + //! \return Type static int get_r_type( Elf_Xword info ) { return ELF32_R_TYPE( (Elf_Word)info ); @@ -39,10 +47,18 @@ template <> struct get_sym_and_type }; template <> struct get_sym_and_type { + //------------------------------------------------------------------------------ + //! \brief Get the symbol from the relocation info + //! \param info Relocation info + //! \return Symbol static int get_r_sym( Elf_Xword info ) { return ELF32_R_SYM( (Elf_Word)info ); } + //------------------------------------------------------------------------------ + //! \brief Get the type from the relocation info + //! \param info Relocation info + //! \return Type static int get_r_type( Elf_Xword info ) { return ELF32_R_TYPE( (Elf_Word)info ); @@ -50,20 +66,41 @@ template <> struct get_sym_and_type }; template <> struct get_sym_and_type { + //------------------------------------------------------------------------------ + //! \brief Get the symbol from the relocation info + //! \param info Relocation info + //! \return Symbol static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } + //------------------------------------------------------------------------------ + //! \brief Get the type from the relocation info + //! \param info Relocation info + //! \return Type static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } }; template <> struct get_sym_and_type { + //------------------------------------------------------------------------------ + //! \brief Get the symbol from the relocation info + //! \param info Relocation info + //! \return Symbol static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } + //------------------------------------------------------------------------------ + //! \brief Get the type from the relocation info + //! \param info Relocation info + //! \return Type static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } }; //------------------------------------------------------------------------------ +//! \class relocation_section_accessor_template +//! \brief Class for accessing relocation section data template class relocation_section_accessor_template { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param elf_file Reference to the ELF file + //! \param section Pointer to the section explicit relocation_section_accessor_template( const elfio& elf_file, S* section ) : elf_file( elf_file ), relocation_section( section ) @@ -71,6 +108,8 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get the number of entries + //! \return Number of entries Elf_Xword get_entries_num() const { Elf_Xword nRet = 0; @@ -84,6 +123,13 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get an entry + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry + //! \return True if successful, false otherwise bool get_entry( Elf_Xword index, Elf64_Addr& offset, Elf_Word& symbol, @@ -119,6 +165,15 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get an entry with additional information + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbolValue Value of the symbol + //! \param symbolName Name of the symbol + //! \param type Type of the entry + //! \param addend Addend of the entry + //! \param calcValue Calculated value + //! \return True if successful, false otherwise bool get_entry( Elf_Xword index, Elf64_Addr& offset, Elf64_Addr& symbolValue, @@ -186,6 +241,13 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Set an entry + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry + //! \return True if successful, false otherwise bool set_entry( Elf_Xword index, Elf64_Addr offset, Elf_Word symbol, @@ -221,6 +283,9 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add an entry + //! \param offset Offset of the entry + //! \param info Information of the entry void add_entry( Elf64_Addr offset, Elf_Xword info ) { if ( elf_file.get_class() == ELFCLASS32 ) { @@ -232,6 +297,10 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add an entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned type ) { Elf_Xword info; @@ -246,6 +315,10 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add an entry + //! \param offset Offset of the entry + //! \param info Information of the entry + //! \param addend Addend of the entry void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) { if ( elf_file.get_class() == ELFCLASS32 ) { @@ -257,6 +330,11 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add an entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned type, @@ -274,6 +352,17 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add an entry with additional information + //! \param str_writer String section accessor + //! \param str String + //! \param sym_writer Symbol section accessor + //! \param value Value of the symbol + //! \param size Size of the symbol + //! \param sym_info Symbol information + //! \param other Other information + //! \param shndx Section index + //! \param offset Offset of the entry + //! \param type Type of the entry void add_entry( string_section_accessor str_writer, const char* str, symbol_section_accessor sym_writer, @@ -292,6 +381,9 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Swap symbols + //! \param first First symbol + //! \param second Second symbol void swap_symbols( Elf_Xword first, Elf_Xword second ) { Elf64_Addr offset = 0; @@ -312,12 +404,21 @@ template class relocation_section_accessor_template //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ + //! \brief Get the symbol table index + //! \return Symbol table index Elf_Half get_symbol_table_index() const { return (Elf_Half)relocation_section->get_link(); } //------------------------------------------------------------------------------ + //! \brief Get a generic entry for REL type + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry + //! \return True if successful, false otherwise template bool generic_get_entry_rel( Elf_Xword index, Elf64_Addr& offset, @@ -342,6 +443,13 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get a generic entry for RELA type + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry + //! \return True if successful, false otherwise template bool generic_get_entry_rela( Elf_Xword index, Elf64_Addr& offset, @@ -367,6 +475,12 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Set a generic entry for REL type + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry template void generic_set_entry_rel( Elf_Xword index, Elf64_Addr offset, @@ -392,6 +506,12 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Set a generic entry for RELA type + //! \param index Index of the entry + //! \param offset Offset of the entry + //! \param symbol Symbol of the entry + //! \param type Type of the entry + //! \param addend Addend of the entry template void generic_set_entry_rela( Elf_Xword index, Elf64_Addr offset, @@ -419,6 +539,9 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add a generic entry for REL type + //! \param offset Offset of the entry + //! \param info Information of the entry template void generic_add_entry( Elf64_Addr offset, Elf_Xword info ) { @@ -435,6 +558,10 @@ template class relocation_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add a generic entry for RELA type + //! \param offset Offset of the entry + //! \param info Information of the entry + //! \param addend Addend of the entry template void generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) diff --git a/elfio/elfio_section.hpp b/elfio/elfio_section.hpp index 579af4a5..1766453e 100644 --- a/elfio/elfio_section.hpp +++ b/elfio/elfio_section.hpp @@ -30,6 +30,10 @@ THE SOFTWARE. namespace ELFIO { +/** + * @class section + * @brief Represents a section in an ELF file. + */ class section { friend class elfio; @@ -50,35 +54,117 @@ class section ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); - virtual const char* get_data() const = 0; - virtual void free_data() const = 0; - virtual void set_data( const char* raw_data, Elf_Word size ) = 0; - virtual void set_data( const std::string& data ) = 0; - virtual void append_data( const char* raw_data, Elf_Word size ) = 0; - virtual void append_data( const std::string& data ) = 0; + /** + * @brief Get the data of the section. + * @return Pointer to the data. + */ + virtual const char* get_data() const = 0; + + /** + * @brief Free the data of the section. + */ + virtual void free_data() const = 0; + + /** + * @brief Set the data of the section. + * @param raw_data Pointer to the raw data. + * @param size Size of the data. + */ + virtual void set_data( const char* raw_data, Elf_Word size ) = 0; + + /** + * @brief Set the data of the section. + * @param data String containing the data. + */ + virtual void set_data( const std::string& data ) = 0; + + /** + * @brief Append data to the section. + * @param raw_data Pointer to the raw data. + * @param size Size of the data. + */ + virtual void append_data( const char* raw_data, Elf_Word size ) = 0; + + /** + * @brief Append data to the section. + * @param data String containing the data. + */ + virtual void append_data( const std::string& data ) = 0; + + /** + * @brief Insert data into the section at a specific position. + * @param pos Position to insert the data. + * @param raw_data Pointer to the raw data. + * @param size Size of the data. + */ virtual void - insert_data( Elf_Xword pos, const char* raw_data, Elf_Word size ) = 0; - virtual void insert_data( Elf_Xword pos, const std::string& data ) = 0; - virtual size_t get_stream_size() const = 0; - virtual void set_stream_size( size_t value ) = 0; + insert_data( Elf_Xword pos, const char* raw_data, Elf_Word size ) = 0; + + /** + * @brief Insert data into the section at a specific position. + * @param pos Position to insert the data. + * @param data String containing the data. + */ + virtual void insert_data( Elf_Xword pos, const std::string& data ) = 0; + + /** + * @brief Get the size of the stream. + * @return Size of the stream. + */ + virtual size_t get_stream_size() const = 0; + + /** + * @brief Set the size of the stream. + * @param value Size of the stream. + */ + virtual void set_stream_size( size_t value ) = 0; protected: ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_SET_ACCESS_DECL( Elf_Half, index ); + /** + * @brief Load the section from a stream. + * @param stream Input stream. + * @param header_offset Offset of the header. + * @param is_lazy Whether to load lazily. + * @return True if successful, false otherwise. + */ virtual bool load( std::istream& stream, std::streampos header_offset, - bool is_lazy ) = 0; + bool is_lazy ) = 0; + + /** + * @brief Save the section to a stream. + * @param stream Output stream. + * @param header_offset Offset of the header. + * @param data_offset Offset of the data. + */ virtual void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) = 0; - virtual bool is_address_initialized() const = 0; + + /** + * @brief Check if the address is initialized. + * @return True if initialized, false otherwise. + */ + virtual bool is_address_initialized() const = 0; }; +/** + * @class section_impl + * @brief Implementation of the section class. + * @tparam T Type of the section header. + */ template class section_impl : public section { public: - //------------------------------------------------------------------------------ + /** + * @brief Constructor. + * @param convertor Pointer to the endianness convertor. + * @param translator Pointer to the address translator. + * @param compression Shared pointer to the compression interface. + */ section_impl( const endianness_convertor* convertor, const address_translator* translator, const std::shared_ptr& compression ) @@ -87,7 +173,6 @@ template class section_impl : public section { } - //------------------------------------------------------------------------------ // Section info functions ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); @@ -98,19 +183,32 @@ template class section_impl : public section ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr ); - //------------------------------------------------------------------------------ + + /** + * @brief Get the index of the section. + * @return Index of the section. + */ Elf_Half get_index() const override { return index; } - //------------------------------------------------------------------------------ + /** + * @brief Get the name of the section. + * @return Name of the section. + */ std::string get_name() const override { return name; } - //------------------------------------------------------------------------------ + /** + * @brief Set the name of the section. + * @param name_prm Name of the section. + */ void set_name( const std::string& name_prm ) override { this->name = name_prm; } - //------------------------------------------------------------------------------ + /** + * @brief Set the address of the section. + * @param value Address of the section. + */ void set_address( const Elf64_Addr& value ) override { header.sh_addr = decltype( header.sh_addr )( value ); @@ -118,10 +216,16 @@ template class section_impl : public section is_address_set = true; } - //------------------------------------------------------------------------------ + /** + * @brief Check if the address is initialized. + * @return True if initialized, false otherwise. + */ bool is_address_initialized() const override { return is_address_set; } - //------------------------------------------------------------------------------ + /** + * @brief Get the data of the section. + * @return Pointer to the data. + */ const char* get_data() const override { if ( !is_loaded ) { @@ -130,7 +234,9 @@ template class section_impl : public section return data.get(); } - //------------------------------------------------------------------------------ + /** + * @brief Free the data of the section. + */ void free_data() const override { if ( is_lazy ) { @@ -139,7 +245,11 @@ template class section_impl : public section } } - //------------------------------------------------------------------------------ + /** + * @brief Set the data of the section. + * @param raw_data Pointer to the raw data. + * @param size Size of the data. + */ void set_data( const char* raw_data, Elf_Word size ) override { if ( get_type() != SHT_NOBITS ) { @@ -159,25 +269,40 @@ template class section_impl : public section } } - //------------------------------------------------------------------------------ + /** + * @brief Set the data of the section. + * @param str_data String containing the data. + */ void set_data( const std::string& str_data ) override { return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); } - //------------------------------------------------------------------------------ + /** + * @brief Append data to the section. + * @param raw_data Pointer to the raw data. + * @param size Size of the data. + */ void append_data( const char* raw_data, Elf_Word size ) override { insert_data( get_size(), raw_data, size ); } - //------------------------------------------------------------------------------ + /** + * @brief Append data to the section. + * @param str_data String containing the data. + */ void append_data( const std::string& str_data ) override { return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); } - //------------------------------------------------------------------------------ + /** + * @brief Insert data into the section at a specific position. + * @param pos Position to insert the data. + * @param raw_data Pointer to the raw data. + * @param size Size of the data. + */ void insert_data( Elf_Xword pos, const char* raw_data, Elf_Word size ) override { @@ -213,25 +338,41 @@ template class section_impl : public section } } - //------------------------------------------------------------------------------ + /** + * @brief Insert data into the section at a specific position. + * @param pos Position to insert the data. + * @param str_data String containing the data. + */ void insert_data( Elf_Xword pos, const std::string& str_data ) override { return insert_data( pos, str_data.c_str(), (Elf_Word)str_data.size() ); } + /** + * @brief Get the size of the stream. + * @return Size of the stream. + */ size_t get_stream_size() const override { return stream_size; } - //------------------------------------------------------------------------------ + /** + * @brief Set the size of the stream. + * @param value Size of the stream. + */ void set_stream_size( size_t value ) override { stream_size = value; } - //------------------------------------------------------------------------------ protected: - //------------------------------------------------------------------------------ ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); - //------------------------------------------------------------------------------ + /** + * @brief Set the index of the section. + * @param value Index of the section. + */ void set_index( const Elf_Half& value ) override { index = value; } + /** + * @brief Check if the section is compressed. + * @return True if compressed, false otherwise. + */ bool is_compressed() const { return ( ( get_flags() & SHF_RPX_DEFLATE ) || @@ -239,7 +380,13 @@ template class section_impl : public section compression != nullptr; } - //------------------------------------------------------------------------------ + /** + * @brief Load the section from a stream. + * @param stream Input stream. + * @param header_offset Offset of the header. + * @param is_lazy_ Whether to load lazily. + * @return True if successful, false otherwise. + */ bool load( std::istream& stream, std::streampos header_offset, bool is_lazy_ ) override @@ -278,6 +425,10 @@ template class section_impl : public section return true; } + /** + * @brief Load the data of the section. + * @return True if successful, false otherwise. + */ bool load_data() const { Elf_Xword sh_offset = @@ -312,7 +463,12 @@ template class section_impl : public section return true; } - //------------------------------------------------------------------------------ + /** + * @brief Save the section to a stream. + * @param stream Output stream. + * @param header_offset Offset of the header. + * @param data_offset Offset of the data. + */ void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) override @@ -329,9 +485,12 @@ template class section_impl : public section } } - //------------------------------------------------------------------------------ private: - //------------------------------------------------------------------------------ + /** + * @brief Save the header of the section to a stream. + * @param stream Output stream. + * @param header_offset Offset of the header. + */ void save_header( std::ostream& stream, std::streampos header_offset ) const { adjust_stream_size( stream, header_offset ); @@ -339,7 +498,11 @@ template class section_impl : public section sizeof( header ) ); } - //------------------------------------------------------------------------------ + /** + * @brief Save the data of the section to a stream. + * @param stream Output stream. + * @param data_offset Offset of the data. + */ void save_data( std::ostream& stream, std::streampos data_offset ) { adjust_stream_size( stream, data_offset ); @@ -358,21 +521,26 @@ template class section_impl : public section } } - //------------------------------------------------------------------------------ private: - mutable std::istream* pstream = nullptr; - T header = {}; - Elf_Half index = 0; - std::string name; - mutable std::unique_ptr data; - mutable Elf_Word data_size = 0; - const endianness_convertor* convertor = nullptr; - const address_translator* translator = nullptr; - const std::shared_ptr compression = nullptr; - bool is_address_set = false; - size_t stream_size = 0; - mutable bool is_lazy = false; - mutable bool is_loaded = false; + mutable std::istream* pstream = + nullptr; /**< Pointer to the input stream. */ + T header = {}; /**< Section header. */ + Elf_Half index = 0; /**< Index of the section. */ + std::string name; /**< Name of the section. */ + mutable std::unique_ptr data; /**< Pointer to the data. */ + mutable Elf_Word data_size = 0; /**< Size of the data. */ + const endianness_convertor* convertor = + nullptr; /**< Pointer to the endianness convertor. */ + const address_translator* translator = + nullptr; /**< Pointer to the address translator. */ + const std::shared_ptr compression = + nullptr; /**< Shared pointer to the compression interface. */ + bool is_address_set = false; /**< Flag indicating if the address is set. */ + size_t stream_size = 0; /**< Size of the stream. */ + mutable bool is_lazy = + false; /**< Flag indicating if lazy loading is enabled. */ + mutable bool is_loaded = + false; /**< Flag indicating if the data is loaded. */ }; } // namespace ELFIO diff --git a/elfio/elfio_segment.hpp b/elfio/elfio_segment.hpp index 402d461f..d0f1b782 100644 --- a/elfio/elfio_segment.hpp +++ b/elfio/elfio_segment.hpp @@ -30,6 +30,9 @@ THE SOFTWARE. namespace ELFIO { +//------------------------------------------------------------------------------ +//! \class segment +//! \brief Class for accessing segment data class segment { friend class elfio; @@ -37,45 +40,122 @@ class segment public: virtual ~segment() = default; + //------------------------------------------------------------------------------ + //! \brief Get the index of the segment + //! \return Index of the segment ELFIO_GET_ACCESS_DECL( Elf_Half, index ); + //------------------------------------------------------------------------------ + //! \brief Get the type of the segment + //! \return Type of the segment ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); + //------------------------------------------------------------------------------ + //! \brief Get the flags of the segment + //! \return Flags of the segment ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); + //------------------------------------------------------------------------------ + //! \brief Get the alignment of the segment + //! \return Alignment of the segment ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); + //------------------------------------------------------------------------------ + //! \brief Get the virtual address of the segment + //! \return Virtual address of the segment ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); + //------------------------------------------------------------------------------ + //! \brief Get the physical address of the segment + //! \return Physical address of the segment ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); + //------------------------------------------------------------------------------ + //! \brief Get the file size of the segment + //! \return File size of the segment ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); + //------------------------------------------------------------------------------ + //! \brief Get the memory size of the segment + //! \return Memory size of the segment ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); + //------------------------------------------------------------------------------ + //! \brief Get the offset of the segment + //! \return Offset of the segment ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); - virtual const char* get_data() const = 0; - virtual void free_data() const = 0; + //------------------------------------------------------------------------------ + //! \brief Get the data of the segment + //! \return Pointer to the data + virtual const char* get_data() const = 0; + //------------------------------------------------------------------------------ + //! \brief Free the data of the segment + virtual void free_data() const = 0; + //------------------------------------------------------------------------------ + //! \brief Add a section to the segment + //! \param psec Pointer to the section + //! \param addr_align Alignment of the section + //! \return Index of the added section virtual Elf_Half add_section( section* psec, Elf_Xword addr_align ) = 0; + //------------------------------------------------------------------------------ + //! \brief Add a section index to the segment + //! \param index Index of the section + //! \param addr_align Alignment of the section + //! \return Index of the added section virtual Elf_Half add_section_index( Elf_Half index, - Elf_Xword addr_align ) = 0; - virtual Elf_Half get_sections_num() const = 0; - virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; - virtual bool is_offset_initialized() const = 0; + Elf_Xword addr_align ) = 0; + //------------------------------------------------------------------------------ + //! \brief Get the number of sections in the segment + //! \return Number of sections in the segment + virtual Elf_Half get_sections_num() const = 0; + //------------------------------------------------------------------------------ + //! \brief Get the index of a section at a given position + //! \param num Position of the section + //! \return Index of the section + virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; + //------------------------------------------------------------------------------ + //! \brief Check if the offset is initialized + //! \return True if the offset is initialized, false otherwise + virtual bool is_offset_initialized() const = 0; protected: + //------------------------------------------------------------------------------ + //! \brief Set the offset of the segment + //! \param offset Offset of the segment ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); + //------------------------------------------------------------------------------ + //! \brief Set the index of the segment + //! \param index Index of the segment ELFIO_SET_ACCESS_DECL( Elf_Half, index ); + //------------------------------------------------------------------------------ + //! \brief Get the sections of the segment + //! \return Vector of section indices virtual const std::vector& get_sections() const = 0; + //------------------------------------------------------------------------------ + //! \brief Load the segment from a stream + //! \param stream Input stream + //! \param header_offset Offset of the segment header + //! \param is_lazy Whether to load the segment lazily + //! \return True if successful, false otherwise virtual bool load( std::istream& stream, std::streampos header_offset, - bool is_lazy ) = 0; + bool is_lazy ) = 0; + //------------------------------------------------------------------------------ + //! \brief Save the segment to a stream + //! \param stream Output stream + //! \param header_offset Offset of the segment header + //! \param data_offset Offset of the segment data virtual void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) = 0; }; //------------------------------------------------------------------------------ +//! \class segment_impl +//! \brief Implementation of the segment class template class segment_impl : public segment { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param convertor Pointer to the endianness convertor + //! \param translator Pointer to the address translator segment_impl( const endianness_convertor* convertor, const address_translator* translator ) : convertor( convertor ), translator( translator ) @@ -94,9 +174,13 @@ template class segment_impl : public segment ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); //------------------------------------------------------------------------------ + //! \brief Get the index of the segment + //! \return Index of the segment Elf_Half get_index() const override { return index; } //------------------------------------------------------------------------------ + //! \brief Get the data of the segment + //! \return Pointer to the data const char* get_data() const override { if ( !is_loaded ) { @@ -106,6 +190,7 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Free the data of the segment void free_data() const override { if ( is_lazy ) { @@ -115,6 +200,10 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Add a section index to the segment + //! \param sec_index Index of the section + //! \param addr_align Alignment of the section + //! \return Index of the added section Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align ) override { @@ -127,18 +216,27 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Add a section to the segment + //! \param psec Pointer to the section + //! \param addr_align Alignment of the section + //! \return Index of the added section Elf_Half add_section( section* psec, Elf_Xword addr_align ) override { return add_section_index( psec->get_index(), addr_align ); } //------------------------------------------------------------------------------ + //! \brief Get the number of sections in the segment + //! \return Number of sections in the segment Elf_Half get_sections_num() const override { return (Elf_Half)sections.size(); } //------------------------------------------------------------------------------ + //! \brief Get the index of a section at a given position + //! \param num Position of the section + //! \return Index of the section Elf_Half get_section_index_at( Elf_Half num ) const override { if ( num < sections.size() ) { @@ -151,8 +249,8 @@ template class segment_impl : public segment //------------------------------------------------------------------------------ protected: //------------------------------------------------------------------------------ - - //------------------------------------------------------------------------------ + //! \brief Set the offset of the segment + //! \param value Offset of the segment void set_offset( const Elf64_Off& value ) override { ph.p_offset = decltype( ph.p_offset )( value ); @@ -161,18 +259,29 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Check if the offset is initialized + //! \return True if the offset is initialized, false otherwise bool is_offset_initialized() const override { return is_offset_set; } //------------------------------------------------------------------------------ + //! \brief Get the sections of the segment + //! \return Vector of section indices const std::vector& get_sections() const override { return sections; } //------------------------------------------------------------------------------ + //! \brief Set the index of the segment + //! \param value Index of the segment void set_index( const Elf_Half& value ) override { index = value; } //------------------------------------------------------------------------------ + //! \brief Load the segment from a stream + //! \param stream Input stream + //! \param header_offset Offset of the segment header + //! \param is_lazy_ Whether to load the segment lazily + //! \return True if successful, false otherwise bool load( std::istream& stream, std::streampos header_offset, bool is_lazy_ ) override @@ -200,6 +309,8 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Load the data of the segment + //! \return True if successful, false otherwise bool load_data() const { if ( PT_NULL == get_type() || 0 == get_file_size() ) { @@ -231,6 +342,10 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Save the segment to a stream + //! \param stream Output stream + //! \param header_offset Offset of the segment header + //! \param data_offset Offset of the segment data void save( std::ostream& stream, std::streampos header_offset, std::streampos data_offset ) override @@ -242,24 +357,32 @@ template class segment_impl : public segment } //------------------------------------------------------------------------------ + //! \brief Get the stream size + //! \return Stream size size_t get_stream_size() const { return stream_size; } //------------------------------------------------------------------------------ + //! \brief Set the stream size + //! \param value Stream size void set_stream_size( size_t value ) { stream_size = value; } //------------------------------------------------------------------------------ private: - mutable std::istream* pstream = nullptr; - T ph = {}; - Elf_Half index = 0; - mutable std::unique_ptr data; - std::vector sections; - const endianness_convertor* convertor = nullptr; - const address_translator* translator = nullptr; - size_t stream_size = 0; - bool is_offset_set = false; - mutable bool is_lazy = false; - mutable bool is_loaded = false; + mutable std::istream* pstream = nullptr; //!< Pointer to the input stream + T ph = {}; //!< Segment header + Elf_Half index = 0; //!< Index of the segment + mutable std::unique_ptr data; //!< Pointer to the segment data + std::vector sections; //!< Vector of section indices + const endianness_convertor* convertor = + nullptr; //!< Pointer to the endianness convertor + const address_translator* translator = + nullptr; //!< Pointer to the address translator + size_t stream_size = 0; //!< Stream size + bool is_offset_set = false; //!< Flag indicating if the offset is set + mutable bool is_lazy = + false; //!< Flag indicating if the segment is loaded lazily + mutable bool is_loaded = + false; //!< Flag indicating if the segment is loaded }; } // namespace ELFIO diff --git a/elfio/elfio_strings.hpp b/elfio/elfio_strings.hpp index 530e0370..ef957024 100644 --- a/elfio/elfio_strings.hpp +++ b/elfio/elfio_strings.hpp @@ -30,23 +30,31 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +//! \class string_section_accessor_template +//! \brief Class for accessing string section data template class string_section_accessor_template { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param section Pointer to the section explicit string_section_accessor_template( S* section ) : string_section( section ) { } //------------------------------------------------------------------------------ + //! \brief Get a string from the section + //! \param index Index of the string + //! \return Pointer to the string, or nullptr if not found const char* get_string( Elf_Word index ) const { if ( string_section ) { const char* data = string_section->get_data(); if ( index < string_section->get_size() && nullptr != data ) { size_t string_length = strnlength( - data + index, string_section->get_size() - index ); + data + index, + static_cast( string_section->get_size() ) - index ); if ( string_length < ( string_section->get_size() - index ) ) return data + index; } @@ -56,12 +64,15 @@ template class string_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add a string to the section + //! \param str Pointer to the string + //! \return Index of the added string Elf_Word add_string( const char* str ) { Elf_Word current_position = 0; if ( string_section ) { - // Strings are addeded to the end of the current section data + // Strings are added to the end of the current section data current_position = static_cast( string_section->get_size() ); @@ -78,6 +89,9 @@ template class string_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add a string to the section + //! \param str The string to add + //! \return Index of the added string Elf_Word add_string( const std::string& str ) { return add_string( str.c_str() ); @@ -85,7 +99,7 @@ template class string_section_accessor_template //------------------------------------------------------------------------------ private: - S* string_section; + S* string_section; //!< Pointer to the section }; using string_section_accessor = string_section_accessor_template
; diff --git a/elfio/elfio_symbols.hpp b/elfio/elfio_symbols.hpp index f84e7c5e..d3848f59 100644 --- a/elfio/elfio_symbols.hpp +++ b/elfio/elfio_symbols.hpp @@ -25,10 +25,17 @@ THE SOFTWARE. namespace ELFIO { +//------------------------------------------------------------------------------ +// @class symbol_section_accessor_template +// @brief A template class for accessing symbol sections in an ELF file. //------------------------------------------------------------------------------ template class symbol_section_accessor_template { public: + //------------------------------------------------------------------------------ + // @brief Constructor + // @param elf_file Reference to the ELF file + // @param symbol_section Pointer to the symbol section //------------------------------------------------------------------------------ explicit symbol_section_accessor_template( const elfio& elf_file, S* symbol_section ) @@ -37,6 +44,9 @@ template class symbol_section_accessor_template find_hash_section(); } + //------------------------------------------------------------------------------ + // @brief Get the number of symbols in the section + // @return Number of symbols //------------------------------------------------------------------------------ Elf_Xword get_symbols_num() const { @@ -63,6 +73,17 @@ template class symbol_section_accessor_template return nRet; } + //------------------------------------------------------------------------------ + // @brief Get the symbol at the specified index + // @param index Index of the symbol + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param section_index Section index of the symbol + // @param other Other attributes of the symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ bool get_symbol( Elf_Xword index, std::string& name, @@ -87,6 +108,16 @@ template class symbol_section_accessor_template return ret; } + //------------------------------------------------------------------------------ + // @brief Get the symbol with the specified name + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param section_index Section index of the symbol + // @param other Other attributes of the symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ bool get_symbol( const std::string& name, Elf64_Addr& value, @@ -130,6 +161,16 @@ template class symbol_section_accessor_template return ret; } + //------------------------------------------------------------------------------ + // @brief Get the symbol with the specified value + // @param value Value of the symbol + // @param name Name of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param section_index Section index of the symbol + // @param other Other attributes of the symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ bool get_symbol( const Elf64_Addr& value, std::string& name, @@ -169,6 +210,15 @@ template class symbol_section_accessor_template return false; } + //------------------------------------------------------------------------------ + // @brief Add a symbol to the section + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param info Info of the symbol + // @param other Other attributes of the symbol + // @param shndx Section index of the symbol + // @return Index of the added symbol //------------------------------------------------------------------------------ Elf_Word add_symbol( Elf_Word name, Elf64_Addr value, @@ -200,6 +250,16 @@ template class symbol_section_accessor_template return nRet; } + //------------------------------------------------------------------------------ + // @brief Add a symbol to the section + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param other Other attributes of the symbol + // @param shndx Section index of the symbol + // @return Index of the added symbol //------------------------------------------------------------------------------ Elf_Word add_symbol( Elf_Word name, Elf64_Addr value, @@ -213,6 +273,16 @@ template class symbol_section_accessor_template shndx ); } + //------------------------------------------------------------------------------ + // @brief Add a symbol to the section + // @param pStrWriter String section accessor + // @param str Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param info Info of the symbol + // @param other Other attributes of the symbol + // @param shndx Section index of the symbol + // @return Index of the added symbol //------------------------------------------------------------------------------ Elf_Word add_symbol( string_section_accessor& pStrWriter, const char* str, @@ -226,6 +296,17 @@ template class symbol_section_accessor_template return add_symbol( index, value, size, info, other, shndx ); } + //------------------------------------------------------------------------------ + // @brief Add a symbol to the section + // @param pStrWriter String section accessor + // @param str Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param other Other attributes of the symbol + // @param shndx Section index of the symbol + // @return Index of the added symbol //------------------------------------------------------------------------------ Elf_Word add_symbol( string_section_accessor& pStrWriter, const char* str, @@ -240,6 +321,10 @@ template class symbol_section_accessor_template ELF_ST_INFO( bind, type ), other, shndx ); } + //------------------------------------------------------------------------------ + // @brief Arrange local symbols in the section + // @param func Function to be called for each pair of symbols + // @return Number of local symbols //------------------------------------------------------------------------------ Elf_Xword arrange_local_symbols( std::function func = @@ -259,6 +344,8 @@ template class symbol_section_accessor_template //------------------------------------------------------------------------------ private: + //------------------------------------------------------------------------------ + // @brief Find the hash section //------------------------------------------------------------------------------ void find_hash_section() { @@ -276,15 +363,31 @@ template class symbol_section_accessor_template } } + //------------------------------------------------------------------------------ + // @brief Get the index of the string table + // @return Index of the string table //------------------------------------------------------------------------------ Elf_Half get_string_table_index() const { return (Elf_Half)symbol_section->get_link(); } + //------------------------------------------------------------------------------ + // @brief Get the index of the hash table + // @return Index of the hash table //------------------------------------------------------------------------------ Elf_Half get_hash_table_index() const { return hash_section_index; } + //------------------------------------------------------------------------------ + // @brief Lookup a symbol in the hash table + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param section_index Section index of the symbol + // @param other Other attributes of the symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ bool hash_lookup( const std::string& name, Elf64_Addr& value, @@ -323,6 +426,16 @@ template class symbol_section_accessor_template return ret; } + //------------------------------------------------------------------------------ + // @brief Lookup a symbol in the GNU hash table + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param section_index Section index of the symbol + // @param other Other attributes of the symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ template bool gnu_hash_lookup( const std::string& name, @@ -391,6 +504,10 @@ template class symbol_section_accessor_template return ret; } + //------------------------------------------------------------------------------ + // @brief Get the symbol at the specified index + // @param index Index of the symbol + // @return Pointer to the symbol //------------------------------------------------------------------------------ template const T* generic_get_symbol_ptr( Elf_Xword index ) const { @@ -408,6 +525,11 @@ template class symbol_section_accessor_template return nullptr; } + //------------------------------------------------------------------------------ + // @brief Search for a symbol in the section + // @param match Function to be called for each symbol + // @param idx Index of the found symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ template bool generic_search_symbols( std::function match, @@ -428,6 +550,17 @@ template class symbol_section_accessor_template return false; } + //------------------------------------------------------------------------------ + // @brief Get the symbol at the specified index + // @param index Index of the symbol + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param bind Binding of the symbol + // @param type Type of the symbol + // @param section_index Section index of the symbol + // @param other Other attributes of the symbol + // @return True if the symbol is found, false otherwise //------------------------------------------------------------------------------ template bool generic_get_symbol( Elf_Xword index, @@ -470,6 +603,15 @@ template class symbol_section_accessor_template return ret; } + //------------------------------------------------------------------------------ + // @brief Add a symbol to the section + // @param name Name of the symbol + // @param value Value of the symbol + // @param size Size of the symbol + // @param info Info of the symbol + // @param other Other attributes of the symbol + // @param shndx Section index of the symbol + // @return Index of the added symbol //------------------------------------------------------------------------------ template Elf_Word generic_add_symbol( Elf_Word name, @@ -500,6 +642,10 @@ template class symbol_section_accessor_template return nRet; } + //------------------------------------------------------------------------------ + // @brief Arrange local symbols in the section + // @param func Function to be called for each pair of symbols + // @return Number of local symbols //------------------------------------------------------------------------------ template Elf_Xword generic_arrange_local_symbols( @@ -550,10 +696,10 @@ template class symbol_section_accessor_template //------------------------------------------------------------------------------ private: - const elfio& elf_file; - S* symbol_section; - Elf_Half hash_section_index{ 0 }; - const section* hash_section{ nullptr }; + const elfio& elf_file; ///< Reference to the ELF file + S* symbol_section; ///< Pointer to the symbol section + Elf_Half hash_section_index{ 0 }; ///< Index of the hash section + const section* hash_section{ nullptr }; ///< Pointer to the hash section }; using symbol_section_accessor = symbol_section_accessor_template
; diff --git a/elfio/elfio_utils.hpp b/elfio/elfio_utils.hpp index 69d96a9a..a7c8c81f 100644 --- a/elfio/elfio_utils.hpp +++ b/elfio/elfio_utils.hpp @@ -56,16 +56,23 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +//! \class endianness_convertor +//! \brief Class for converting endianness of data class endianness_convertor { public: //------------------------------------------------------------------------------ + //! \brief Setup the endianness convertor + //! \param elf_file_encoding The encoding of the ELF file void setup( unsigned char elf_file_encoding ) { need_conversion = ( elf_file_encoding != get_host_encoding() ); } //------------------------------------------------------------------------------ + //! \brief Convert a 64-bit unsigned integer + //! \param value The value to convert + //! \return The converted value uint64_t operator()( uint64_t value ) const { if ( !need_conversion ) { @@ -84,6 +91,9 @@ class endianness_convertor } //------------------------------------------------------------------------------ + //! \brief Convert a 64-bit signed integer + //! \param value The value to convert + //! \return The converted value int64_t operator()( int64_t value ) const { if ( !need_conversion ) { @@ -93,6 +103,9 @@ class endianness_convertor } //------------------------------------------------------------------------------ + //! \brief Convert a 32-bit unsigned integer + //! \param value The value to convert + //! \return The converted value uint32_t operator()( uint32_t value ) const { if ( !need_conversion ) { @@ -106,6 +119,9 @@ class endianness_convertor } //------------------------------------------------------------------------------ + //! \brief Convert a 32-bit signed integer + //! \param value The value to convert + //! \return The converted value int32_t operator()( int32_t value ) const { if ( !need_conversion ) { @@ -115,6 +131,9 @@ class endianness_convertor } //------------------------------------------------------------------------------ + //! \brief Convert a 16-bit unsigned integer + //! \param value The value to convert + //! \return The converted value uint16_t operator()( uint16_t value ) const { if ( !need_conversion ) { @@ -127,6 +146,9 @@ class endianness_convertor } //------------------------------------------------------------------------------ + //! \brief Convert a 16-bit signed integer + //! \param value The value to convert + //! \return The converted value int16_t operator()( int16_t value ) const { if ( !need_conversion ) { @@ -136,14 +158,22 @@ class endianness_convertor } //------------------------------------------------------------------------------ + //! \brief Convert an 8-bit signed integer + //! \param value The value to convert + //! \return The converted value int8_t operator()( int8_t value ) const { return value; } //------------------------------------------------------------------------------ + //! \brief Convert an 8-bit unsigned integer + //! \param value The value to convert + //! \return The converted value uint8_t operator()( uint8_t value ) const { return value; } //------------------------------------------------------------------------------ private: //------------------------------------------------------------------------------ + //! \brief Get the host encoding + //! \return The host encoding unsigned char get_host_encoding() const { static const int tmp = 1; @@ -156,24 +186,35 @@ class endianness_convertor } //------------------------------------------------------------------------------ - bool need_conversion = false; + bool need_conversion = false; //!< Flag indicating if conversion is needed }; //------------------------------------------------------------------------------ +//! \struct address_translation +//! \brief Structure for address translation struct address_translation { + //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param start The start address + //! \param size The size of the address range + //! \param mapped_to The mapped address address_translation( uint64_t start, uint64_t size, uint64_t mapped_to ) : start( start ), size( size ), mapped_to( mapped_to ){}; - std::streampos start; - std::streampos size; - std::streampos mapped_to; + std::streampos start; //!< Start address + std::streampos size; //!< Size of the address range + std::streampos mapped_to; //!< Mapped address }; //------------------------------------------------------------------------------ +//! \class address_translator +//! \brief Class for translating addresses class address_translator { public: //------------------------------------------------------------------------------ + //! \brief Set address translation + //! \param addr_trans Vector of address translations void set_address_translation( std::vector& addr_trans ) { addr_translations = addr_trans; @@ -186,6 +227,9 @@ class address_translator } //------------------------------------------------------------------------------ + //! \brief Translate an address + //! \param value The address to translate + //! \return The translated address std::streampos operator[]( std::streampos value ) const { if ( addr_translations.empty() ) { @@ -201,13 +245,20 @@ class address_translator return value; } + //------------------------------------------------------------------------------ + //! \brief Check if the address translator is empty + //! \return True if empty, false otherwise bool empty() const { return addr_translations.empty(); } private: - std::vector addr_translations; + std::vector + addr_translations; //!< Vector of address translations }; //------------------------------------------------------------------------------ +//! \brief Calculate the ELF hash of a name +//! \param name The name to hash +//! \return The ELF hash inline uint32_t elf_hash( const unsigned char* name ) { uint32_t h = 0; @@ -223,6 +274,9 @@ inline uint32_t elf_hash( const unsigned char* name ) } //------------------------------------------------------------------------------ +//! \brief Calculate the GNU hash of a name +//! \param s The name to hash +//! \return The GNU hash inline uint32_t elf_gnu_hash( const unsigned char* s ) { uint32_t h = 0x1505; @@ -232,6 +286,9 @@ inline uint32_t elf_gnu_hash( const unsigned char* s ) } //------------------------------------------------------------------------------ +//! \brief Convert a value to a hexadecimal string +//! \param value The value to convert +//! \return The hexadecimal string inline std::string to_hex_string( uint64_t value ) { std::string str; @@ -250,6 +307,9 @@ inline std::string to_hex_string( uint64_t value ) } //------------------------------------------------------------------------------ +//! \brief Adjust the size of a stream +//! \param stream The stream to adjust +//! \param offset The offset to adjust to inline void adjust_stream_size( std::ostream& stream, std::streamsize offset ) { stream.seekp( 0, std::ios_base::end ); @@ -261,43 +321,44 @@ inline void adjust_stream_size( std::ostream& stream, std::streamsize offset ) } //------------------------------------------------------------------------------ +//! \brief Get the length of a string with a maximum length +//! \param s The string +//! \param n The maximum length +//! \return The length of the string inline static size_t strnlength( const char* s, size_t n ) { auto found = (const char*)std::memchr( s, '\0', n ); return found ? (size_t)( found - s ) : n; } -/** - * Consumers should write an implementation of this class and pass an instance of it to the ELFIO::elfio constructor. - */ +//------------------------------------------------------------------------------ +//! \class compression_interface +//! \brief Interface for compression and decompression class compression_interface { public: virtual ~compression_interface() = default; - /** - * decompresses a compressed section - * - * @param data the buffer of compressed data - * @param endianness_convertor pointer to an endianness_convertor instance, used to convert numbers to/from the target endianness. - * @param compressed_size the size of the data buffer, in bytes - * @param decompressed_size a reference to a variable where the decompressed buffer size will be stored. - * @returns a smart pointer to the decompressed data. - */ + + //------------------------------------------------------------------------------ + //! \brief Decompress a compressed section + //! \param data The buffer of compressed data + //! \param convertor Pointer to an endianness convertor instance + //! \param compressed_size The size of the compressed data buffer + //! \param uncompressed_size Reference to a variable to store the decompressed buffer size + //! \return A smart pointer to the decompressed data virtual std::unique_ptr inflate( const char* data, const endianness_convertor* convertor, Elf_Xword compressed_size, Elf_Xword& uncompressed_size ) const = 0; - /** - * compresses a section - * - * @param data the buffer of uncompressed data - * @param endianness_convertor pointer to an endianness_convertor instance, used to convert numbers to/from the target endianness. - * @param decompressed_size the size of the data buffer, in bytes - * @param compressed_size a reference to a variable where the compressed buffer size will be stored. - * @returns a smart pointer to the compressed data. - */ + //------------------------------------------------------------------------------ + //! \brief Compress a section + //! \param data The buffer of uncompressed data + //! \param convertor Pointer to an endianness convertor instance + //! \param decompressed_size The size of the uncompressed data buffer + //! \param compressed_size Reference to a variable to store the compressed buffer size + //! \return A smart pointer to the compressed data virtual std::unique_ptr deflate( const char* data, const endianness_convertor* convertor, diff --git a/elfio/elfio_version.hpp b/elfio/elfio_version.hpp index 4a25268e..0a1426dc 100644 --- a/elfio/elfio_version.hpp +++ b/elfio/elfio_version.hpp @@ -1 +1,4 @@ +//------------------------------------------------------------------------------ +//! \def ELFIO_VERSION +//! \brief Defines the version of the ELFIO library #define ELFIO_VERSION "3.14" diff --git a/elfio/elfio_versym.hpp b/elfio/elfio_versym.hpp index 003a7e1b..16f735ff 100644 --- a/elfio/elfio_versym.hpp +++ b/elfio/elfio_versym.hpp @@ -26,10 +26,14 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ +//! \class versym_section_accessor_template +//! \brief Class for accessing version symbol section data template class versym_section_accessor_template { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param section Pointer to the section explicit versym_section_accessor_template( S* section ) : versym_section( section ) { @@ -40,6 +44,8 @@ template class versym_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get the number of entries + //! \return Number of entries Elf_Word get_entries_num() const { if ( versym_section ) { @@ -49,6 +55,10 @@ template class versym_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get an entry + //! \param no Index of the entry + //! \param value Value of the entry + //! \return True if successful, false otherwise bool get_entry( Elf_Word no, Elf_Half& value ) const { if ( versym_section && ( no < get_entries_num() ) ) { @@ -60,6 +70,10 @@ template class versym_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Modify an entry + //! \param no Index of the entry + //! \param value New value of the entry + //! \return True if successful, false otherwise bool modify_entry( Elf_Word no, Elf_Half value ) { if ( versym_section && ( no < get_entries_num() ) ) { @@ -71,6 +85,9 @@ template class versym_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Add an entry + //! \param value Value of the entry + //! \return True if successful, false otherwise bool add_entry( Elf_Half value ) { if ( !versym_section ) { @@ -85,8 +102,8 @@ template class versym_section_accessor_template //------------------------------------------------------------------------------ private: - S* versym_section = nullptr; - Elf_Word entries_num = 0; + S* versym_section = nullptr; //!< Pointer to the section + Elf_Word entries_num = 0; //!< Number of entries }; using versym_section_accessor = versym_section_accessor_template
; @@ -94,10 +111,15 @@ using const_versym_section_accessor = versym_section_accessor_template; //------------------------------------------------------------------------------ +//! \class versym_r_section_accessor_template +//! \brief Class for accessing version requirement section data template class versym_r_section_accessor_template { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param elf_file Reference to the ELF file + //! \param versym_r_section Pointer to the version requirement section versym_r_section_accessor_template( const elfio& elf_file, S* versym_r_section ) : elf_file( elf_file ), versym_r_section( versym_r_section ), @@ -127,9 +149,20 @@ template class versym_r_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get the number of entries + //! \return Number of entries Elf_Word get_entries_num() const { return entries_num; } //------------------------------------------------------------------------------ + //! \brief Get an entry + //! \param no Index of the entry + //! \param version Version of the entry + //! \param file_name File name of the entry + //! \param hash Hash of the entry + //! \param flags Flags of the entry + //! \param other Other information of the entry + //! \param dep_name Dependency name of the entry + //! \return True if successful, false otherwise bool get_entry( Elf_Word no, Elf_Half& version, std::string& file_name, @@ -166,8 +199,9 @@ template class versym_r_section_accessor_template //------------------------------------------------------------------------------ private: const elfio& elf_file; - S* versym_r_section = nullptr; - Elf_Word entries_num = 0; + S* versym_r_section = + nullptr; //!< Pointer to the version requirement section + Elf_Word entries_num = 0; //!< Number of entries }; using versym_r_section_accessor = versym_r_section_accessor_template
; @@ -175,10 +209,15 @@ using const_versym_r_section_accessor = versym_r_section_accessor_template; //------------------------------------------------------------------------------ +//! \class versym_d_section_accessor_template +//! \brief Class for accessing version definition section data template class versym_d_section_accessor_template { public: //------------------------------------------------------------------------------ + //! \brief Constructor + //! \param elf_file Reference to the ELF file + //! \param versym_d_section Pointer to the version definition section versym_d_section_accessor_template( const elfio& elf_file, S* versym_d_section ) : elf_file( elf_file ), versym_d_section( versym_d_section ), @@ -208,9 +247,18 @@ template class versym_d_section_accessor_template } //------------------------------------------------------------------------------ + //! \brief Get the number of entries + //! \return Number of entries Elf_Word get_entries_num() const { return entries_num; } //------------------------------------------------------------------------------ + //! \brief Get an entry + //! \param no Index of the entry + //! \param flags Flags of the entry + //! \param version_index Version index of the entry + //! \param hash Hash of the entry + //! \param dep_name Dependency name of the entry + //! \return True if successful, false otherwise bool get_entry( Elf_Word no, Elf_Half& flags, Elf_Half& version_index, @@ -248,8 +296,9 @@ template class versym_d_section_accessor_template //------------------------------------------------------------------------------ private: const elfio& elf_file; - S* versym_d_section = nullptr; - Elf_Word entries_num = 0; + S* versym_d_section = + nullptr; //!< Pointer to the version definition section + Elf_Word entries_num = 0; //!< Number of entries }; using versym_d_section_accessor = versym_d_section_accessor_template
; diff --git a/tests/ELFIOTest.cpp b/tests/ELFIOTest.cpp index d8950cee..8a58357c 100644 --- a/tests/ELFIOTest.cpp +++ b/tests/ELFIOTest.cpp @@ -1016,7 +1016,7 @@ class mock_wiiu_compression : public compression_interface { uncompressed_size = 2 * compressed_size; return std::unique_ptr( - new ( std::nothrow ) char[uncompressed_size + 1] ); + new ( std::nothrow ) char[static_cast(uncompressed_size) + 1] ); } std::unique_ptr deflate( const char* data, @@ -1026,7 +1026,7 @@ class mock_wiiu_compression : public compression_interface { compressed_size = decompressed_size / 2; return std::unique_ptr( - new ( std::nothrow ) char[compressed_size + 1] ); + new ( std::nothrow ) char[static_cast(compressed_size) + 1] ); } }; @@ -1131,7 +1131,7 @@ TEST( ELFIOTest, test_free_data ) sec->free_data(); EXPECT_TRUE( 0 == std::memcmp( data.data(), sec->get_data(), - sec->get_size() ) ); + static_cast(sec->get_size()) ) ); } for ( const auto& seg : reader.segments ) { @@ -1145,7 +1145,7 @@ TEST( ELFIOTest, test_free_data ) seg->free_data(); EXPECT_TRUE( 0 == std::memcmp( data.data(), seg->get_data(), - seg->get_file_size() ) ); + static_cast(seg->get_file_size()) ) ); } } while ( is_lazy ); }