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 {
//------------------------------------------------------------------------------
template <class S> class array_section_accessor_template
template <class S, typename T> class array_section_accessor_template
{
public:
//------------------------------------------------------------------------------
@ -40,9 +40,7 @@ template <class S> class array_section_accessor_template
//------------------------------------------------------------------------------
Elf_Xword get_entries_num() const
{
Elf_Xword entry_size = elf_file.get_class() == ELFCLASS32
? sizeof( Elf32_Addr )
: sizeof( Elf64_Addr );
Elf_Xword entry_size = sizeof( T );
return array_section->get_size() / entry_size;
}
@ -53,41 +51,17 @@ template <class S> class array_section_accessor_template
return false;
}
if ( elf_file.get_class() == ELFCLASS32 ) {
generic_get_entry_arr<Elf32_Addr>( index, address );
}
else {
generic_get_entry_arr<Elf64_Addr>( index, address );
}
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 );
return true;
}
//------------------------------------------------------------------------------
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();
@ -96,15 +70,18 @@ template <class S> class array_section_accessor_template
sizeof( temp ) );
}
private:
//------------------------------------------------------------------------------
private:
const elfio& elf_file;
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 =
array_section_accessor_template<const section>;
array_section_accessor_template<const section, T>;
} // 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,
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; }

View File

@ -85,7 +85,7 @@ typedef ELFIO::string_section_accessor* pstring_t;
typedef ELFIO::note_section_accessor* pnote_t;
typedef ELFIO::modinfo_section_accessor* pmodinfo_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"
{

View File

@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE( array_read_32 )
section* array_sec = reader.sections[".ctors"];
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 );
Elf64_Addr addr;
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"];
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 );
Elf64_Addr addr;
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"];
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_CHECK_EQUAL( array.get_entry( 0, addr ), true );
BOOST_CHECK_EQUAL( addr, 0x12C0 );
@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE( init_array_read_64 )
array_sec = reader.sections[".fini_array"];
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_CHECK_EQUAL( arrayf.get_entry( 0, addr ), true );
BOOST_CHECK_EQUAL( addr, 0x1280 );
@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE( init_array_write_64 )
section* array_sec = reader.sections[".init_array"];
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_CHECK_EQUAL( array.get_entry( 0, addr ), true );
BOOST_CHECK_EQUAL( addr, 0x12C0 );
@ -355,3 +355,51 @@ BOOST_AUTO_TEST_CASE( gnu_hash64_le )
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;
}
}
}