mirror of
https://github.com/serge1/ELFIO.git
synced 2024-12-26 18:15:40 +00:00
Address array section accessor added
The accessor is useful for manipulation of such sections as .ctors, .dtors, .init_array and .fini_array
This commit is contained in:
parent
0368a08624
commit
22ff134363
@ -7,7 +7,8 @@ nobase_include_HEADERS = elfio/elf_types.hpp elfio/elfio_dynamic.hpp \
|
||||
elfio/elfio_section.hpp elfio/elfio_segment.hpp \
|
||||
elfio/elfio_strings.hpp elfio/elfio_symbols.hpp \
|
||||
elfio/elfio_utils.hpp elfio/elfio_dump.hpp \
|
||||
elfio/elfio_version.hpp elfio/elfio_modinfo.hpp
|
||||
elfio/elfio_version.hpp elfio/elfio_modinfo.hpp \
|
||||
elfio/elfio_array.hpp
|
||||
|
||||
EXTRA_DIST = doc/elfio.pdf CMakeLists.txt examples/CMakeLists.txt cmake/elfioConfig.cmake.in
|
||||
|
||||
|
@ -505,7 +505,8 @@ nobase_include_HEADERS = elfio/elf_types.hpp elfio/elfio_dynamic.hpp \
|
||||
elfio/elfio_section.hpp elfio/elfio_segment.hpp \
|
||||
elfio/elfio_strings.hpp elfio/elfio_symbols.hpp \
|
||||
elfio/elfio_utils.hpp elfio/elfio_dump.hpp \
|
||||
elfio/elfio_version.hpp elfio/elfio_modinfo.hpp
|
||||
elfio/elfio_version.hpp elfio/elfio_modinfo.hpp \
|
||||
elfio/elfio_array.hpp
|
||||
|
||||
EXTRA_DIST = doc/elfio.pdf CMakeLists.txt examples/CMakeLists.txt cmake/elfioConfig.cmake.in
|
||||
TESTS = examples/elfdump/elfdump
|
||||
|
@ -947,6 +947,7 @@ class elfio
|
||||
#include <elfio/elfio_note.hpp>
|
||||
#include <elfio/elfio_relocation.hpp>
|
||||
#include <elfio/elfio_dynamic.hpp>
|
||||
#include <elfio/elfio_array.hpp>
|
||||
#include <elfio/elfio_modinfo.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
111
elfio/elfio_array.hpp
Normal file
111
elfio/elfio_array.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright (C) 2001-2020 by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_ARRAY_HPP
|
||||
#define ELFIO_ARRAY_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class S> class array_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
array_section_accessor_template( const elfio& elf_file_, S* section_ )
|
||||
: elf_file( elf_file_ ), array_section( section_ )
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Xword get_entries_num() const
|
||||
{
|
||||
Elf_Xword entry_size = elf_file.get_class() == ELFCLASS32
|
||||
? sizeof( Elf32_Addr )
|
||||
: sizeof( Elf64_Addr );
|
||||
return array_section->get_size() / entry_size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool get_entry( Elf_Xword index, Elf64_Addr& address ) const
|
||||
{
|
||||
if ( index >= get_entries_num() ) { // Is index valid
|
||||
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 );
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
T temp = (T)address;
|
||||
array_section->append_data( reinterpret_cast<char*>( &temp ),
|
||||
sizeof( temp ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
const elfio& elf_file;
|
||||
S* array_section;
|
||||
};
|
||||
|
||||
using array_section_accessor = array_section_accessor_template<section>;
|
||||
using const_array_section_accessor =
|
||||
array_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
|
||||
#endif // ELFIO_ARRAY_HPP
|
@ -99,10 +99,10 @@ template <class S> class dynamic_section_accessor_template
|
||||
void add_entry( Elf_Xword tag, Elf_Xword value )
|
||||
{
|
||||
if ( elf_file.get_class() == ELFCLASS32 ) {
|
||||
generic_add_entry<Elf32_Dyn>( tag, value );
|
||||
generic_add_entry_dyn<Elf32_Dyn>( tag, value );
|
||||
}
|
||||
else {
|
||||
generic_add_entry<Elf64_Dyn>( tag, value );
|
||||
generic_add_entry_dyn<Elf64_Dyn>( tag, value );
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ template <class S> class dynamic_section_accessor_template
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T> void generic_add_entry( Elf_Xword tag, Elf_Xword value )
|
||||
template <class T> void generic_add_entry_dyn( Elf_Xword tag, Elf_Xword value )
|
||||
{
|
||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||
|
||||
|
@ -161,6 +161,21 @@ int main( int argc, char* argv[] )
|
||||
}
|
||||
elfio_dynamic_section_accessor_delete( pdynamic );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// array
|
||||
//-----------------------------------------------------------------------------
|
||||
psection = elfio_get_section_by_name( pelfio, ".init_array" );
|
||||
if ( psection != 0 ) {
|
||||
parray_t parray = elfio_array_section_accessor_new( pelfio, psection );
|
||||
Elf_Xword arrno = elfio_array_get_entries_num( parray );
|
||||
for ( int i = 0; i < arrno; i++ ) {
|
||||
Elf64_Addr addr;
|
||||
elfio_array_get_entry( parray, i, &addr );
|
||||
// printf( "[%4d] %16lx\n", i, addr );
|
||||
}
|
||||
elfio_array_section_accessor_delete( parray );
|
||||
}
|
||||
|
||||
elfio_delete( pelfio );
|
||||
|
||||
return 0;
|
||||
|
@ -455,3 +455,32 @@ void elfio_dynamic_add_entry( pdynamic_t pdynamic,
|
||||
{
|
||||
pdynamic->add_entry( tag, value );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// array
|
||||
//-----------------------------------------------------------------------------
|
||||
parray_t elfio_array_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection )
|
||||
{
|
||||
return new array_section_accessor( *pelfio, psection );
|
||||
}
|
||||
|
||||
void elfio_array_section_accessor_delete( parray_t parray ) { delete parray; }
|
||||
|
||||
Elf_Xword elfio_array_get_entries_num( parray_t parray )
|
||||
{
|
||||
return parray->get_entries_num();
|
||||
}
|
||||
|
||||
bool elfio_array_get_entry( parray_t parray,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr* paddress )
|
||||
{
|
||||
bool ret = parray->get_entry( index, *paddress);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void elfio_array_add_entry( parray_t parray, Elf64_Addr address ) {
|
||||
parray->add_entry( address );
|
||||
}
|
||||
|
@ -85,6 +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;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -98,6 +99,7 @@ typedef void* pstring_t;
|
||||
typedef void* pnote_t;
|
||||
typedef void* pmodinfo_t;
|
||||
typedef void* pdynamic_t;
|
||||
typedef void* parray_t;
|
||||
typedef int bool;
|
||||
#endif
|
||||
|
||||
@ -301,6 +303,18 @@ typedef int bool;
|
||||
Elf_Xword tag,
|
||||
Elf_Xword value );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// array
|
||||
//-----------------------------------------------------------------------------
|
||||
parray_t elfio_array_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection );
|
||||
void elfio_array_section_accessor_delete( parray_t parray );
|
||||
Elf_Xword elfio_array_get_entries_num( parray_t parray );
|
||||
bool elfio_array_get_entry( parray_t parray,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr* paddress );
|
||||
void elfio_array_add_entry( parray_t parray, Elf64_Addr address );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -142,3 +142,93 @@ BOOST_AUTO_TEST_CASE( modinfo_write )
|
||||
BOOST_CHECK_EQUAL( value, attributes[i].value );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( array_read_32 )
|
||||
{
|
||||
elfio reader;
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/hello_32" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".ctors"];
|
||||
BOOST_REQUIRE_NE( array_sec, nullptr );
|
||||
|
||||
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 );
|
||||
BOOST_CHECK_EQUAL( addr, 0xFFFFFFFF );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 1, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x00000000 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( array_read_64 )
|
||||
{
|
||||
elfio reader;
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/hello_64" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".ctors"];
|
||||
BOOST_REQUIRE_NE( array_sec, nullptr );
|
||||
|
||||
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 );
|
||||
BOOST_CHECK_EQUAL( addr, 0xFFFFFFFFFFFFFFFF );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 1, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x0000000000000000 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( init_array_read_64 )
|
||||
{
|
||||
elfio reader;
|
||||
Elf64_Addr addr;
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/ctors" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".init_array"];
|
||||
BOOST_REQUIRE_NE( array_sec, nullptr );
|
||||
|
||||
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 );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 1, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x149F );
|
||||
|
||||
array_sec = reader.sections[".fini_array"];
|
||||
BOOST_REQUIRE_NE( array_sec, nullptr );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( init_array_write_64 )
|
||||
{
|
||||
elfio reader;
|
||||
Elf64_Addr addr;
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/ctors" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".init_array"];
|
||||
BOOST_REQUIRE_NE( array_sec, nullptr );
|
||||
|
||||
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 );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 1, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x149F );
|
||||
|
||||
array.add_entry( 0x12345678 );
|
||||
|
||||
BOOST_REQUIRE_EQUAL( array.get_entries_num(), (Elf_Xword)3 );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 0, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x12C0 );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 1, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x149F );
|
||||
BOOST_CHECK_EQUAL( array.get_entry( 2, addr ), true );
|
||||
BOOST_CHECK_EQUAL( addr, 0x12345678 );
|
||||
}
|
||||
|
BIN
tests/elf_examples/ctors
Executable file
BIN
tests/elf_examples/ctors
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user