Explicit element size for array accessor

This commit is contained in:
Serge Lamikhov-Center 2021-08-13 09:40:49 +03:00
parent 91c8c7770a
commit fc0293ebbd
4 changed files with 67 additions and 42 deletions

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
namespace ELFIO { namespace ELFIO {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template <class S> class array_section_accessor_template template <class S, typename T> class array_section_accessor_template
{ {
public: public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -40,9 +40,7 @@ template <class S> class array_section_accessor_template
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Elf_Xword get_entries_num() const Elf_Xword get_entries_num() const
{ {
Elf_Xword entry_size = elf_file.get_class() == ELFCLASS32 Elf_Xword entry_size = sizeof( T );
? sizeof( Elf32_Addr )
: sizeof( Elf64_Addr );
return array_section->get_size() / entry_size; return array_section->get_size() / entry_size;
} }
@ -53,41 +51,17 @@ template <class S> class array_section_accessor_template
return false; return false;
} }
if ( elf_file.get_class() == ELFCLASS32 ) { const endianess_convertor& convertor = elf_file.get_convertor();
generic_get_entry_arr<Elf32_Addr>( index, address );
} const T temp = *reinterpret_cast<const T*>( array_section->get_data() +
else { index * sizeof( T ) );
generic_get_entry_arr<Elf64_Addr>( index, address ); address = convertor( temp );
}
return true; return true;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void add_entry( Elf64_Addr address ) void add_entry( Elf64_Addr address )
{
if ( elf_file.get_class() == ELFCLASS32 ) {
generic_add_entry_arr<Elf32_Addr>( address );
}
else {
generic_add_entry_arr<Elf64_Addr>( address );
}
}
private:
//------------------------------------------------------------------------------
template <class T>
void generic_get_entry_arr( Elf_Xword index, Elf64_Addr& address ) const
{
const endianess_convertor& convertor = elf_file.get_convertor();
const T temp = *reinterpret_cast<const T*>( array_section->get_data() +
index * sizeof( T ) );
address = convertor( temp );
}
//------------------------------------------------------------------------------
template <class T> void generic_add_entry_arr( Elf64_Addr address )
{ {
const endianess_convertor& convertor = elf_file.get_convertor(); const endianess_convertor& convertor = elf_file.get_convertor();
@ -96,15 +70,18 @@ template <class S> class array_section_accessor_template
sizeof( temp ) ); sizeof( temp ) );
} }
private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
const elfio& elf_file; const elfio& elf_file;
S* array_section; S* array_section;
}; };
using array_section_accessor = array_section_accessor_template<section>; template <typename T>
using array_section_accessor = array_section_accessor_template<section, T>;
template <typename T>
using const_array_section_accessor = using const_array_section_accessor =
array_section_accessor_template<const section>; array_section_accessor_template<const section, T>;
} // namespace ELFIO } // namespace ELFIO

View File

@ -473,7 +473,7 @@ void elfio_dynamic_add_entry( pdynamic_t pdynamic,
parray_t elfio_array_section_accessor_new( pelfio_t pelfio, parray_t elfio_array_section_accessor_new( pelfio_t pelfio,
psection_t psection ) psection_t psection )
{ {
return new array_section_accessor( *pelfio, psection ); return new array_section_accessor<Elf64_Word>( *pelfio, psection );
} }
void elfio_array_section_accessor_delete( parray_t parray ) { delete parray; } void elfio_array_section_accessor_delete( parray_t parray ) { delete parray; }

View File

@ -85,7 +85,7 @@ typedef ELFIO::string_section_accessor* pstring_t;
typedef ELFIO::note_section_accessor* pnote_t; typedef ELFIO::note_section_accessor* pnote_t;
typedef ELFIO::modinfo_section_accessor* pmodinfo_t; typedef ELFIO::modinfo_section_accessor* pmodinfo_t;
typedef ELFIO::dynamic_section_accessor* pdynamic_t; typedef ELFIO::dynamic_section_accessor* pdynamic_t;
typedef ELFIO::array_section_accessor* parray_t; typedef ELFIO::array_section_accessor<Elf64_Word>* parray_t;
extern "C" extern "C"
{ {

View File

@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE( array_read_32 )
section* array_sec = reader.sections[".ctors"]; section* array_sec = reader.sections[".ctors"];
BOOST_REQUIRE_NE( array_sec, nullptr ); BOOST_REQUIRE_NE( array_sec, nullptr );
const_array_section_accessor array( reader, array_sec ); const_array_section_accessor<Elf32_Addr> array( reader, array_sec );
BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 ); BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 );
Elf64_Addr addr; Elf64_Addr addr;
BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true ); BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true );
@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE( array_read_64 )
section* array_sec = reader.sections[".ctors"]; section* array_sec = reader.sections[".ctors"];
BOOST_REQUIRE_NE( array_sec, nullptr ); BOOST_REQUIRE_NE( array_sec, nullptr );
const_array_section_accessor array( reader, array_sec ); const_array_section_accessor<Elf64_Addr> array( reader, array_sec );
BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 ); BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 );
Elf64_Addr addr; Elf64_Addr addr;
BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true ); BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true );
@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE( init_array_read_64 )
section* array_sec = reader.sections[".init_array"]; section* array_sec = reader.sections[".init_array"];
BOOST_REQUIRE_NE( array_sec, nullptr ); BOOST_REQUIRE_NE( array_sec, nullptr );
const_array_section_accessor array( reader, array_sec ); const_array_section_accessor<Elf64_Addr> array( reader, array_sec );
BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 ); BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 );
BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true ); BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true );
BOOST_CHECK_EQUAL( addr, 0x12C0 ); BOOST_CHECK_EQUAL( addr, 0x12C0 );
@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE( init_array_read_64 )
array_sec = reader.sections[".fini_array"]; array_sec = reader.sections[".fini_array"];
BOOST_REQUIRE_NE( array_sec, nullptr ); BOOST_REQUIRE_NE( array_sec, nullptr );
array_section_accessor arrayf( reader, array_sec ); array_section_accessor<Elf64_Addr> arrayf( reader, array_sec );
BOOST_REQUIRE_EQUAL( arrayf.get_entries_num(), (Elf_Xword)1 ); BOOST_REQUIRE_EQUAL( arrayf.get_entries_num(), (Elf_Xword)1 );
BOOST_CHECK_EQUAL( arrayf.get_entry( 0, addr ), true ); BOOST_CHECK_EQUAL( arrayf.get_entry( 0, addr ), true );
BOOST_CHECK_EQUAL( addr, 0x1280 ); BOOST_CHECK_EQUAL( addr, 0x1280 );
@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE( init_array_write_64 )
section* array_sec = reader.sections[".init_array"]; section* array_sec = reader.sections[".init_array"];
BOOST_REQUIRE_NE( array_sec, nullptr ); BOOST_REQUIRE_NE( array_sec, nullptr );
array_section_accessor array( reader, array_sec ); array_section_accessor<Elf64_Addr> array( reader, array_sec );
BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 ); BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)2 );
BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true ); BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true );
BOOST_CHECK_EQUAL( addr, 0x12C0 ); BOOST_CHECK_EQUAL( addr, 0x12C0 );
@ -355,3 +355,51 @@ BOOST_AUTO_TEST_CASE( gnu_hash64_le )
true ); true );
} }
} }
////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE( gnu_version_64_le )
{
elfio reader;
// Load ELF data
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/hello_64" ), true );
std::string name;
Elf64_Addr value;
Elf_Xword size;
unsigned char bind;
unsigned char type;
Elf_Half section_index;
unsigned char other;
section* symsec = reader.sections[".dynsym"];
const_symbol_section_accessor dynsym( reader, symsec );
section* versec = reader.sections[".gnu.version"];
const_array_section_accessor<Elf64_Half> vers( reader, versec );
section* verneed = reader.sections[".gnu.version_r"];
const_array_section_accessor<Elf64_Half> vern( reader, verneed );
section* dynstr = reader.sections[".dynstr"];
BOOST_CHECK_EQUAL( versec->get_link(), symsec->get_index() );
BOOST_CHECK_EQUAL( verneed->get_link(), dynstr->get_index() );
for ( int i = 0; i < dynsym.get_symbols_num(); i++ ) {
BOOST_REQUIRE_EQUAL( dynsym.get_symbol( i, name, value, size, bind, type,
section_index, other ),
true );
Elf64_Addr verindex = 0;
vers.get_entry( i, verindex );
BOOST_CHECK_EQUAL( verindex, ( i / 2 ) * 2 );
const char* ptr = verneed->get_data();
if ( verindex > 1 ) {
Elf64_Addr value = 0;
vern.get_entry( verindex * 8, value );
std::cout << value << std::endl;
}
}
}