Add AI generated comments for classes and methods

This commit is contained in:
Serge Lamikhov-Center 2025-01-03 23:40:19 +02:00
parent 4c829d48eb
commit cba0a73823
17 changed files with 1370 additions and 249 deletions

View File

@ -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
};

View File

@ -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_interface>( 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<address_translation>& 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<std::ifstream>();
@ -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<elf_header> 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<segment*> get_ordered_segments() const
{
std::vector<segment*> 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<segment*> 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<bool>& 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<Elf_Half>( 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<std::unique_ptr<section>>::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<std::unique_ptr<section>>::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<std::unique_ptr<section>>::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<std::unique_ptr<section>>::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<Elf_Half>( 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<std::unique_ptr<segment>>::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<std::unique_ptr<segment>>::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<std::unique_ptr<segment>>::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<std::unique_ptr<segment>>::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<std::ifstream> pstream = nullptr;
std::unique_ptr<elf_header> header = nullptr;
std::vector<std::unique_ptr<section>> sections_;
std::vector<std::unique_ptr<segment>> segments_;
endianness_convertor convertor;
address_translator addr_translator;
std::shared_ptr<compression_interface> compression = nullptr;
std::unique_ptr<std::ifstream> pstream =
nullptr; //!< Pointer to the input stream
std::unique_ptr<elf_header> header = nullptr; //!< Pointer to the ELF header
std::vector<std::unique_ptr<section>> sections_; //!< Vector of sections
std::vector<std::unique_ptr<segment>> segments_; //!< Vector of segments
endianness_convertor convertor; //!< Endianness convertor
address_translator addr_translator; //!< Address translator
std::shared_ptr<compression_interface> compression =
nullptr; //!< Pointer to the compression interface
Elf_Xword current_file_pos = 0;
Elf_Xword current_file_pos = 0; //!< Current file position
};
} // namespace ELFIO

View File

@ -28,55 +28,86 @@ THE SOFTWARE.
namespace ELFIO {
//------------------------------------------------------------------------------
// Template class for accessing array sections
template <class S, typename T> 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<const T*>( 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<char*>( &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 <class S, typename T>
array_section_accessor_template<S, T>::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 <class S, typename T>
Elf_Xword array_section_accessor_template<S, T>::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 <class S, typename T>
bool array_section_accessor_template<S, T>::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<const T*>( array_section->get_data() +
index * sizeof( T ) );
address = convertor( temp );
return true;
}
//------------------------------------------------------------------------------
// Adds an entry to the array section
template <class S, typename T>
void array_section_accessor_template<S, T>::add_entry( Elf64_Addr address )
{
const endianness_convertor& convertor = elf_file.get_convertor();
T temp = convertor( (T)address );
array_section->append_data( reinterpret_cast<char*>( &temp ),
sizeof( temp ) );
}
// Type aliases for array section accessors
template <typename T = Elf32_Word>
using array_section_accessor = array_section_accessor_template<section, T>;
template <typename T = Elf32_Word>

View File

@ -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();

View File

@ -28,10 +28,12 @@ THE SOFTWARE.
namespace ELFIO {
//------------------------------------------------------------------------------
// Template class for accessing dynamic sections
template <class S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 <class T>
void generic_get_entry_dyn( Elf_Xword index,
Elf_Xword& tag,
@ -200,6 +207,7 @@ template <class S> class dynamic_section_accessor_template
}
//------------------------------------------------------------------------------
// Adds a generic entry to the dynamic section
template <class T>
void generic_add_entry_dyn( Elf_Xword tag, Elf_Xword value )
{
@ -258,13 +266,16 @@ template <class S> 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<section>;
using const_dynamic_section_accessor =
dynamic_section_accessor_template<const section>;

View File

@ -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 <class T> struct elf_header_impl_types;
template <> struct elf_header_impl_types<Elf32_Ehdr>
{
@ -71,10 +93,19 @@ template <> struct elf_header_impl_types<Elf64_Ehdr>
static const unsigned char file_class = ELFCLASS64;
};
/**
* @class elf_header_impl
* @brief Template class for ELF header implementation.
*/
template <class T> 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 T> 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 T> 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] );

View File

@ -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 S> 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 S> 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 S> 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 S> 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 S> 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 S> class modinfo_section_accessor_template
//------------------------------------------------------------------------------
private:
S* modinfo_section;
std::vector<std::pair<std::string, std::string>> content;
S* modinfo_section; ///< The section to be accessed.
std::vector<std::pair<std::string, std::string>>
content; ///< The list of attributes.
};
using modinfo_section_accessor = modinfo_section_accessor_template<section>;

View File

@ -38,11 +38,16 @@ namespace ELFIO {
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//! \class note_section_accessor_template
//! \brief Class for accessing note section data
template <class S, Elf_Xword ( S::*F_get_size )() const>
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<Elf_Xword> note_start_positions;
const elfio& elf_file; //!< Reference to the ELF file
S* notes; //!< Pointer to the section or segment
std::vector<Elf_Xword>
note_start_positions; //!< Vector of note start positions
};
using note_section_accessor =

View File

@ -28,10 +28,18 @@ namespace ELFIO {
template <typename T> struct get_sym_and_type;
template <> struct get_sym_and_type<Elf32_Rel>
{
//------------------------------------------------------------------------------
//! \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<Elf32_Rel>
};
template <> struct get_sym_and_type<Elf32_Rela>
{
//------------------------------------------------------------------------------
//! \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<Elf32_Rela>
};
template <> struct get_sym_and_type<Elf64_Rel>
{
//------------------------------------------------------------------------------
//! \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<Elf64_Rela>
{
//------------------------------------------------------------------------------
//! \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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 <class T>
bool generic_get_entry_rel( Elf_Xword index,
Elf64_Addr& offset,
@ -342,6 +443,13 @@ template <class S> 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 <class T>
bool generic_get_entry_rela( Elf_Xword index,
Elf64_Addr& offset,
@ -367,6 +475,12 @@ template <class S> 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 <class T>
void generic_set_entry_rel( Elf_Xword index,
Elf64_Addr offset,
@ -392,6 +506,12 @@ template <class S> 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 <class T>
void generic_set_entry_rela( Elf_Xword index,
Elf64_Addr offset,
@ -419,6 +539,9 @@ template <class S> 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 <class T>
void generic_add_entry( Elf64_Addr offset, Elf_Xword info )
{
@ -435,6 +558,10 @@ template <class S> 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 <class T>
void
generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )

View File

@ -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 T> 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_interface>& compression )
@ -87,7 +173,6 @@ template <class T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> class section_impl : public section
}
}
//------------------------------------------------------------------------------
private:
mutable std::istream* pstream = nullptr;
T header = {};
Elf_Half index = 0;
std::string name;
mutable std::unique_ptr<char[]> data;
mutable Elf_Word data_size = 0;
const endianness_convertor* convertor = nullptr;
const address_translator* translator = nullptr;
const std::shared_ptr<compression_interface> 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<char[]> 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_interface> 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

View File

@ -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<Elf_Half>& 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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 T> 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<Elf_Half>& 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 T> 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 T> 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 T> 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<char[]> data;
std::vector<Elf_Half> 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<char[]> data; //!< Pointer to the segment data
std::vector<Elf_Half> 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

View File

@ -30,23 +30,31 @@ THE SOFTWARE.
namespace ELFIO {
//------------------------------------------------------------------------------
//! \class string_section_accessor_template
//! \brief Class for accessing string section data
template <class S> 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<size_t>( string_section->get_size() ) - index );
if ( string_length < ( string_section->get_size() - index ) )
return data + index;
}
@ -56,12 +64,15 @@ template <class S> 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<Elf_Word>( string_section->get_size() );
@ -78,6 +89,9 @@ template <class S> 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 S> class string_section_accessor_template
//------------------------------------------------------------------------------
private:
S* string_section;
S* string_section; //!< Pointer to the section
};
using string_section_accessor = string_section_accessor_template<section>;

View File

@ -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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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 S> 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<void( Elf_Xword first, Elf_Xword second )> func =
@ -259,6 +344,8 @@ template <class S> class symbol_section_accessor_template
//------------------------------------------------------------------------------
private:
//------------------------------------------------------------------------------
// @brief Find the hash section
//------------------------------------------------------------------------------
void find_hash_section()
{
@ -276,15 +363,31 @@ template <class S> 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 S> 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 <class T>
bool gnu_hash_lookup( const std::string& name,
@ -391,6 +504,10 @@ template <class S> 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 <class T> const T* generic_get_symbol_ptr( Elf_Xword index ) const
{
@ -408,6 +525,11 @@ template <class S> 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 <class T>
bool generic_search_symbols( std::function<bool( const T* )> match,
@ -428,6 +550,17 @@ template <class S> 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 <class T>
bool generic_get_symbol( Elf_Xword index,
@ -470,6 +603,15 @@ template <class S> 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 <class T>
Elf_Word generic_add_symbol( Elf_Word name,
@ -500,6 +642,10 @@ template <class S> 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 <class T>
Elf_Xword generic_arrange_local_symbols(
@ -550,10 +696,10 @@ template <class S> 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<section>;

View File

@ -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<address_translation>& 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<address_translation> addr_translations;
std::vector<address_translation>
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<char[]>
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<char[]>
deflate( const char* data,
const endianness_convertor* convertor,

View File

@ -1 +1,4 @@
//------------------------------------------------------------------------------
//! \def ELFIO_VERSION
//! \brief Defines the version of the ELFIO library
#define ELFIO_VERSION "3.14"

View File

@ -26,10 +26,14 @@ THE SOFTWARE.
namespace ELFIO {
//------------------------------------------------------------------------------
//! \class versym_section_accessor_template
//! \brief Class for accessing version symbol section data
template <class S> 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 S> 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 S> 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 S> 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 S> 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 S> 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<section>;
@ -94,10 +111,15 @@ using const_versym_section_accessor =
versym_section_accessor_template<const section>;
//------------------------------------------------------------------------------
//! \class versym_r_section_accessor_template
//! \brief Class for accessing version requirement section data
template <class S> 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 S> 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 S> 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<section>;
@ -175,10 +209,15 @@ using const_versym_r_section_accessor =
versym_r_section_accessor_template<const section>;
//------------------------------------------------------------------------------
//! \class versym_d_section_accessor_template
//! \brief Class for accessing version definition section data
template <class S> 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 S> 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 S> 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<section>;

View File

@ -1016,7 +1016,7 @@ class mock_wiiu_compression : public compression_interface
{
uncompressed_size = 2 * compressed_size;
return std::unique_ptr<char[]>(
new ( std::nothrow ) char[uncompressed_size + 1] );
new ( std::nothrow ) char[static_cast<size_t>(uncompressed_size) + 1] );
}
std::unique_ptr<char[]> deflate( const char* data,
@ -1026,7 +1026,7 @@ class mock_wiiu_compression : public compression_interface
{
compressed_size = decompressed_size / 2;
return std::unique_ptr<char[]>(
new ( std::nothrow ) char[compressed_size + 1] );
new ( std::nothrow ) char[static_cast<size_t>(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<size_t>(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<size_t>(seg->get_file_size()) ) );
}
} while ( is_lazy );
}