mirror of
https://github.com/serge1/ELFIO.git
synced 2025-03-14 04:19:31 +00:00
Add AI generated comments for classes and methods
This commit is contained in:
parent
4c829d48eb
commit
cba0a73823
@ -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
|
||||
};
|
||||
|
181
elfio/elfio.hpp
181
elfio/elfio.hpp
@ -59,15 +59,21 @@ THE SOFTWARE.
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! \class elfio
|
||||
//! \brief The elfio class represents an ELF file and provides methods to manipulate it.
|
||||
class elfio
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
//! \brief Default constructor
|
||||
elfio() noexcept : sections( this ), segments( this )
|
||||
{
|
||||
create( ELFCLASS32, ELFDATA2LSB );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! \brief Constructor with compression interface
|
||||
//! \param compression Pointer to the compression interface
|
||||
explicit elfio( compression_interface* compression ) noexcept
|
||||
: sections( this ), segments( this ),
|
||||
compression( std::shared_ptr<compression_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
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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>;
|
||||
|
@ -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] );
|
||||
|
@ -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>;
|
||||
|
@ -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 =
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
@ -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>;
|
||||
|
@ -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,
|
||||
|
@ -1 +1,4 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//! \def ELFIO_VERSION
|
||||
//! \brief Defines the version of the ELFIO library
|
||||
#define ELFIO_VERSION "3.14"
|
||||
|
@ -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>;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user