Don't calculate section address if it was already initialized

This commit is contained in:
Serge Lamikhov-Center 2012-06-03 23:19:33 +03:00
parent 8e3eedac9a
commit 1a957edfba
4 changed files with 67 additions and 22 deletions

View File

@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE( write_obj_i386_64 )
BOOST_CHECK( output.match_pattern() );
}
bool write_exe_i386( bool is64bit )
bool write_exe_i386( bool is64bit, bool set_addr = false, Elf64_Addr addr = 0 )
{
elfio writer;
@ -147,6 +147,9 @@ bool write_exe_i386( bool is64bit )
text_sec->set_type( SHT_PROGBITS );
text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
text_sec->set_addr_align( 0x10 );
if ( set_addr ) {
text_sec->set_address( addr );
}
// Add data into it
char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
@ -316,3 +319,24 @@ BOOST_AUTO_TEST_CASE( elf_exe_copy_32 )
checkExeAreEqual( "../elf_examples/test_ppc",
"../elf_examples/test_ppc_copy" );
}
////////////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE( section_header_address_update )
{
elfio reader;
write_exe_i386( false, true, 0x0100 );
reader.load( "../elf_examples/write_exe_i386_32" );
section* sec = reader.sections[".text"];
BOOST_REQUIRE_NE( sec, (section*)0 );
BOOST_CHECK_EQUAL( sec->get_address(), 0x00000100 );
write_exe_i386( false, false, 0 );
reader.load( "../elf_examples/write_exe_i386_32" );
sec = reader.sections[".text"];
BOOST_REQUIRE_NE( sec, (section*)0 );
BOOST_CHECK_EQUAL( sec->get_address(), 0x08048000 );
}

View File

@ -471,8 +471,9 @@ class elfio
std::streampos headerPosition = (std::streamoff)header->get_sections_offset() +
header->get_section_entry_size()*sec->get_index();
// TODO: Fix this
sec->set_address( segments[i]->get_virtual_address() );
if ( !sec->is_address_initialized() ) {
sec->set_address( segments[i]->get_virtual_address() );
}
sec->save( f, headerPosition, (std::streamoff)current_data_pos );
current_data_pos += sec->get_size();
}

View File

@ -72,6 +72,7 @@ class section
virtual void save( std::ofstream& f,
std::streampos header_offset,
std::streampos data_offset ) = 0;
virtual bool is_address_initialized() = 0;
};
@ -83,8 +84,9 @@ class section_impl : public section
section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ )
{
std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
data = 0;
data_size = 0;
is_address_set = false;
data = 0;
data_size = 0;
}
//------------------------------------------------------------------------------
@ -95,15 +97,15 @@ class section_impl : public section
//------------------------------------------------------------------------------
// Section info functions
ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type )
ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags )
ELFIO_GET_SET_ACCESS( Elf64_Addr, address, header.sh_addr )
ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size )
ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link )
ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info )
ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign )
ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize )
ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name )
ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type );
ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags );
ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size );
ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link );
ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info );
ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign );
ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize );
ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name );
ELFIO_GET_ACCESS ( Elf64_Addr, address, header.sh_addr );
//------------------------------------------------------------------------------
Elf_Half
@ -127,6 +129,22 @@ class section_impl : public section
name = name_;
}
//------------------------------------------------------------------------------
void
set_address( Elf64_Addr value )
{
header.sh_addr = value;
header.sh_addr = (*convertor)( header.sh_addr );
is_address_set = true;
}
//------------------------------------------------------------------------------
bool
is_address_initialized()
{
return is_address_set;
}
//------------------------------------------------------------------------------
const char*
get_data() const
@ -225,7 +243,8 @@ class section_impl : public section
}
save_header( f, header_offset );
if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && get_size() != 0 && data != 0 ) {
if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL &&
get_size() != 0 && data != 0 ) {
save_data( f, data_offset );
}
}
@ -258,6 +277,7 @@ class section_impl : public section
mutable char* data;
Elf_Word data_size;
const endianess_convertor* convertor;
bool is_address_set;
};
} // namespace ELFIO

View File

@ -88,13 +88,13 @@ class segment_impl : public segment
//------------------------------------------------------------------------------
// Section info functions
ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type )
ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags )
ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align )
ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr )
ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr )
ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz )
ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz )
ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type );
ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags );
ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align );
ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr );
ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr );
ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz );
ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz );
//------------------------------------------------------------------------------
Elf_Half