Reformat sources by using clang-format

It is not perfect (and, probably, it is worser than it was before), but, it is automatic
This commit is contained in:
Serge Lamikhov-Center 2020-08-21 07:56:08 -07:00
parent 46acd5c16d
commit 9c739b49a0
20 changed files with 3011 additions and 3216 deletions

View File

@ -1,27 +1,34 @@
{ BasedOnStyle : LLVM
BasedOnStyle : LLVM,
AlignConsecutiveAssignments : true, AccessModifierOffset : -2
AlignConsecutiveDeclarations : true, AlignAfterOpenBracket : true
AlignConsecutiveMacros : true, AlignConsecutiveAssignments : true
AlignEscapedNewlines : true, AlignConsecutiveDeclarations : true
AlignOperands : true, AlignConsecutiveMacros : true
AlignTrailingComments : true, AlignEscapedNewlines : true
AlignOperands : true
UseTab : Never, AlignTrailingComments : true
IndentWidth : 4, BinPackParameters : false
TabWidth : 4, BraceWrapping:
BreakBeforeBraces : Stroustrup, AfterCaseLabel : true
AllowShortIfStatementsOnASingleLine : false, AfterClass : true
IndentCaseLabels : false, AfterEnum : true
ColumnLimit : 90, AfterFunction : true
AccessModifierOffset : -4, AfterNamespace : false
NamespaceIndentation : Inner, AfterStruct : true
PointerAlignment : Left, AfterExternBlock : true
FixNamespaceComments : true, BeforeCatch : true
SortIncludes : false, BeforeElse : true
BreakBeforeBraces : Custom
ReflowComments : false, ColumnLimit : 80
SpacesInConditionalStatement : true, FixNamespaceComments : true
SpacesInParentheses : true, IndentCaseLabels : false
} IndentWidth : 4
NamespaceIndentation : Inner
PointerAlignment : Left
ReflowComments : false
SortIncludes : false
SpacesInConditionalStatement : true
SpacesInParentheses : true
TabWidth : 4
UseTab : Never

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,55 +26,50 @@ THE SOFTWARE.
namespace ELFIO { namespace ELFIO {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class S > template <class S> class dynamic_section_accessor_template
class dynamic_section_accessor_template
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) : dynamic_section_accessor_template( const elfio& elf_file_, S* section_ )
elf_file( elf_file_ ), : elf_file( elf_file_ ), dynamic_section( section_ )
dynamic_section( section_ )
{ {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Xword Elf_Xword get_entries_num() const
get_entries_num() const
{ {
Elf_Xword nRet = 0; Elf_Xword nRet = 0;
if ( 0 != dynamic_section->get_entry_size() ) { if ( 0 != dynamic_section->get_entry_size() ) {
nRet = dynamic_section->get_size() / dynamic_section->get_entry_size(); nRet =
dynamic_section->get_size() / dynamic_section->get_entry_size();
} }
return nRet; return nRet;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_entry( Elf_Xword index,
get_entry( Elf_Xword index, Elf_Xword& tag,
Elf_Xword& tag, Elf_Xword& value,
Elf_Xword& value, std::string& str ) const
std::string& str ) const
{ {
if ( index >= get_entries_num() ) { // Is index valid if ( index >= get_entries_num() ) { // Is index valid
return false; return false;
} }
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
generic_get_entry_dyn< Elf32_Dyn >( index, tag, value ); generic_get_entry_dyn<Elf32_Dyn>( index, tag, value );
} }
else { else {
generic_get_entry_dyn< Elf64_Dyn >( index, tag, value ); generic_get_entry_dyn<Elf64_Dyn>( index, tag, value );
} }
// If the tag may have a string table reference, prepare the string // If the tag may have a string table reference, prepare the string
if ( tag == DT_NEEDED || if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH ||
tag == DT_SONAME ||
tag == DT_RPATH ||
tag == DT_RUNPATH ) { tag == DT_RUNPATH ) {
string_section_accessor strsec = string_section_accessor strsec =
elf_file.sections[ get_string_table_index() ]; elf_file.sections[get_string_table_index()];
const char* result = strsec.get_string( value ); const char* result = strsec.get_string( value );
if ( 0 == result ) { if ( 0 == result ) {
str.clear(); str.clear();
@ -89,59 +84,54 @@ class dynamic_section_accessor_template
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( Elf_Xword tag, Elf_Xword value )
add_entry( Elf_Xword tag,
Elf_Xword value )
{ {
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
generic_add_entry< Elf32_Dyn >( tag, value ); generic_add_entry<Elf32_Dyn>( tag, value );
} }
else { else {
generic_add_entry< Elf64_Dyn >( tag, value ); generic_add_entry<Elf64_Dyn>( tag, value );
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( Elf_Xword tag, const std::string& str )
add_entry( Elf_Xword tag,
const std::string& str )
{ {
string_section_accessor strsec = string_section_accessor strsec =
elf_file.sections[ get_string_table_index() ]; elf_file.sections[get_string_table_index()];
Elf_Xword value = strsec.add_string( str ); Elf_Xword value = strsec.add_string( str );
add_entry( tag, value ); add_entry( tag, value );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_string_table_index() const
get_string_table_index() const
{ {
return (Elf_Half)dynamic_section->get_link(); return (Elf_Half)dynamic_section->get_link();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
void void generic_get_entry_dyn( Elf_Xword index,
generic_get_entry_dyn( Elf_Xword index, Elf_Xword& tag,
Elf_Xword& tag, Elf_Xword& value ) const
Elf_Xword& value ) const
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
// Check unusual case when dynamic section has no data // Check unusual case when dynamic section has no data
if( dynamic_section->get_data() == 0 || if ( dynamic_section->get_data() == 0 ||
( index + 1 ) * dynamic_section->get_entry_size() > dynamic_section->get_size() ) { ( index + 1 ) * dynamic_section->get_entry_size() >
dynamic_section->get_size() ) {
tag = DT_NULL; tag = DT_NULL;
value = 0; value = 0;
return; return;
} }
const T* pEntry = reinterpret_cast<const T*>( const T* pEntry = reinterpret_cast<const T*>(
dynamic_section->get_data() + dynamic_section->get_data() +
index * dynamic_section->get_entry_size() ); index * dynamic_section->get_entry_size() );
tag = convertor( pEntry->d_tag ); tag = convertor( pEntry->d_tag );
switch ( tag ) { switch ( tag ) {
case DT_NULL: case DT_NULL:
@ -187,10 +177,8 @@ class dynamic_section_accessor_template
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T> void generic_add_entry( Elf_Xword tag, Elf_Xword value )
void
generic_add_entry( Elf_Xword tag, Elf_Xword value )
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
@ -240,17 +228,19 @@ class dynamic_section_accessor_template
entry.d_tag = convertor( tag ); entry.d_tag = convertor( tag );
dynamic_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) ); dynamic_section->append_data( reinterpret_cast<char*>( &entry ),
sizeof( entry ) );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
const elfio& elf_file; const elfio& elf_file;
S* dynamic_section; S* dynamic_section;
}; };
using dynamic_section_accessor = dynamic_section_accessor_template<section>; using dynamic_section_accessor = dynamic_section_accessor_template<section>;
using const_dynamic_section_accessor = dynamic_section_accessor_template<const section>; using const_dynamic_section_accessor =
dynamic_section_accessor_template<const section>;
} // namespace ELFIO } // namespace ELFIO

View File

@ -30,55 +30,56 @@ namespace ELFIO {
class elf_header class elf_header
{ {
public: public:
virtual ~elf_header() {}; virtual ~elf_header(){};
virtual bool load( std::istream& stream ) = 0; virtual bool load( std::istream& stream ) = 0;
virtual bool save( std::ostream& stream ) const = 0; virtual bool save( std::ostream& stream ) const = 0;
// ELF header functions // ELF header functions
ELFIO_GET_ACCESS_DECL( unsigned char, class ); ELFIO_GET_ACCESS_DECL( unsigned char, class );
ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); ELFIO_GET_ACCESS_DECL( unsigned char, elf_version );
ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); ELFIO_GET_ACCESS_DECL( unsigned char, encoding );
ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); ELFIO_GET_ACCESS_DECL( Elf_Half, header_size );
ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size );
ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size );
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version );
ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi );
ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version );
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type );
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine );
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry );
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset );
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset );
ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index );
}; };
template <class T> struct elf_header_impl_types;
template< class T > struct elf_header_impl_types; template <> struct elf_header_impl_types<Elf32_Ehdr>
template<> struct elf_header_impl_types<Elf32_Ehdr> { {
typedef Elf32_Phdr Phdr_type; typedef Elf32_Phdr Phdr_type;
typedef Elf32_Shdr Shdr_type; typedef Elf32_Shdr Shdr_type;
static const unsigned char file_class = ELFCLASS32; static const unsigned char file_class = ELFCLASS32;
}; };
template<> struct elf_header_impl_types<Elf64_Ehdr> { template <> struct elf_header_impl_types<Elf64_Ehdr>
typedef Elf64_Phdr Phdr_type; {
typedef Elf64_Shdr Shdr_type; typedef Elf64_Phdr Phdr_type;
typedef Elf64_Shdr Shdr_type;
static const unsigned char file_class = ELFCLASS64; static const unsigned char file_class = ELFCLASS64;
}; };
template< class T > class elf_header_impl : public elf_header template <class T> class elf_header_impl : public elf_header
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
elf_header_impl( endianess_convertor* convertor_, elf_header_impl( endianess_convertor* convertor_, unsigned char encoding )
unsigned char encoding )
{ {
convertor = convertor_; convertor = convertor_;
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' ); std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ),
'\0' );
header.e_ident[EI_MAG0] = ELFMAG0; header.e_ident[EI_MAG0] = ELFMAG0;
header.e_ident[EI_MAG1] = ELFMAG1; header.e_ident[EI_MAG1] = ELFMAG1;
@ -87,60 +88,63 @@ template< class T > class elf_header_impl : public elf_header
header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class; header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class;
header.e_ident[EI_DATA] = encoding; header.e_ident[EI_DATA] = encoding;
header.e_ident[EI_VERSION] = EV_CURRENT; header.e_ident[EI_VERSION] = EV_CURRENT;
header.e_version = (*convertor)( (Elf_Word)EV_CURRENT ); header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT );
header.e_ehsize = ( sizeof( header ) ); header.e_ehsize = ( sizeof( header ) );
header.e_ehsize = (*convertor)( header.e_ehsize ); header.e_ehsize = ( *convertor )( header.e_ehsize );
header.e_shstrndx = (*convertor)( (Elf_Half)1 ); header.e_shstrndx = ( *convertor )( (Elf_Half)1 );
header.e_phentsize = sizeof( typename elf_header_impl_types<T>::Phdr_type ); header.e_phentsize =
header.e_shentsize = sizeof( typename elf_header_impl_types<T>::Shdr_type ); sizeof( typename elf_header_impl_types<T>::Phdr_type );
header.e_phentsize = (*convertor)( header.e_phentsize ); header.e_shentsize =
header.e_shentsize = (*convertor)( header.e_shentsize ); sizeof( typename elf_header_impl_types<T>::Shdr_type );
header.e_phentsize = ( *convertor )( header.e_phentsize );
header.e_shentsize = ( *convertor )( header.e_shentsize );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool load( std::istream& stream )
load( std::istream& stream )
{ {
stream.seekg( 0 ); stream.seekg( 0 );
stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
return (stream.gcount() == sizeof( header ) ); return ( stream.gcount() == sizeof( header ) );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool save( std::ostream& stream ) const
save( std::ostream& stream ) const
{ {
stream.seekp( 0 ); stream.seekp( 0 );
stream.write( reinterpret_cast<const char*>( &header ), sizeof( header ) ); stream.write( reinterpret_cast<const char*>( &header ),
sizeof( header ) );
return stream.good(); return stream.good();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// ELF header functions // ELF header functions
ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] );
ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] );
ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] );
ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize );
ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize );
ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize );
ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version); ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version );
ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] );
ELFIO_GET_SET_ACCESS( unsigned char, abi_version, header.e_ident[EI_ABIVERSION] ); ELFIO_GET_SET_ACCESS( unsigned char,
ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); abi_version,
ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); header.e_ident[EI_ABIVERSION] );
ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type );
ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine );
ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags );
ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx );
ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry );
ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum );
ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff );
ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum );
ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff );
private: private:
T header; T header;
endianess_convertor* convertor; endianess_convertor* convertor;
}; };

View File

@ -38,63 +38,62 @@ namespace ELFIO {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class S > template <class S> class note_section_accessor_template
class note_section_accessor_template
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
note_section_accessor_template( const elfio& elf_file_, S* section_ ) : note_section_accessor_template( const elfio& elf_file_, S* section_ )
elf_file( elf_file_ ), note_section( section_ ) : elf_file( elf_file_ ), note_section( section_ )
{ {
process_section(); process_section();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Word Elf_Word get_notes_num() const
get_notes_num() const
{ {
return (Elf_Word)note_start_positions.size(); return (Elf_Word)note_start_positions.size();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_note( Elf_Word index,
get_note( Elf_Word index, Elf_Word& type,
Elf_Word& type, std::string& name,
std::string& name, void*& desc,
void*& desc, Elf_Word& descSize ) const
Elf_Word& descSize ) const
{ {
if ( index >= note_section->get_size() ) { if ( index >= note_section->get_size() ) {
return false; return false;
} }
const char* pData = note_section->get_data() + note_start_positions[index]; const char* pData =
note_section->get_data() + note_start_positions[index];
int align = sizeof( Elf_Word ); int align = sizeof( Elf_Word );
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
type = convertor( *(const Elf_Word*)( pData + 2*align ) ); type = convertor( *(const Elf_Word*)( pData + 2 * align ) );
Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) ); Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) );
descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) ); descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) );
Elf_Xword max_name_size = note_section->get_size() - note_start_positions[index]; Elf_Xword max_name_size =
if ( namesz < 1 || note_section->get_size() - note_start_positions[index];
namesz > max_name_size || if ( namesz < 1 || namesz > max_name_size ||
(Elf_Xword)namesz + descSize > max_name_size ) { (Elf_Xword)namesz + descSize > max_name_size ) {
return false; return false;
} }
name.assign( pData + 3*align, namesz - 1); name.assign( pData + 3 * align, namesz - 1 );
if ( 0 == descSize ) { if ( 0 == descSize ) {
desc = 0; desc = 0;
} }
else { else {
desc = const_cast<char*> ( pData + 3*align + desc =
( ( namesz + align - 1 )/align )*align ); const_cast<char*>( pData + 3 * align +
( ( namesz + align - 1 ) / align ) * align );
} }
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void add_note( Elf_Word type, void add_note( Elf_Word type,
const std::string& name, const std::string& name,
const void* desc, const void* desc,
@ -102,11 +101,12 @@ class note_section_accessor_template
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
int align = sizeof( Elf_Word ); int align = sizeof( Elf_Word );
Elf_Word nameLen = (Elf_Word)name.size() + 1; Elf_Word nameLen = (Elf_Word)name.size() + 1;
Elf_Word nameLenConv = convertor( nameLen ); Elf_Word nameLenConv = convertor( nameLen );
std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align ); std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align );
Elf_Word descSizeConv = convertor( descSize ); Elf_Word descSizeConv = convertor( descSize );
buffer.append( reinterpret_cast<char*>( &descSizeConv ), align ); buffer.append( reinterpret_cast<char*>( &descSizeConv ), align );
type = convertor( type ); type = convertor( type );
buffer.append( reinterpret_cast<char*>( &type ), align ); buffer.append( reinterpret_cast<char*>( &type ), align );
@ -128,13 +128,13 @@ class note_section_accessor_template
} }
private: private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void process_section() void process_section()
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
const char* data = note_section->get_data(); const char* data = note_section->get_data();
Elf_Xword size = note_section->get_size(); Elf_Xword size = note_section->get_size();
Elf_Xword current = 0; Elf_Xword current = 0;
note_start_positions.clear(); note_start_positions.clear();
@ -144,28 +144,28 @@ class note_section_accessor_template
} }
Elf_Word align = sizeof( Elf_Word ); Elf_Word align = sizeof( Elf_Word );
while ( current + (Elf_Xword)3*align <= size ) { while ( current + (Elf_Xword)3 * align <= size ) {
note_start_positions.push_back( current ); note_start_positions.push_back( current );
Elf_Word namesz = convertor( Elf_Word namesz = convertor( *(const Elf_Word*)( data + current ) );
*(const Elf_Word*)( data + current ) );
Elf_Word descsz = convertor( Elf_Word descsz = convertor(
*(const Elf_Word*)( data + current + sizeof( namesz ) ) ); *(const Elf_Word*)( data + current + sizeof( namesz ) ) );
current += (Elf_Xword)3*sizeof( Elf_Word ) + current += (Elf_Xword)3 * sizeof( Elf_Word ) +
( ( namesz + align - 1 ) / align ) * (Elf_Xword)align + ( ( namesz + align - 1 ) / align ) * (Elf_Xword)align +
( ( descsz + align - 1 ) / align ) * (Elf_Xword)align; ( ( descsz + align - 1 ) / align ) * (Elf_Xword)align;
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
const elfio& elf_file; const elfio& elf_file;
S* note_section; S* note_section;
std::vector<Elf_Xword> note_start_positions; std::vector<Elf_Xword> note_start_positions;
}; };
using note_section_accessor = note_section_accessor_template<section>; using note_section_accessor = note_section_accessor_template<section>;
using const_note_section_accessor = note_section_accessor_template<const section>; using const_note_section_accessor =
note_section_accessor_template<const section>;
} // namespace ELFIO } // namespace ELFIO

View File

@ -25,8 +25,8 @@ THE SOFTWARE.
namespace ELFIO { namespace ELFIO {
template<typename T> struct get_sym_and_type; template <typename T> struct get_sym_and_type;
template<> struct get_sym_and_type< Elf32_Rel > template <> struct get_sym_and_type<Elf32_Rel>
{ {
static int get_r_sym( Elf_Xword info ) static int get_r_sym( Elf_Xword info )
{ {
@ -37,7 +37,7 @@ template<> struct get_sym_and_type< Elf32_Rel >
return ELF32_R_TYPE( (Elf_Word)info ); return ELF32_R_TYPE( (Elf_Word)info );
} }
}; };
template<> struct get_sym_and_type< Elf32_Rela > template <> struct get_sym_and_type<Elf32_Rela>
{ {
static int get_r_sym( Elf_Xword info ) static int get_r_sym( Elf_Xword info )
{ {
@ -48,104 +48,87 @@ template<> struct get_sym_and_type< Elf32_Rela >
return ELF32_R_TYPE( (Elf_Word)info ); return ELF32_R_TYPE( (Elf_Word)info );
} }
}; };
template<> struct get_sym_and_type< Elf64_Rel > template <> struct get_sym_and_type<Elf64_Rel>
{ {
static int get_r_sym( Elf_Xword info ) static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); }
{ static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); }
return ELF64_R_SYM( info );
}
static int get_r_type( Elf_Xword info )
{
return ELF64_R_TYPE( info );
}
}; };
template<> struct get_sym_and_type< Elf64_Rela > template <> struct get_sym_and_type<Elf64_Rela>
{ {
static int get_r_sym( Elf_Xword info ) static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); }
{ static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); }
return ELF64_R_SYM( info );
}
static int get_r_type( Elf_Xword info )
{
return ELF64_R_TYPE( info );
}
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class S > template <class S> class relocation_section_accessor_template
class relocation_section_accessor_template
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) : relocation_section_accessor_template( const elfio& elf_file_, S* section_ )
elf_file( elf_file_ ), : elf_file( elf_file_ ), relocation_section( section_ )
relocation_section( section_ )
{ {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Xword Elf_Xword get_entries_num() const
get_entries_num() const
{ {
Elf_Xword nRet = 0; Elf_Xword nRet = 0;
if ( 0 != relocation_section->get_entry_size() ) { if ( 0 != relocation_section->get_entry_size() ) {
nRet = relocation_section->get_size() / relocation_section->get_entry_size(); nRet = relocation_section->get_size() /
relocation_section->get_entry_size();
} }
return nRet; return nRet;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_entry( Elf_Xword index,
get_entry( Elf_Xword index, Elf64_Addr& offset,
Elf64_Addr& offset, Elf_Word& symbol,
Elf_Word& symbol, Elf_Word& type,
Elf_Word& type, Elf_Sxword& addend ) const
Elf_Sxword& addend ) const
{ {
if ( index >= get_entries_num() ) { // Is index valid if ( index >= get_entries_num() ) { // Is index valid
return false; return false;
} }
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
if ( SHT_REL == relocation_section->get_type() ) { if ( SHT_REL == relocation_section->get_type() ) {
generic_get_entry_rel< Elf32_Rel >( index, offset, symbol, generic_get_entry_rel<Elf32_Rel>( index, offset, symbol, type,
type, addend ); addend );
} }
else if ( SHT_RELA == relocation_section->get_type() ) { else if ( SHT_RELA == relocation_section->get_type() ) {
generic_get_entry_rela< Elf32_Rela >( index, offset, symbol, generic_get_entry_rela<Elf32_Rela>( index, offset, symbol, type,
type, addend ); addend );
} }
} }
else { else {
if ( SHT_REL == relocation_section->get_type() ) { if ( SHT_REL == relocation_section->get_type() ) {
generic_get_entry_rel< Elf64_Rel >( index, offset, symbol, generic_get_entry_rel<Elf64_Rel>( index, offset, symbol, type,
type, addend ); addend );
} }
else if ( SHT_RELA == relocation_section->get_type() ) { else if ( SHT_RELA == relocation_section->get_type() ) {
generic_get_entry_rela< Elf64_Rela >( index, offset, symbol, generic_get_entry_rela<Elf64_Rela>( index, offset, symbol, type,
type, addend ); addend );
} }
} }
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_entry( Elf_Xword index,
get_entry( Elf_Xword index, Elf64_Addr& offset,
Elf64_Addr& offset, Elf64_Addr& symbolValue,
Elf64_Addr& symbolValue, std::string& symbolName,
std::string& symbolName, Elf_Word& type,
Elf_Word& type, Elf_Sxword& addend,
Elf_Sxword& addend, Elf_Sxword& calcValue ) const
Elf_Sxword& calcValue ) const
{ {
// Do regular job // Do regular job
Elf_Word symbol; Elf_Word symbol;
bool ret = get_entry( index, offset, symbol, type, addend ); bool ret = get_entry( index, offset, symbol, type, addend );
// Find the symbol // Find the symbol
Elf_Xword size; Elf_Xword size;
@ -154,44 +137,45 @@ class relocation_section_accessor_template
Elf_Half section; Elf_Half section;
unsigned char other; unsigned char other;
symbol_section_accessor symbols( elf_file, elf_file.sections[get_symbol_table_index()] ); symbol_section_accessor symbols(
ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, elf_file, elf_file.sections[get_symbol_table_index()] );
size, bind, symbolType, section, other ); ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, size,
bind, symbolType, section, other );
if ( ret ) { // Was it successful? if ( ret ) { // Was it successful?
switch ( type ) { switch ( type ) {
case R_386_NONE: // none case R_386_NONE: // none
calcValue = 0; calcValue = 0;
break; break;
case R_386_32: // S + A case R_386_32: // S + A
calcValue = symbolValue + addend; calcValue = symbolValue + addend;
break; break;
case R_386_PC32: // S + A - P case R_386_PC32: // S + A - P
calcValue = symbolValue + addend - offset; calcValue = symbolValue + addend - offset;
break; break;
case R_386_GOT32: // G + A - P case R_386_GOT32: // G + A - P
calcValue = 0; calcValue = 0;
break; break;
case R_386_PLT32: // L + A - P case R_386_PLT32: // L + A - P
calcValue = 0; calcValue = 0;
break; break;
case R_386_COPY: // none case R_386_COPY: // none
calcValue = 0; calcValue = 0;
break; break;
case R_386_GLOB_DAT: // S case R_386_GLOB_DAT: // S
case R_386_JMP_SLOT: // S case R_386_JMP_SLOT: // S
calcValue = symbolValue; calcValue = symbolValue;
break; break;
case R_386_RELATIVE: // B + A case R_386_RELATIVE: // B + A
calcValue = addend; calcValue = addend;
break; break;
case R_386_GOTOFF: // S + A - GOT case R_386_GOTOFF: // S + A - GOT
calcValue = 0; calcValue = 0;
break; break;
case R_386_GOTPC: // GOT + A - P case R_386_GOTPC: // GOT + A - P
calcValue = 0; calcValue = 0;
break; break;
default: // Not recognized symbol! default: // Not recognized symbol!
calcValue = 0; calcValue = 0;
break; break;
} }
@ -201,80 +185,81 @@ class relocation_section_accessor_template
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool set_entry( Elf_Xword index,
set_entry(Elf_Xword index, Elf64_Addr offset,
Elf64_Addr offset, Elf_Word symbol,
Elf_Word symbol, Elf_Word type,
Elf_Word type, Elf_Sxword addend )
Elf_Sxword addend)
{ {
if (index >= get_entries_num()) { // Is index valid if ( index >= get_entries_num() ) { // Is index valid
return false; return false;
} }
if (elf_file.get_class() == ELFCLASS32) { if ( elf_file.get_class() == ELFCLASS32 ) {
if (SHT_REL == relocation_section->get_type()) { if ( SHT_REL == relocation_section->get_type() ) {
generic_set_entry_rel<Elf32_Rel>(index, offset, symbol, type, addend); generic_set_entry_rel<Elf32_Rel>( index, offset, symbol, type,
addend );
} }
else if (SHT_RELA == relocation_section->get_type()) { else if ( SHT_RELA == relocation_section->get_type() ) {
generic_set_entry_rela<Elf32_Rela>(index, offset, symbol, type, addend); generic_set_entry_rela<Elf32_Rela>( index, offset, symbol, type,
addend );
} }
} }
else { else {
if (SHT_REL == relocation_section->get_type()) { if ( SHT_REL == relocation_section->get_type() ) {
generic_set_entry_rel<Elf64_Rel>(index, offset, symbol, type, addend); generic_set_entry_rel<Elf64_Rel>( index, offset, symbol, type,
addend );
} }
else if (SHT_RELA == relocation_section->get_type()) { else if ( SHT_RELA == relocation_section->get_type() ) {
generic_set_entry_rela<Elf64_Rela>(index, offset, symbol, type, addend); generic_set_entry_rela<Elf64_Rela>( index, offset, symbol, type,
addend );
} }
} }
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( Elf64_Addr offset, Elf_Xword info )
add_entry( Elf64_Addr offset, Elf_Xword info )
{ {
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
generic_add_entry< Elf32_Rel >( offset, info ); generic_add_entry<Elf32_Rel>( offset, info );
} }
else { else {
generic_add_entry< Elf64_Rel >( offset, info ); generic_add_entry<Elf64_Rel>( offset, info );
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type )
add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type )
{ {
Elf_Xword info; Elf_Xword info;
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
info = ELF32_R_INFO( (Elf_Xword)symbol, type ); info = ELF32_R_INFO( (Elf_Xword)symbol, type );
} }
else { else {
info = ELF64_R_INFO((Elf_Xword)symbol, type ); info = ELF64_R_INFO( (Elf_Xword)symbol, type );
} }
add_entry( offset, info ); add_entry( offset, info );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
{ {
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
generic_add_entry< Elf32_Rela >( offset, info, addend ); generic_add_entry<Elf32_Rela>( offset, info, addend );
} }
else { else {
generic_add_entry< Elf64_Rela >( offset, info, addend ); generic_add_entry<Elf64_Rela>( offset, info, addend );
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( Elf64_Addr offset,
add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type, Elf_Word symbol,
Elf_Sxword addend ) unsigned char type,
Elf_Sxword addend )
{ {
Elf_Xword info; Elf_Xword info;
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
@ -287,70 +272,63 @@ class relocation_section_accessor_template
add_entry( offset, info, addend ); add_entry( offset, info, addend );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void add_entry( string_section_accessor str_writer,
add_entry( string_section_accessor str_writer, const char* str,
const char* str, symbol_section_accessor sym_writer,
symbol_section_accessor sym_writer, Elf64_Addr value,
Elf64_Addr value, Elf_Word size,
Elf_Word size, unsigned char sym_info,
unsigned char sym_info, unsigned char other,
unsigned char other, Elf_Half shndx,
Elf_Half shndx, Elf64_Addr offset,
Elf64_Addr offset, unsigned char type )
unsigned char type )
{ {
Elf_Word str_index = str_writer.add_string( str ); Elf_Word str_index = str_writer.add_string( str );
Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size, Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size,
sym_info, other, shndx ); sym_info, other, shndx );
add_entry( offset, sym_index, type ); add_entry( offset, sym_index, type );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void swap_symbols( Elf_Xword first, Elf_Xword second )
swap_symbols(Elf_Xword first, Elf_Xword second)
{ {
Elf64_Addr offset; Elf64_Addr offset;
Elf_Word symbol; Elf_Word symbol;
Elf_Word rtype; Elf_Word rtype;
Elf_Sxword addend; Elf_Sxword addend;
for (Elf_Word i = 0; i < get_entries_num(); i++) for ( Elf_Word i = 0; i < get_entries_num(); i++ ) {
{ get_entry( i, offset, symbol, rtype, addend );
get_entry(i, offset, symbol, rtype, addend); if ( symbol == first ) {
if (symbol == first) set_entry( i, offset, (Elf_Word)second, rtype, addend );
{
set_entry(i, offset, (Elf_Word)second, rtype, addend);
} }
if (symbol == second) if ( symbol == second ) {
{ set_entry( i, offset, (Elf_Word)first, rtype, addend );
set_entry(i, offset, (Elf_Word)first, rtype, addend);
} }
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_symbol_table_index() const
get_symbol_table_index() const
{ {
return (Elf_Half)relocation_section->get_link(); return (Elf_Half)relocation_section->get_link();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
void void generic_get_entry_rel( Elf_Xword index,
generic_get_entry_rel( Elf_Xword index, Elf64_Addr& offset,
Elf64_Addr& offset, Elf_Word& symbol,
Elf_Word& symbol, Elf_Word& type,
Elf_Word& type, Elf_Sxword& addend ) const
Elf_Sxword& addend ) const
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
const T* pEntry = reinterpret_cast<const T*>( const T* pEntry = reinterpret_cast<const T*>(
relocation_section->get_data() + relocation_section->get_data() +
index * relocation_section->get_entry_size() ); index * relocation_section->get_entry_size() );
offset = convertor( pEntry->r_offset ); offset = convertor( pEntry->r_offset );
Elf_Xword tmp = convertor( pEntry->r_info ); Elf_Xword tmp = convertor( pEntry->r_info );
symbol = get_sym_and_type<T>::get_r_sym( tmp ); symbol = get_sym_and_type<T>::get_r_sym( tmp );
@ -358,20 +336,19 @@ class relocation_section_accessor_template
addend = 0; addend = 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
void void generic_get_entry_rela( Elf_Xword index,
generic_get_entry_rela( Elf_Xword index, Elf64_Addr& offset,
Elf64_Addr& offset, Elf_Word& symbol,
Elf_Word& symbol, Elf_Word& type,
Elf_Word& type, Elf_Sxword& addend ) const
Elf_Sxword& addend ) const
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
const T* pEntry = reinterpret_cast<const T*>( const T* pEntry = reinterpret_cast<const T*>(
relocation_section->get_data() + relocation_section->get_data() +
index * relocation_section->get_entry_size() ); index * relocation_section->get_entry_size() );
offset = convertor( pEntry->r_offset ); offset = convertor( pEntry->r_offset );
Elf_Xword tmp = convertor( pEntry->r_info ); Elf_Xword tmp = convertor( pEntry->r_info );
symbol = get_sym_and_type<T>::get_r_sym( tmp ); symbol = get_sym_and_type<T>::get_r_sym( tmp );
@ -381,60 +358,59 @@ class relocation_section_accessor_template
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template <class T> template <class T>
void void generic_set_entry_rel( Elf_Xword index,
generic_set_entry_rel(Elf_Xword index, Elf64_Addr offset,
Elf64_Addr offset, Elf_Word symbol,
Elf_Word symbol, Elf_Word type,
Elf_Word type, Elf_Sxword )
Elf_Sxword)
{ {
const endianess_convertor &convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
T *pEntry = const_cast<T *>(reinterpret_cast<const T *>(relocation_section->get_data() + T* pEntry = const_cast<T*>( reinterpret_cast<const T*>(
index * relocation_section->get_entry_size())); relocation_section->get_data() +
index * relocation_section->get_entry_size() ) );
if (elf_file.get_class() == ELFCLASS32) { if ( elf_file.get_class() == ELFCLASS32 ) {
pEntry->r_info = ELF32_R_INFO((Elf_Xword)symbol, type); pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type );
} }
else { else {
pEntry->r_info = ELF64_R_INFO((Elf_Xword)symbol, type); pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type );
} }
pEntry->r_offset = offset; pEntry->r_offset = offset;
pEntry->r_offset = convertor(pEntry->r_offset); pEntry->r_offset = convertor( pEntry->r_offset );
pEntry->r_info = convertor(pEntry->r_info); pEntry->r_info = convertor( pEntry->r_info );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template <class T> template <class T>
void void generic_set_entry_rela( Elf_Xword index,
generic_set_entry_rela(Elf_Xword index, Elf64_Addr offset,
Elf64_Addr offset, Elf_Word symbol,
Elf_Word symbol, Elf_Word type,
Elf_Word type, Elf_Sxword addend )
Elf_Sxword addend)
{ {
const endianess_convertor &convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
T *pEntry = const_cast<T *>(reinterpret_cast<const T *>(relocation_section->get_data() + T* pEntry = const_cast<T*>( reinterpret_cast<const T*>(
index * relocation_section->get_entry_size())); relocation_section->get_data() +
index * relocation_section->get_entry_size() ) );
if (elf_file.get_class() == ELFCLASS32) { if ( elf_file.get_class() == ELFCLASS32 ) {
pEntry->r_info = ELF32_R_INFO((Elf_Xword)symbol, type); pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type );
} }
else { else {
pEntry->r_info = ELF64_R_INFO((Elf_Xword)symbol, type); pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type );
} }
pEntry->r_offset = offset; pEntry->r_offset = offset;
pEntry->r_addend = addend; pEntry->r_addend = addend;
pEntry->r_offset = convertor(pEntry->r_offset); pEntry->r_offset = convertor( pEntry->r_offset );
pEntry->r_info = convertor(pEntry->r_info); pEntry->r_info = convertor( pEntry->r_info );
pEntry->r_addend = convertor(pEntry->r_addend); pEntry->r_addend = convertor( pEntry->r_addend );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
void void generic_add_entry( Elf64_Addr offset, Elf_Xword info )
generic_add_entry( Elf64_Addr offset, Elf_Xword info )
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
@ -444,11 +420,12 @@ class relocation_section_accessor_template
entry.r_offset = convertor( entry.r_offset ); entry.r_offset = convertor( entry.r_offset );
entry.r_info = convertor( entry.r_info ); entry.r_info = convertor( entry.r_info );
relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) ); relocation_section->append_data( reinterpret_cast<char*>( &entry ),
sizeof( entry ) );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
void void
generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
{ {
@ -462,17 +439,20 @@ class relocation_section_accessor_template
entry.r_info = convertor( entry.r_info ); entry.r_info = convertor( entry.r_info );
entry.r_addend = convertor( entry.r_addend ); entry.r_addend = convertor( entry.r_addend );
relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) ); relocation_section->append_data( reinterpret_cast<char*>( &entry ),
sizeof( entry ) );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
const elfio& elf_file; const elfio& elf_file;
S* relocation_section; S* relocation_section;
}; };
using relocation_section_accessor = relocation_section_accessor_template<section>; using relocation_section_accessor =
using const_relocation_section_accessor = relocation_section_accessor_template<const section>; relocation_section_accessor_template<section>;
using const_relocation_section_accessor =
relocation_section_accessor_template<const section>;
} // namespace ELFIO } // namespace ELFIO

View File

@ -31,21 +31,22 @@ namespace ELFIO {
class section class section
{ {
friend class elfio; friend class elfio;
public:
virtual ~section() {};
ELFIO_GET_ACCESS_DECL ( Elf_Half, index ); public:
ELFIO_GET_SET_ACCESS_DECL( std::string, name ); virtual ~section(){};
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags ); ELFIO_GET_ACCESS_DECL( Elf_Half, index );
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info ); ELFIO_GET_SET_ACCESS_DECL( std::string, name );
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align );
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size );
ELFIO_GET_ACCESS_DECL ( Elf64_Off, offset ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size );
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 const char* get_data() const = 0;
virtual void set_data( const char* pData, Elf_Word size ) = 0; virtual void set_data( const char* pData, Elf_Word size ) = 0;
@ -55,27 +56,26 @@ class section
virtual size_t get_stream_size() const = 0; virtual size_t get_stream_size() const = 0;
virtual void set_stream_size( size_t value ) = 0; virtual void set_stream_size( size_t value ) = 0;
protected: protected:
ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
ELFIO_SET_ACCESS_DECL( Elf_Half, index ); ELFIO_SET_ACCESS_DECL( Elf_Half, index );
virtual void load( std::istream& stream, virtual void load( std::istream& stream, std::streampos header_offset ) = 0;
std::streampos header_offset ) = 0;
virtual void save( std::ostream& stream, virtual void save( std::ostream& stream,
std::streampos header_offset, std::streampos header_offset,
std::streampos data_offset ) = 0; std::streampos data_offset ) = 0;
virtual bool is_address_initialized() const = 0; virtual bool is_address_initialized() const = 0;
}; };
template <class T> class section_impl : public section
template< class T >
class section_impl : public section
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ ) section_impl( const endianess_convertor* convertor_ )
: convertor( convertor_ )
{ {
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' ); std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ),
'\0' );
is_address_set = false; is_address_set = false;
data = 0; data = 0;
data_size = 0; data_size = 0;
@ -83,78 +83,53 @@ class section_impl : public section
stream_size = 0; stream_size = 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
~section_impl() ~section_impl() { delete[] data; }
{
delete [] data;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Section info functions // Section info functions
ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type );
ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags );
ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size );
ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link );
ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info );
ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign );
ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); 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_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name );
ELFIO_GET_ACCESS ( Elf64_Addr, address, header.sh_addr ); ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr );
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_index() const { return index; }
get_index() const
{
return index;
}
//------------------------------------------------------------------------------
std::string get_name() const { return name; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::string void set_name( std::string name_ ) { name = name_; }
get_name() const
{
return name;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_address( Elf64_Addr value )
set_name( std::string name_ )
{
name = name_;
}
//------------------------------------------------------------------------------
void
set_address( Elf64_Addr value )
{ {
header.sh_addr = value; header.sh_addr = value;
header.sh_addr = (*convertor)( header.sh_addr ); header.sh_addr = ( *convertor )( header.sh_addr );
is_address_set = true; is_address_set = true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool is_address_initialized() const { return is_address_set; }
is_address_initialized() const
{
return is_address_set;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const char* const char* get_data() const { return data; }
get_data() const
{
return data;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_data( const char* raw_data, Elf_Word size )
set_data( const char* raw_data, Elf_Word size )
{ {
if ( get_type() != SHT_NOBITS ) { if ( get_type() != SHT_NOBITS ) {
delete [] data; delete[] data;
try { try {
data = new char[size]; data = new char[size];
} catch (const std::bad_alloc&) { }
catch ( const std::bad_alloc& ) {
data = 0; data = 0;
data_size = 0; data_size = 0;
size = 0; size = 0;
@ -168,34 +143,34 @@ class section_impl : public section
set_size( size ); set_size( size );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_data( const std::string& str_data )
set_data( const std::string& str_data )
{ {
return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); return set_data( str_data.c_str(), (Elf_Word)str_data.size() );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void append_data( const char* raw_data, Elf_Word size )
append_data( const char* raw_data, Elf_Word size )
{ {
if ( get_type() != SHT_NOBITS ) { if ( get_type() != SHT_NOBITS ) {
if ( get_size() + size < data_size ) { if ( get_size() + size < data_size ) {
std::copy( raw_data, raw_data + size, data + get_size() ); std::copy( raw_data, raw_data + size, data + get_size() );
} }
else { else {
data_size = 2*( data_size + size); data_size = 2 * ( data_size + size );
char* new_data; char* new_data;
try { try {
new_data = new char[data_size]; new_data = new char[data_size];
} catch (const std::bad_alloc&) { }
catch ( const std::bad_alloc& ) {
new_data = 0; new_data = 0;
size = 0; size = 0;
} }
if ( 0 != new_data ) { if ( 0 != new_data ) {
std::copy( data, data + get_size(), new_data ); std::copy( data, data + get_size(), new_data );
std::copy( raw_data, raw_data + size, new_data + get_size() ); std::copy( raw_data, raw_data + size,
delete [] data; new_data + get_size() );
delete[] data;
data = new_data; data = new_data;
} }
} }
@ -203,66 +178,60 @@ class section_impl : public section
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void append_data( const std::string& str_data )
append_data( const std::string& str_data )
{ {
return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); return append_data( str_data.c_str(), (Elf_Word)str_data.size() );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
protected: protected:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset );
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_index( Elf_Half value ) { index = value; }
set_index( Elf_Half value )
{
index = value;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void load( std::istream& stream, std::streampos header_offset )
load( std::istream& stream,
std::streampos header_offset )
{ {
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' ); std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ),
'\0' );
stream.seekg ( 0, stream.end ); stream.seekg( 0, stream.end );
set_stream_size ( stream.tellg() ); set_stream_size( stream.tellg() );
stream.seekg( header_offset ); stream.seekg( header_offset );
stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
Elf_Xword size = get_size(); Elf_Xword size = get_size();
if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && size < get_stream_size()) { if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() &&
size < get_stream_size() ) {
try { try {
data = new char[size + 1]; data = new char[size + 1];
} catch (const std::bad_alloc&) { }
catch ( const std::bad_alloc& ) {
data = 0; data = 0;
data_size = 0; data_size = 0;
} }
if ( ( 0 != size ) && ( 0 != data ) ) { if ( ( 0 != size ) && ( 0 != data ) ) {
stream.seekg( (*convertor)( header.sh_offset ) ); stream.seekg( ( *convertor )( header.sh_offset ) );
stream.read( data, size ); stream.read( data, size );
data[size] = 0; // Ensure data is ended with 0 to avoid oob read data[size] = 0; // Ensure data is ended with 0 to avoid oob read
data_size = size; data_size = size;
} }
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void save( std::ostream& stream,
save( std::ostream& stream, std::streampos header_offset,
std::streampos header_offset, std::streampos data_offset )
std::streampos data_offset )
{ {
if ( 0 != get_index() ) { if ( 0 != get_index() ) {
header.sh_offset = data_offset; header.sh_offset = data_offset;
header.sh_offset = (*convertor)( header.sh_offset ); header.sh_offset = ( *convertor )( header.sh_offset );
} }
save_header( stream, header_offset ); save_header( stream, header_offset );
@ -272,39 +241,30 @@ class section_impl : public section
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void save_header( std::ostream& stream, std::streampos header_offset ) const
save_header( std::ostream& stream,
std::streampos header_offset ) const
{ {
stream.seekp( header_offset ); stream.seekp( header_offset );
stream.write( reinterpret_cast<const char*>( &header ), sizeof( header ) ); stream.write( reinterpret_cast<const char*>( &header ),
sizeof( header ) );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void save_data( std::ostream& stream, std::streampos data_offset ) const
save_data( std::ostream& stream,
std::streampos data_offset ) const
{ {
stream.seekp( data_offset ); stream.seekp( data_offset );
stream.write( get_data(), get_size() ); stream.write( get_data(), get_size() );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
size_t get_stream_size() const size_t get_stream_size() const { return stream_size; }
{
return stream_size;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void set_stream_size(size_t value) void set_stream_size( size_t value ) { stream_size = value; }
{
stream_size = value;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
T header; T header;
Elf_Half index; Elf_Half index;

View File

@ -31,99 +31,80 @@ namespace ELFIO {
class segment class segment
{ {
friend class elfio; friend class elfio;
public:
virtual ~segment() {};
ELFIO_GET_ACCESS_DECL ( Elf_Half, index ); public:
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); virtual ~segment(){};
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); ELFIO_GET_ACCESS_DECL( Elf_Half, index );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address );
ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size );
ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size );
ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_GET_ACCESS_DECL( Elf64_Off, offset );
virtual const char* get_data() const = 0; virtual const char* get_data() const = 0;
virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0; virtual Elf_Half add_section_index( Elf_Half index,
virtual Elf_Half get_sections_num() const = 0; Elf_Xword addr_align ) = 0;
virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; virtual Elf_Half get_sections_num() const = 0;
virtual bool is_offset_initialized() const = 0; virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0;
virtual bool is_offset_initialized() const = 0;
protected: protected:
ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
ELFIO_SET_ACCESS_DECL( Elf_Half, index ); ELFIO_SET_ACCESS_DECL( Elf_Half, index );
virtual const std::vector<Elf_Half>& get_sections() const = 0; virtual const std::vector<Elf_Half>& get_sections() const = 0;
virtual void load( std::istream& stream, std::streampos header_offset ) = 0; virtual void load( std::istream& stream, std::streampos header_offset ) = 0;
virtual void save( std::ostream& stream, std::streampos header_offset, virtual void save( std::ostream& stream,
std::streampos data_offset ) = 0; std::streampos header_offset,
std::streampos data_offset ) = 0;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T> class segment_impl : public segment
class segment_impl : public segment
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
segment_impl( endianess_convertor* convertor_ ) : segment_impl( endianess_convertor* convertor_ )
stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ ) : stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ )
{ {
is_offset_set = false; is_offset_set = false;
std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' ); std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
virtual ~segment_impl() virtual ~segment_impl() { delete[] data; }
{
delete [] data;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Section info functions // Section info functions
ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type );
ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags );
ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align );
ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr );
ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr );
ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz );
ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz );
ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset );
size_t stream_size; size_t stream_size;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
size_t size_t get_stream_size() const { return stream_size; }
get_stream_size() const
{
return stream_size;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_stream_size( size_t value ) { stream_size = value; }
set_stream_size(size_t value)
{
stream_size = value;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_index() const { return index; }
get_index() const
{
return index;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const char* const char* get_data() const { return data; }
get_data() const
{
return data;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align )
add_section_index( Elf_Half sec_index, Elf_Xword addr_align )
{ {
sections.push_back( sec_index ); sections.push_back( sec_index );
if ( addr_align > get_align() ) { if ( addr_align > get_align() ) {
@ -133,73 +114,53 @@ class segment_impl : public segment
return (Elf_Half)sections.size(); return (Elf_Half)sections.size();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_sections_num() const { return (Elf_Half)sections.size(); }
get_sections_num() const
{
return (Elf_Half)sections.size();
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_section_index_at( Elf_Half num ) const
get_section_index_at( Elf_Half num ) const
{ {
if ( num < sections.size() ) { if ( num < sections.size() ) {
return sections[num]; return sections[num];
} }
return Elf_Half(-1); return Elf_Half( -1 );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
protected: protected:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_offset( Elf64_Off value )
set_offset( Elf64_Off value )
{ {
ph.p_offset = value; ph.p_offset = value;
ph.p_offset = (*convertor)( ph.p_offset ); ph.p_offset = ( *convertor )( ph.p_offset );
is_offset_set = true; is_offset_set = true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool is_offset_initialized() const { return is_offset_set; }
is_offset_initialized() const
{
return is_offset_set;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
const std::vector<Elf_Half>& const std::vector<Elf_Half>& get_sections() const { return sections; }
get_sections() const
{
return sections;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void set_index( Elf_Half value ) { index = value; }
set_index( Elf_Half value )
{
index = value;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void load( std::istream& stream, std::streampos header_offset )
load( std::istream& stream,
std::streampos header_offset )
{ {
stream.seekg ( 0, stream.end ); stream.seekg( 0, stream.end );
set_stream_size ( stream.tellg() ); set_stream_size( stream.tellg() );
stream.seekg( header_offset ); stream.seekg( header_offset );
stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) ); stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );
is_offset_set = true; is_offset_set = true;
if ( PT_NULL != get_type() && 0 != get_file_size() ) { if ( PT_NULL != get_type() && 0 != get_file_size() ) {
stream.seekg( (*convertor)( ph.p_offset ) ); stream.seekg( ( *convertor )( ph.p_offset ) );
Elf_Xword size = get_file_size(); Elf_Xword size = get_file_size();
if ( size > get_stream_size() ) { if ( size > get_stream_size() ) {
@ -208,7 +169,8 @@ class segment_impl : public segment
else { else {
try { try {
data = new char[size + 1]; data = new char[size + 1];
} catch (const std::bad_alloc&) { }
catch ( const std::bad_alloc& ) {
data = 0; data = 0;
} }
@ -220,18 +182,18 @@ class segment_impl : public segment
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void save( std::ostream& stream, void save( std::ostream& stream,
std::streampos header_offset, std::streampos header_offset,
std::streampos data_offset ) std::streampos data_offset )
{ {
ph.p_offset = data_offset; ph.p_offset = data_offset;
ph.p_offset = (*convertor)(ph.p_offset); ph.p_offset = ( *convertor )( ph.p_offset );
stream.seekp( header_offset ); stream.seekp( header_offset );
stream.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) ); stream.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
T ph; T ph;
Elf_Half index; Elf_Half index;

View File

@ -30,20 +30,16 @@ THE SOFTWARE.
namespace ELFIO { namespace ELFIO {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class S > template <class S> class string_section_accessor_template
class string_section_accessor_template
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
string_section_accessor_template( S* section_ ) : string_section_accessor_template( S* section_ ) : string_section( section_ )
string_section( section_ )
{ {
} }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------ const char* get_string( Elf_Word index ) const
const char*
get_string( Elf_Word index ) const
{ {
if ( string_section ) { if ( string_section ) {
if ( index < string_section->get_size() ) { if ( index < string_section->get_size() ) {
@ -57,14 +53,12 @@ class string_section_accessor_template
return 0; return 0;
} }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------ Elf_Word add_string( const char* str )
Elf_Word
add_string( const char* str )
{ {
Elf_Word current_position = 0; Elf_Word current_position = 0;
if (string_section) { if ( string_section ) {
// Strings are addeded to the end of the current section data // Strings are addeded to the end of the current section data
current_position = (Elf_Word)string_section->get_size(); current_position = (Elf_Word)string_section->get_size();
@ -73,27 +67,27 @@ class string_section_accessor_template
string_section->append_data( &empty_string, 1 ); string_section->append_data( &empty_string, 1 );
current_position++; current_position++;
} }
string_section->append_data( str, (Elf_Word)std::strlen( str ) + 1 ); string_section->append_data( str,
(Elf_Word)std::strlen( str ) + 1 );
} }
return current_position; return current_position;
} }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------ Elf_Word add_string( const std::string& str )
Elf_Word
add_string( const std::string& str )
{ {
return add_string( str.c_str() ); return add_string( str.c_str() );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
S* string_section; S* string_section;
}; };
using string_section_accessor = string_section_accessor_template<section>; using string_section_accessor = string_section_accessor_template<section>;
using const_string_section_accessor = string_section_accessor_template<const section>; using const_string_section_accessor =
string_section_accessor_template<const section>;
} // namespace ELFIO } // namespace ELFIO

View File

@ -26,40 +26,38 @@ THE SOFTWARE.
namespace ELFIO { namespace ELFIO {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class S > template <class S> class symbol_section_accessor_template
class symbol_section_accessor_template
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
symbol_section_accessor_template( const elfio& elf_file_, S* symbol_section_ ) : symbol_section_accessor_template( const elfio& elf_file_,
elf_file( elf_file_ ), S* symbol_section_ )
symbol_section( symbol_section_ ) : elf_file( elf_file_ ), symbol_section( symbol_section_ )
{ {
find_hash_section(); find_hash_section();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Xword Elf_Xword get_symbols_num() const
get_symbols_num() const
{ {
Elf_Xword nRet = 0; Elf_Xword nRet = 0;
if ( 0 != symbol_section->get_entry_size() ) { if ( 0 != symbol_section->get_entry_size() ) {
nRet = symbol_section->get_size() / symbol_section->get_entry_size(); nRet =
symbol_section->get_size() / symbol_section->get_entry_size();
} }
return nRet; return nRet;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_symbol( Elf_Xword index,
get_symbol( Elf_Xword index, std::string& name,
std::string& name, Elf64_Addr& value,
Elf64_Addr& value, Elf_Xword& size,
Elf_Xword& size, unsigned char& bind,
unsigned char& bind, unsigned char& type,
unsigned char& type, Elf_Half& section_index,
Elf_Half& section_index, unsigned char& other ) const
unsigned char& other ) const
{ {
bool ret = false; bool ret = false;
@ -75,33 +73,35 @@ class symbol_section_accessor_template
return ret; return ret;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_symbol( const std::string& name,
get_symbol( const std::string& name, Elf64_Addr& value,
Elf64_Addr& value, Elf_Xword& size,
Elf_Xword& size, unsigned char& bind,
unsigned char& bind, unsigned char& type,
unsigned char& type, Elf_Half& section_index,
Elf_Half& section_index, unsigned char& other ) const
unsigned char& other ) const
{ {
bool ret = false; bool ret = false;
if ( 0 != get_hash_table_index() ) { if ( 0 != get_hash_table_index() ) {
Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data(); Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data();
Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() + Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() +
sizeof( Elf_Word ) ); sizeof( Elf_Word ) );
Elf_Word val = elf_hash( (const unsigned char*)name.c_str() ); Elf_Word val = elf_hash( (const unsigned char*)name.c_str() );
Elf_Word y = *(const Elf_Word*)( hash_section->get_data() + Elf_Word y = *(const Elf_Word*)( hash_section->get_data() +
( 2 + val % nbucket ) * sizeof( Elf_Word ) ); ( 2 + val % nbucket ) *
std::string str; sizeof( Elf_Word ) );
std::string str;
get_symbol( y, str, value, size, bind, type, section_index, other ); get_symbol( y, str, value, size, bind, type, section_index, other );
while ( str != name && STN_UNDEF != y && y < nchain ) { while ( str != name && STN_UNDEF != y && y < nchain ) {
y = *(const Elf_Word*)( hash_section->get_data() + y = *(const Elf_Word*)( hash_section->get_data() +
( 2 + nbucket + y ) * sizeof( Elf_Word ) ); ( 2 + nbucket + y ) *
get_symbol( y, str, value, size, bind, type, section_index, other ); sizeof( Elf_Word ) );
get_symbol( y, str, value, size, bind, type, section_index,
other );
} }
if ( str == name ) { if ( str == name ) {
ret = true; ret = true;
} }
} }
@ -109,7 +109,7 @@ class symbol_section_accessor_template
for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) { for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) {
std::string symbol_name; std::string symbol_name;
if ( get_symbol( i, symbol_name, value, size, bind, type, if ( get_symbol( i, symbol_name, value, size, bind, type,
section_index, other) ) { section_index, other ) ) {
if ( symbol_name == name ) { if ( symbol_name == name ) {
ret = true; ret = true;
} }
@ -120,18 +120,16 @@ class symbol_section_accessor_template
return ret; return ret;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool bool get_symbol( const Elf64_Addr& value,
get_symbol( const Elf64_Addr& value, std::string& name,
std::string& name, Elf_Xword& size,
Elf_Xword& size, unsigned char& bind,
unsigned char& bind, unsigned char& type,
unsigned char& type, Elf_Half& section_index,
Elf_Half& section_index, unsigned char& other ) const
unsigned char& other ) const
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
Elf_Xword idx = 0; Elf_Xword idx = 0;
@ -139,27 +137,35 @@ class symbol_section_accessor_template
Elf64_Addr v = 0; Elf64_Addr v = 0;
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
match = generic_search_symbols<Elf32_Sym>([&](const Elf32_Sym* sym) { match = generic_search_symbols<Elf32_Sym>(
return convertor(sym->st_value) == value; [&]( const Elf32_Sym* sym ) {
}, idx); return convertor( sym->st_value ) == value;
} else { },
match = generic_search_symbols<Elf64_Sym>([&](const Elf64_Sym* sym) { idx );
return convertor(sym->st_value) == value; }
}, idx); else {
match = generic_search_symbols<Elf64_Sym>(
[&]( const Elf64_Sym* sym ) {
return convertor( sym->st_value ) == value;
},
idx );
} }
if ( match ) { if ( match ) {
return get_symbol( idx, name, v, size, bind, type, section_index, other ); return get_symbol( idx, name, v, size, bind, type, section_index,
other );
} }
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Word Elf_Word add_symbol( Elf_Word name,
add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, Elf64_Addr value,
unsigned char info, unsigned char other, Elf_Xword size,
Elf_Half shndx ) unsigned char info,
unsigned char other,
Elf_Half shndx )
{ {
Elf_Word nRet; Elf_Word nRet;
@ -173,72 +179,82 @@ class symbol_section_accessor_template
} }
if ( elf_file.get_class() == ELFCLASS32 ) { if ( elf_file.get_class() == ELFCLASS32 ) {
nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info, other, nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info,
shndx ); other, shndx );
} }
else { else {
nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info, other, nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info,
shndx ); other, shndx );
} }
return nRet; return nRet;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Word Elf_Word add_symbol( Elf_Word name,
add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, Elf64_Addr value,
unsigned char bind, unsigned char type, unsigned char other, Elf_Xword size,
Elf_Half shndx ) unsigned char bind,
unsigned char type,
unsigned char other,
Elf_Half shndx )
{ {
return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, shndx ); return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other,
shndx );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Word Elf_Word add_symbol( string_section_accessor& pStrWriter,
add_symbol( string_section_accessor& pStrWriter, const char* str, const char* str,
Elf64_Addr value, Elf_Xword size, Elf64_Addr value,
unsigned char info, unsigned char other, Elf_Xword size,
Elf_Half shndx ) unsigned char info,
unsigned char other,
Elf_Half shndx )
{ {
Elf_Word index = pStrWriter.add_string( str ); Elf_Word index = pStrWriter.add_string( str );
return add_symbol( index, value, size, info, other, shndx ); return add_symbol( index, value, size, info, other, shndx );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Word Elf_Word add_symbol( string_section_accessor& pStrWriter,
add_symbol( string_section_accessor& pStrWriter, const char* str, const char* str,
Elf64_Addr value, Elf_Xword size, Elf64_Addr value,
unsigned char bind, unsigned char type, unsigned char other, Elf_Xword size,
Elf_Half shndx ) unsigned char bind,
unsigned char type,
unsigned char other,
Elf_Half shndx )
{ {
return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx ); return add_symbol( pStrWriter, str, value, size,
ELF_ST_INFO( bind, type ), other, shndx );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Xword Elf_Xword arrange_local_symbols(
arrange_local_symbols(std::function<void(Elf_Xword first, Elf_Xword second)> func = nullptr) std::function<void( Elf_Xword first, Elf_Xword second )> func =
nullptr )
{ {
int nRet = 0; int nRet = 0;
if (elf_file.get_class() == ELFCLASS32) { if ( elf_file.get_class() == ELFCLASS32 ) {
nRet = generic_arrange_local_symbols<Elf32_Sym>(func); nRet = generic_arrange_local_symbols<Elf32_Sym>( func );
} }
else { else {
nRet = generic_arrange_local_symbols<Elf64_Sym>(func); nRet = generic_arrange_local_symbols<Elf64_Sym>( func );
} }
return nRet; return nRet;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private : private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void find_hash_section()
find_hash_section()
{ {
hash_section = 0; hash_section = 0;
hash_section_index = 0; hash_section_index = 0;
Elf_Half nSecNo = elf_file.sections.size(); Elf_Half nSecNo = elf_file.sections.size();
for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) { for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) {
const section* sec = elf_file.sections[i]; const section* sec = elf_file.sections[i];
if ( sec->get_link() == symbol_section->get_index() ) { if ( sec->get_link() == symbol_section->get_index() ) {
@ -248,28 +264,22 @@ class symbol_section_accessor_template
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_string_table_index() const
get_string_table_index() const
{ {
return (Elf_Half)symbol_section->get_link(); return (Elf_Half)symbol_section->get_link();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Half Elf_Half get_hash_table_index() const { return hash_section_index; }
get_hash_table_index() const
{
return hash_section_index;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T> const T* generic_get_symbol_ptr( Elf_Xword index ) const
const T* {
generic_get_symbol_ptr(Elf_Xword index) const {
if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) {
const T* pSym = reinterpret_cast<const T*>( const T* pSym = reinterpret_cast<const T*>(
symbol_section->get_data() + symbol_section->get_data() +
index * symbol_section->get_entry_size() ); index * symbol_section->get_entry_size() );
return pSym; return pSym;
} }
@ -277,17 +287,18 @@ class symbol_section_accessor_template
return nullptr; return nullptr;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
bool bool generic_search_symbols( std::function<bool( const T* )> match,
generic_search_symbols(std::function<bool(const T*)> match, Elf_Xword& idx) const { Elf_Xword& idx ) const
for (Elf_Xword i = 0; i < get_symbols_num(); i++){ {
const T* symPtr = generic_get_symbol_ptr<T>(i); for ( Elf_Xword i = 0; i < get_symbols_num(); i++ ) {
const T* symPtr = generic_get_symbol_ptr<T>( i );
if (symPtr == nullptr) if ( symPtr == nullptr )
return false; return false;
if (match(symPtr)) { if ( match( symPtr ) ) {
idx = i; idx = i;
return true; return true;
} }
@ -296,37 +307,40 @@ class symbol_section_accessor_template
return false; return false;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
bool bool generic_get_symbol( Elf_Xword index,
generic_get_symbol( Elf_Xword index, std::string& name,
std::string& name, Elf64_Addr& value, Elf64_Addr& value,
Elf_Xword& size, Elf_Xword& size,
unsigned char& bind, unsigned char& type, unsigned char& bind,
Elf_Half& section_index, unsigned char& type,
unsigned char& other ) const Elf_Half& section_index,
unsigned char& other ) const
{ {
bool ret = false; bool ret = false;
if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) {
const T* pSym = reinterpret_cast<const T*>( const T* pSym = reinterpret_cast<const T*>(
symbol_section->get_data() + symbol_section->get_data() +
index * symbol_section->get_entry_size() ); index * symbol_section->get_entry_size() );
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
section* string_section = elf_file.sections[get_string_table_index()]; section* string_section =
elf_file.sections[get_string_table_index()];
string_section_accessor str_reader( string_section ); string_section_accessor str_reader( string_section );
const char* pStr = str_reader.get_string( convertor( pSym->st_name ) ); const char* pStr =
str_reader.get_string( convertor( pSym->st_name ) );
if ( 0 != pStr ) { if ( 0 != pStr ) {
name = pStr; name = pStr;
} }
value = convertor( pSym->st_value ); value = convertor( pSym->st_value );
size = convertor( pSym->st_size ); size = convertor( pSym->st_size );
bind = ELF_ST_BIND( pSym->st_info ); bind = ELF_ST_BIND( pSym->st_info );
type = ELF_ST_TYPE( pSym->st_info ); type = ELF_ST_TYPE( pSym->st_info );
section_index = convertor( pSym->st_shndx ); section_index = convertor( pSym->st_shndx );
other = pSym->st_other; other = pSym->st_other;
ret = true; ret = true;
} }
@ -334,12 +348,14 @@ class symbol_section_accessor_template
return ret; return ret;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template< class T > template <class T>
Elf_Word Elf_Word generic_add_symbol( Elf_Word name,
generic_add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size, Elf64_Addr value,
unsigned char info, unsigned char other, Elf_Xword size,
Elf_Half shndx ) unsigned char info,
unsigned char other,
Elf_Half shndx )
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
@ -363,53 +379,50 @@ class symbol_section_accessor_template
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template <class T> template <class T>
Elf_Xword Elf_Xword generic_arrange_local_symbols(
generic_arrange_local_symbols(std::function<void (Elf_Xword first, Elf_Xword second)> func) std::function<void( Elf_Xword first, Elf_Xword second )> func )
{ {
const endianess_convertor &convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
const Elf_Xword size = symbol_section->get_entry_size(); const Elf_Xword size = symbol_section->get_entry_size();
Elf_Xword first_not_local = 1; // Skip the first entry. It is always NOTYPE Elf_Xword first_not_local =
Elf_Xword current = 0; 1; // Skip the first entry. It is always NOTYPE
Elf_Xword count = get_symbols_num(); Elf_Xword current = 0;
Elf_Xword count = get_symbols_num();
while (true) while ( true ) {
{ T* p1 = nullptr;
T *p1 = nullptr; T* p2 = nullptr;
T *p2 = nullptr;
while (first_not_local < count) while ( first_not_local < count ) {
{ p1 = const_cast<T*>(
p1 = const_cast<T *>(generic_get_symbol_ptr<T>(first_not_local)); generic_get_symbol_ptr<T>( first_not_local ) );
if (ELF_ST_BIND(convertor(p1->st_info)) != STB_LOCAL) if ( ELF_ST_BIND( convertor( p1->st_info ) ) != STB_LOCAL )
break; break;
++first_not_local; ++first_not_local;
} }
current = first_not_local + 1; current = first_not_local + 1;
while (current < count) while ( current < count ) {
{ p2 = const_cast<T*>( generic_get_symbol_ptr<T>( current ) );
p2 = const_cast<T *>(generic_get_symbol_ptr<T>(current)); if ( ELF_ST_BIND( convertor( p2->st_info ) ) == STB_LOCAL )
if (ELF_ST_BIND(convertor(p2->st_info)) == STB_LOCAL)
break; break;
++current; ++current;
} }
if (first_not_local < count && current < count) if ( first_not_local < count && current < count ) {
{ if ( func )
if (func) func( first_not_local, current );
func(first_not_local, current);
// Swap the symbols // Swap the symbols
T tmp; T tmp;
std::copy(p1, p1 + 1, &tmp); std::copy( p1, p1 + 1, &tmp );
std::copy(p2, p2 + 1, p1); std::copy( p2, p2 + 1, p1 );
std::copy(&tmp, &tmp + 1, p2); std::copy( &tmp, &tmp + 1, p2 );
} }
else else {
{
// Update 'info' field of the section // Update 'info' field of the section
symbol_section->set_info(first_not_local); symbol_section->set_info( first_not_local );
break; break;
} }
} }
@ -419,7 +432,7 @@ class symbol_section_accessor_template
return first_not_local; return first_not_local;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
const elfio& elf_file; const elfio& elf_file;
S* symbol_section; S* symbol_section;
@ -428,7 +441,8 @@ class symbol_section_accessor_template
}; };
using symbol_section_accessor = symbol_section_accessor_template<section>; using symbol_section_accessor = symbol_section_accessor_template<section>;
using const_symbol_section_accessor = symbol_section_accessor_template<const section>; using const_symbol_section_accessor =
symbol_section_accessor_template<const section>;
} // namespace ELFIO } // namespace ELFIO

View File

@ -24,154 +24,124 @@ THE SOFTWARE.
#define ELFIO_UTILS_HPP #define ELFIO_UTILS_HPP
#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \ #define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \
TYPE get_##NAME() const \ TYPE get_##NAME() const { return ( *convertor )( FIELD ); }
{ \
return (*convertor)( FIELD ); \
}
#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \ #define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \
void set_##NAME( TYPE value ) \ void set_##NAME( TYPE value ) \
{ \ { \
FIELD = value; \ FIELD = value; \
FIELD = (*convertor)( FIELD ); \ FIELD = ( *convertor )( FIELD ); \
} }
#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \ #define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \
TYPE get_##NAME() const \ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \
{ \ void set_##NAME( TYPE value ) \
return (*convertor)( FIELD ); \ { \
} \ FIELD = value; \
void set_##NAME( TYPE value ) \ FIELD = ( *convertor )( FIELD ); \
{ \
FIELD = value; \
FIELD = (*convertor)( FIELD ); \
} }
#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) \ #define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0
virtual TYPE get_##NAME() const = 0
#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \ #define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \
virtual void set_##NAME( TYPE value ) = 0 virtual void set_##NAME( TYPE value ) = 0
#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \ #define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \
virtual TYPE get_##NAME() const = 0; \ virtual TYPE get_##NAME() const = 0; \
virtual void set_##NAME( TYPE value ) = 0 virtual void set_##NAME( TYPE value ) = 0
namespace ELFIO { namespace ELFIO {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class endianess_convertor { class endianess_convertor
{
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
endianess_convertor() endianess_convertor() { need_conversion = false; }
{
need_conversion = false;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void setup( unsigned char elf_file_encoding )
setup( unsigned char elf_file_encoding )
{ {
need_conversion = ( elf_file_encoding != get_host_encoding() ); need_conversion = ( elf_file_encoding != get_host_encoding() );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
uint64_t uint64_t operator()( uint64_t value ) const
operator()( uint64_t value ) const {
if ( !need_conversion ) {
return value;
}
value = ( ( value & 0x00000000000000FFull ) << 56 ) |
( ( value & 0x000000000000FF00ull ) << 40 ) |
( ( value & 0x0000000000FF0000ull ) << 24 ) |
( ( value & 0x00000000FF000000ull ) << 8 ) |
( ( value & 0x000000FF00000000ull ) >> 8 ) |
( ( value & 0x0000FF0000000000ull ) >> 24 ) |
( ( value & 0x00FF000000000000ull ) >> 40 ) |
( ( value & 0xFF00000000000000ull ) >> 56 );
return value;
}
//------------------------------------------------------------------------------
int64_t operator()( int64_t value ) const
{
if ( !need_conversion ) {
return value;
}
return ( int64_t )( *this )( (uint64_t)value );
}
//------------------------------------------------------------------------------
uint32_t operator()( uint32_t value ) const
{ {
if ( !need_conversion ) { if ( !need_conversion ) {
return value; return value;
} }
value = value =
( ( value & 0x00000000000000FFull ) << 56 ) | ( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) |
( ( value & 0x000000000000FF00ull ) << 40 ) | ( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 );
( ( value & 0x0000000000FF0000ull ) << 24 ) |
( ( value & 0x00000000FF000000ull ) << 8 ) |
( ( value & 0x000000FF00000000ull ) >> 8 ) |
( ( value & 0x0000FF0000000000ull ) >> 24 ) |
( ( value & 0x00FF000000000000ull ) >> 40 ) |
( ( value & 0xFF00000000000000ull ) >> 56 );
return value; return value;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int64_t int32_t operator()( int32_t value ) const
operator()( int64_t value ) const
{ {
if ( !need_conversion ) { if ( !need_conversion ) {
return value; return value;
} }
return (int64_t)(*this)( (uint64_t)value ); return ( int32_t )( *this )( (uint32_t)value );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
uint32_t uint16_t operator()( uint16_t value ) const
operator()( uint32_t value ) const
{ {
if ( !need_conversion ) { if ( !need_conversion ) {
return value; return value;
} }
value = value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 );
( ( value & 0x000000FF ) << 24 ) |
( ( value & 0x0000FF00 ) << 8 ) |
( ( value & 0x00FF0000 ) >> 8 ) |
( ( value & 0xFF000000 ) >> 24 );
return value; return value;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int32_t int16_t operator()( int16_t value ) const
operator()( int32_t value ) const
{ {
if ( !need_conversion ) { if ( !need_conversion ) {
return value; return value;
} }
return (int32_t)(*this)( (uint32_t)value ); return ( int16_t )( *this )( (uint16_t)value );
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
uint16_t int8_t operator()( int8_t value ) const { return value; }
operator()( uint16_t value ) const
{
if ( !need_conversion ) {
return value;
}
value =
( ( value & 0x00FF ) << 8 ) |
( ( value & 0xFF00 ) >> 8 );
return value; //------------------------------------------------------------------------------
} uint8_t operator()( uint8_t value ) const { return value; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int16_t
operator()( int16_t value ) const
{
if ( !need_conversion ) {
return value;
}
return (int16_t)(*this)( (uint16_t)value );
}
//------------------------------------------------------------------------------
int8_t
operator()( int8_t value ) const
{
return value;
}
//------------------------------------------------------------------------------
uint8_t
operator()( uint8_t value ) const
{
return value;
}
//------------------------------------------------------------------------------
private: private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned char unsigned char get_host_encoding() const
get_host_encoding() const
{ {
static const int tmp = 1; static const int tmp = 1;
if ( 1 == *(const char*)&tmp ) { if ( 1 == *(const char*)&tmp ) {
@ -182,20 +152,17 @@ class endianess_convertor {
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
bool need_conversion; bool need_conversion;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline inline uint32_t elf_hash( const unsigned char* name )
uint32_t
elf_hash( const unsigned char *name )
{ {
uint32_t h = 0, g; uint32_t h = 0, g;
while ( *name ) { while ( *name ) {
h = (h << 4) + *name++; h = ( h << 4 ) + *name++;
g = h & 0xf0000000; g = h & 0xf0000000;
if ( g != 0 ) if ( g != 0 )
h ^= g >> 24; h ^= g >> 24;

View File

@ -49,36 +49,36 @@ diff before.txt after.txt
using namespace ELFIO; using namespace ELFIO;
void overwrite_data(const std::string &filename, long offset, std::string &str) void overwrite_data( const std::string& filename,
long offset,
std::string& str )
{ {
std::ofstream file(filename, std::ios::in | std::ios::out | std::ios::binary); std::ofstream file( filename,
if (!file) std::ios::in | std::ios::out | std::ios::binary );
if ( !file )
throw "Error opening file" + filename; throw "Error opening file" + filename;
std::string data(str.length(), '-'); std::string data( str.length(), '-' );
file.seekp(offset); file.seekp( offset );
file.write(data.c_str(), data.length() + 1); file.write( data.c_str(), data.length() + 1 );
} }
void process_string_table(const section *s, const std::string &filename) void process_string_table( const section* s, const std::string& filename )
{ {
std::cout << "Info: processing string table section" << std::endl; std::cout << "Info: processing string table section" << std::endl;
int index = 1; int index = 1;
while (index < s->get_size()) while ( index < s->get_size() ) {
{ auto str = std::string( s->get_data() + index );
auto str = std::string(s->get_data() + index);
// For the example purpose, we rename main function name only // For the example purpose, we rename main function name only
if (str == "main") if ( str == "main" )
overwrite_data(filename, s->get_offset() + index, str); overwrite_data( filename, s->get_offset() + index, str );
index += str.length() + 1; index += str.length() + 1;
} }
} }
int main(int argc, char **argv) int main( int argc, char** argv )
{ {
try try {
{ if ( argc != 2 ) {
if (argc != 2)
{
std::cout << "Usage: anonymizer <file_name>\n"; std::cout << "Usage: anonymizer <file_name>\n";
return 1; return 1;
} }
@ -87,28 +87,26 @@ int main(int argc, char **argv)
elfio reader; elfio reader;
if (!reader.load(filename)) if ( !reader.load( filename ) ) {
{ std::cerr << "File " << filename
std::cerr << "File " << filename << " is not found or it is not an ELF file\n"; << " is not found or it is not an ELF file\n";
return 1; return 1;
} }
for (auto section = reader.sections.begin(); section != reader.sections.end(); ++section) for ( auto section = reader.sections.begin();
{ section != reader.sections.end(); ++section ) {
if ((*section)->get_type() == SHT_STRTAB && if ( ( *section )->get_type() == SHT_STRTAB &&
std::string((*section)->get_name()) == std::string(".strtab")) std::string( ( *section )->get_name() ) ==
{ std::string( ".strtab" ) ) {
process_string_table(*section, filename); process_string_table( *section, filename );
} }
} }
return 0; return 0;
} }
catch (const std::string &s) catch ( const std::string& s ) {
{
std::cerr << s << std::endl; std::cerr << s << std::endl;
} }
catch (const char *s) catch ( const char* s ) {
{
std::cerr << s << std::endl; std::cerr << s << std::endl;
} }
return 1; return 1;

View File

@ -23,8 +23,8 @@ THE SOFTWARE.
*/ */
#ifdef _MSC_VER #ifdef _MSC_VER
#define _SCL_SECURE_NO_WARNINGS #define _SCL_SECURE_NO_WARNINGS
#define ELFIO_NO_INTTYPES #define ELFIO_NO_INTTYPES
#endif #endif
#include <iostream> #include <iostream>
@ -46,14 +46,14 @@ int main( int argc, char** argv )
return 1; return 1;
} }
dump::header ( std::cout, reader ); dump::header( std::cout, reader );
dump::section_headers( std::cout, reader ); dump::section_headers( std::cout, reader );
dump::segment_headers( std::cout, reader ); dump::segment_headers( std::cout, reader );
dump::symbol_tables ( std::cout, reader ); dump::symbol_tables( std::cout, reader );
dump::notes ( std::cout, reader ); dump::notes( std::cout, reader );
dump::dynamic_tags ( std::cout, reader ); dump::dynamic_tags( std::cout, reader );
dump::section_datas ( std::cout, reader ); dump::section_datas( std::cout, reader );
dump::segment_datas ( std::cout, reader ); dump::segment_datas( std::cout, reader );
return 0; return 0;
} }

View File

@ -37,11 +37,8 @@ int main( int argc, char** argv )
std::cout << "Number of sections: " << sec_num << std::endl; std::cout << "Number of sections: " << sec_num << std::endl;
for ( int i = 0; i < sec_num; ++i ) { for ( int i = 0; i < sec_num; ++i ) {
section* psec = reader.sections[i]; section* psec = reader.sections[i];
std::cout << " [" << i << "] " std::cout << " [" << i << "] " << psec->get_name() << "\t"
<< psec->get_name() << psec->get_size() << std::endl;
<< "\t"
<< psec->get_size()
<< std::endl;
// Access to section's data // Access to section's data
// const char* p = reader.sections[i]->get_data() // const char* p = reader.sections[i]->get_data()
} }
@ -51,14 +48,9 @@ int main( int argc, char** argv )
std::cout << "Number of segments: " << seg_num << std::endl; std::cout << "Number of segments: " << seg_num << std::endl;
for ( int i = 0; i < seg_num; ++i ) { for ( int i = 0; i < seg_num; ++i ) {
const segment* pseg = reader.segments[i]; const segment* pseg = reader.segments[i];
std::cout << " [" << i << "] 0x" << std::hex std::cout << " [" << i << "] 0x" << std::hex << pseg->get_flags()
<< pseg->get_flags() << "\t0x" << pseg->get_virtual_address() << "\t0x"
<< "\t0x" << pseg->get_file_size() << "\t0x" << pseg->get_memory_size()
<< pseg->get_virtual_address()
<< "\t0x"
<< pseg->get_file_size()
<< "\t0x"
<< pseg->get_memory_size()
<< std::endl; << std::endl;
// Access to segments's data // Access to segments's data
// const char* p = reader.segments[i]->get_data() // const char* p = reader.segments[i]->get_data()
@ -79,8 +71,8 @@ int main( int argc, char** argv )
unsigned char other; unsigned char other;
// Read symbol properties // Read symbol properties
symbols.get_symbol( j, name, value, size, bind, symbols.get_symbol( j, name, value, size, bind, type,
type, section_index, other ); section_index, other );
std::cout << j << " " << name << " " << value << std::endl; std::cout << j << " " << name << " " << value << std::endl;
} }
} }

View File

@ -25,32 +25,32 @@ int main( void )
writer.set_os_abi( ELFOSABI_LINUX ); writer.set_os_abi( ELFOSABI_LINUX );
writer.set_type( ET_REL ); writer.set_type( ET_REL );
writer.set_machine(EM_X86_64); writer.set_machine( EM_X86_64 );
// This is our code // This is our code
char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4 char text[] = {
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1 '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg '\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14 '\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
'\xCD', '\x80', // int 0x80 '\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1 '\xCD', '\x80', // int 0x80
'\xCD', '\x80', // int 0x80 '\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10 '\xCD', '\x80', // int 0x80
'\x2C', '\x20', '\x57', '\x6F', '\x72', '\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
'\x6C', '\x64', '\x21', '\x0A' '\x2C', '\x20', '\x57', '\x6F', '\x72',
}; '\x6C', '\x64', '\x21', '\x0A' };
Elf64_Addr place_to_adjust = 11; Elf64_Addr place_to_adjust = 11;
// Create code section // Create code section
section* text_sec = writer.sections.add( ".text" ); section* text_sec = writer.sections.add( ".text" );
text_sec->set_type ( SHT_PROGBITS ); text_sec->set_type( SHT_PROGBITS );
text_sec->set_flags ( SHF_ALLOC | SHF_EXECINSTR ); text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
text_sec->set_addr_align( 0x10 ); text_sec->set_addr_align( 0x10 );
text_sec->set_data ( text, sizeof( text ) ); text_sec->set_data( text, sizeof( text ) );
// Create string table section // Create string table section
section* str_sec = writer.sections.add( ".strtab" ); section* str_sec = writer.sections.add( ".strtab" );
str_sec->set_type ( SHT_STRTAB ); str_sec->set_type( SHT_STRTAB );
// Create string table writer // Create string table writer
string_section_accessor stra( str_sec ); string_section_accessor stra( str_sec );
@ -59,29 +59,28 @@ int main( void )
// Create symbol table section // Create symbol table section
section* sym_sec = writer.sections.add( ".symtab" ); section* sym_sec = writer.sections.add( ".symtab" );
sym_sec->set_type ( SHT_SYMTAB ); sym_sec->set_type( SHT_SYMTAB );
sym_sec->set_info ( 1 ); sym_sec->set_info( 1 );
sym_sec->set_addr_align( 0x4 ); sym_sec->set_addr_align( 0x4 );
sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) ); sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
sym_sec->set_link ( str_sec->get_index() ); sym_sec->set_link( str_sec->get_index() );
// Create symbol table writer // Create symbol table writer
symbol_section_accessor syma( writer, sym_sec ); symbol_section_accessor syma( writer, sym_sec );
// Add symbol entry (msg has offset == 29) // Add symbol entry (msg has offset == 29)
Elf_Word sym_to_adjust = syma.add_symbol( str_index, 29, 0, STB_GLOBAL, Elf_Word sym_to_adjust = syma.add_symbol(
STT_OBJECT, 0, str_index, 29, 0, STB_GLOBAL, STT_OBJECT, 0, text_sec->get_index() );
text_sec->get_index() );
// Another way to add symbol // Another way to add symbol
syma.add_symbol( stra, "_start", 0x00000000, 0, STB_WEAK, STT_FUNC, 0, syma.add_symbol( stra, "_start", 0x00000000, 0, STB_WEAK, STT_FUNC, 0,
text_sec->get_index() ); text_sec->get_index() );
// Create relocation table section // Create relocation table section
section* rel_sec = writer.sections.add( ".rel.text" ); section* rel_sec = writer.sections.add( ".rel.text" );
rel_sec->set_type ( SHT_REL ); rel_sec->set_type( SHT_REL );
rel_sec->set_info ( text_sec->get_index() ); rel_sec->set_info( text_sec->get_index() );
rel_sec->set_addr_align( 0x4 ); rel_sec->set_addr_align( 0x4 );
rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) ); rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
rel_sec->set_link ( sym_sec->get_index() ); rel_sec->set_link( sym_sec->get_index() );
// Create relocation table writer // Create relocation table writer
relocation_section_accessor rela( writer, rel_sec ); relocation_section_accessor rela( writer, rel_sec );
@ -102,7 +101,7 @@ int main( void )
note_section_accessor note_writer( writer, note_sec ); note_section_accessor note_writer( writer, note_sec );
note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 ); note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
char descr[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36}; char descr[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 };
note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) ); note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );
// Create ELF object file // Create ELF object file

View File

@ -20,14 +20,15 @@ int main( void )
text_sec->set_addr_align( 0x10 ); text_sec->set_addr_align( 0x10 );
// Add data into it // Add data into it
char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4 char text[] = {
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1 '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
'\xB9', '\x20', '\x80', '\x04', '\x08', // mov ecx, msg '\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14 '\xB9', '\x20', '\x80', '\x04', '\x08', // mov ecx, msg
'\xCD', '\x80', // int 0x80 '\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1 '\xCD', '\x80', // int 0x80
'\xCD', '\x80' // int 0x80 '\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
}; '\xCD', '\x80' // int 0x80
};
text_sec->set_data( text, sizeof( text ) ); text_sec->set_data( text, sizeof( text ) );
// Create a loadable segment // Create a loadable segment
@ -39,7 +40,8 @@ int main( void )
text_seg->set_align( 0x1000 ); text_seg->set_align( 0x1000 );
// Add code section into program segment // Add code section into program segment
text_seg->add_section_index( text_sec->get_index(), text_sec->get_addr_align() ); text_seg->add_section_index( text_sec->get_index(),
text_sec->get_addr_align() );
// Create data section // Create data section
section* data_sec = writer.sections.add( ".data" ); section* data_sec = writer.sections.add( ".data" );
@ -47,10 +49,10 @@ int main( void )
data_sec->set_flags( SHF_ALLOC | SHF_WRITE ); data_sec->set_flags( SHF_ALLOC | SHF_WRITE );
data_sec->set_addr_align( 0x4 ); data_sec->set_addr_align( 0x4 );
char data[] = { '\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10 char data[] = {
'\x2C', '\x20', '\x57', '\x6F', '\x72', '\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
'\x6C', '\x64', '\x21', '\x0A' '\x2C', '\x20', '\x57', '\x6F', '\x72',
}; '\x6C', '\x64', '\x21', '\x0A' };
data_sec->set_data( data, sizeof( data ) ); data_sec->set_data( data, sizeof( data ) );
// Create a read/write segment // Create a read/write segment
@ -62,7 +64,8 @@ int main( void )
data_seg->set_align( 0x10 ); data_seg->set_align( 0x10 );
// Add code section into program segment // Add code section into program segment
data_seg->add_section_index( data_sec->get_index(), data_sec->get_addr_align() ); data_seg->add_section_index( data_sec->get_index(),
data_sec->get_addr_align() );
// Add optional signature for the file producer // Add optional signature for the file producer
section* note_sec = writer.sections.add( ".note" ); section* note_sec = writer.sections.add( ".note" );
@ -70,14 +73,14 @@ int main( void )
note_sec->set_addr_align( 1 ); note_sec->set_addr_align( 1 );
note_section_accessor note_writer( writer, note_sec ); note_section_accessor note_writer( writer, note_sec );
note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 ); note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
char descr[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36}; char descr[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 };
note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) ); note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );
// Setup entry point // Setup entry point
writer.set_entry( 0x08048000 ); writer.set_entry( 0x08048000 );
// Create ELF file // Create ELF file
writer.save("hello_x86_64"); writer.save( "hello_x86_64" );
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff