mirror of
https://github.com/serge1/ELFIO.git
synced 2024-12-27 12:17:28 +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 {
|
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
|
||||||
|
|
||||||
|
@ -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; }
|
||||||
|
@ -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"
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user