From fc0293ebbd56e5cd7239fa5e937b373b83f4a964 Mon Sep 17 00:00:00 2001 From: Serge Lamikhov-Center Date: Fri, 13 Aug 2021 09:40:49 +0300 Subject: [PATCH] Explicit element size for array accessor --- elfio/elfio_array.hpp | 47 ++++++--------------- examples/c_wrapper/elfio_c_wrapper.cpp | 2 +- examples/c_wrapper/elfio_c_wrapper.h | 2 +- tests/ELFIOTest2.cpp | 58 +++++++++++++++++++++++--- 4 files changed, 67 insertions(+), 42 deletions(-) diff --git a/elfio/elfio_array.hpp b/elfio/elfio_array.hpp index a757b1f..e9ee925 100644 --- a/elfio/elfio_array.hpp +++ b/elfio/elfio_array.hpp @@ -28,7 +28,7 @@ THE SOFTWARE. namespace ELFIO { //------------------------------------------------------------------------------ -template class array_section_accessor_template +template class array_section_accessor_template { public: //------------------------------------------------------------------------------ @@ -40,9 +40,7 @@ template 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 array_section_accessor_template return false; } - if ( elf_file.get_class() == ELFCLASS32 ) { - generic_get_entry_arr( index, address ); - } - else { - generic_get_entry_arr( index, address ); - } + const endianess_convertor& convertor = elf_file.get_convertor(); + + const T temp = *reinterpret_cast( 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( address ); - } - else { - generic_add_entry_arr( address ); - } - } - - private: - //------------------------------------------------------------------------------ - template - 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( array_section->get_data() + - index * sizeof( T ) ); - address = convertor( temp ); - } - - //------------------------------------------------------------------------------ - template void generic_add_entry_arr( Elf64_Addr address ) { const endianess_convertor& convertor = elf_file.get_convertor(); @@ -96,15 +70,18 @@ template class array_section_accessor_template sizeof( temp ) ); } + private: //------------------------------------------------------------------------------ private: const elfio& elf_file; S* array_section; }; -using array_section_accessor = array_section_accessor_template
; +template +using array_section_accessor = array_section_accessor_template; +template using const_array_section_accessor = - array_section_accessor_template; + array_section_accessor_template; } // namespace ELFIO diff --git a/examples/c_wrapper/elfio_c_wrapper.cpp b/examples/c_wrapper/elfio_c_wrapper.cpp index ac8d706..7a96676 100644 --- a/examples/c_wrapper/elfio_c_wrapper.cpp +++ b/examples/c_wrapper/elfio_c_wrapper.cpp @@ -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( *pelfio, psection ); } void elfio_array_section_accessor_delete( parray_t parray ) { delete parray; } diff --git a/examples/c_wrapper/elfio_c_wrapper.h b/examples/c_wrapper/elfio_c_wrapper.h index e4fcb37..e40d9f6 100644 --- a/examples/c_wrapper/elfio_c_wrapper.h +++ b/examples/c_wrapper/elfio_c_wrapper.h @@ -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* parray_t; extern "C" { diff --git a/tests/ELFIOTest2.cpp b/tests/ELFIOTest2.cpp index 930c145..cfeb418 100644 --- a/tests/ELFIOTest2.cpp +++ b/tests/ELFIOTest2.cpp @@ -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 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 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 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 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 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 vers( reader, versec ); + + section* verneed = reader.sections[".gnu.version_r"]; + const_array_section_accessor 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; + } + } +}