mirror of
https://github.com/serge1/ELFIO.git
synced 2024-12-26 18:15:40 +00:00
Explicit element size for array accessor
This commit is contained in:
parent
91c8c7770a
commit
fc0293ebbd
@ -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
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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"
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user