mirror of
https://github.com/serge1/ELFIO.git
synced 2025-03-16 19:21:07 +00:00
Relocation entry endianness fix; Warnings elimination
This commit is contained in:
parent
ce2faaa00e
commit
8290078a64
@ -319,8 +319,8 @@ void checkExeAreEqual( std::string file_name1, std::string file_name2 )
|
|||||||
Elf64_Off afterPHDR = file1.get_segments_offset() +
|
Elf64_Off afterPHDR = file1.get_segments_offset() +
|
||||||
file1.get_segment_entry_size() * file1.segments.size();
|
file1.get_segment_entry_size() * file1.segments.size();
|
||||||
if( file1.segments[i]->get_offset() < afterPHDR ) {
|
if( file1.segments[i]->get_offset() < afterPHDR ) {
|
||||||
pdata1 = pdata1.substr(afterPHDR);
|
pdata1 = pdata1.substr( (unsigned int)afterPHDR );
|
||||||
pdata2 = pdata2.substr(afterPHDR);
|
pdata2 = pdata2.substr( (unsigned int)afterPHDR );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL_COLLECTIONS( pdata1.begin(), pdata1.end(),
|
BOOST_CHECK_EQUAL_COLLECTIONS( pdata1.begin(), pdata1.end(),
|
||||||
@ -350,12 +350,12 @@ BOOST_AUTO_TEST_CASE( section_header_address_update )
|
|||||||
{
|
{
|
||||||
elfio reader;
|
elfio reader;
|
||||||
|
|
||||||
write_exe_i386( false, true, 0x0100 );
|
write_exe_i386( false, true, 0x08048100 );
|
||||||
|
|
||||||
reader.load( "../elf_examples/write_exe_i386_32" );
|
reader.load( "../elf_examples/write_exe_i386_32" );
|
||||||
section* sec = reader.sections[".text"];
|
section* sec = reader.sections[".text"];
|
||||||
BOOST_REQUIRE_NE( sec, (section*)0 );
|
BOOST_REQUIRE_NE( sec, (section*)0 );
|
||||||
BOOST_CHECK_EQUAL( sec->get_address(), 0x00000100 );
|
BOOST_CHECK_EQUAL( sec->get_address(), 0x08048100 );
|
||||||
|
|
||||||
write_exe_i386( false, false, 0 );
|
write_exe_i386( false, false, 0 );
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ BOOST_AUTO_TEST_CASE( elfio_copy )
|
|||||||
{
|
{
|
||||||
elfio e;
|
elfio e;
|
||||||
|
|
||||||
write_exe_i386( false, true, 0x0100 );
|
write_exe_i386( false, true, 0x08048100 );
|
||||||
|
|
||||||
e.load( "../elf_examples/write_exe_i386_32" );
|
e.load( "../elf_examples/write_exe_i386_32" );
|
||||||
Elf_Half num = e.sections.size();
|
Elf_Half num = e.sections.size();
|
||||||
@ -379,9 +379,6 @@ BOOST_AUTO_TEST_CASE( elfio_copy )
|
|||||||
e.sections.add( "new" );
|
e.sections.add( "new" );
|
||||||
e.save( "../elf_examples/write_exe_i386_32" );
|
e.save( "../elf_examples/write_exe_i386_32" );
|
||||||
BOOST_CHECK_EQUAL( num + 1, e.sections.size() );
|
BOOST_CHECK_EQUAL( num + 1, e.sections.size() );
|
||||||
|
|
||||||
// Just return back the overwritten file
|
|
||||||
write_exe_i386( false, false, 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -418,13 +415,6 @@ BOOST_AUTO_TEST_CASE( elf_exe_copy_32 )
|
|||||||
"../elf_examples/hello_arm_copy" );
|
"../elf_examples/hello_arm_copy" );
|
||||||
checkExeAreEqual( "../elf_examples/hello_arm_stripped",
|
checkExeAreEqual( "../elf_examples/hello_arm_stripped",
|
||||||
"../elf_examples/hello_arm_stripped_copy" );
|
"../elf_examples/hello_arm_stripped_copy" );
|
||||||
|
|
||||||
// The last segment (GNU_RELRO) is bigger than necessary.
|
|
||||||
// I don't see why but it contains a few bits of the .got.plt section.
|
|
||||||
// -> load, store, compare cycle fails
|
|
||||||
// checkExeAreEqual( "../elf_examples/main32",
|
|
||||||
// "../elf_examples/main32_copy" );
|
|
||||||
|
|
||||||
checkExeAreEqual( "../elf_examples/read_write_arm_elf32_input",
|
checkExeAreEqual( "../elf_examples/read_write_arm_elf32_input",
|
||||||
"../elf_examples/read_write_arm_elf32_input_copy" );
|
"../elf_examples/read_write_arm_elf32_input_copy" );
|
||||||
checkExeAreEqual( "../elf_examples/test_ppc",
|
checkExeAreEqual( "../elf_examples/test_ppc",
|
||||||
|
111
elfio/elfio.hpp
111
elfio/elfio.hpp
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (C) 2001-2012 by Serge Lamikhov-Center
|
Copyright (C) 2001-2015 by Serge Lamikhov-Center
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -156,7 +156,7 @@ class elfio
|
|||||||
|
|
||||||
bool is_still_good = true;
|
bool is_still_good = true;
|
||||||
|
|
||||||
// define layout specific header fields
|
// Define layout specific header fields
|
||||||
// The position of the segment table is fixed after the header.
|
// The position of the segment table is fixed after the header.
|
||||||
// The position of the section table is variable and needs to be fixed
|
// The position of the section table is variable and needs to be fixed
|
||||||
// before saving.
|
// before saving.
|
||||||
@ -165,7 +165,7 @@ class elfio
|
|||||||
header->set_sections_num( sections.size() );
|
header->set_sections_num( sections.size() );
|
||||||
header->set_sections_offset( 0 );
|
header->set_sections_offset( 0 );
|
||||||
|
|
||||||
// layout the first section right after the segment table
|
// Layout the first section right after the segment table
|
||||||
current_file_pos = header->get_header_size() +
|
current_file_pos = header->get_header_size() +
|
||||||
header->get_segment_entry_size() * header->get_segments_num();
|
header->get_segment_entry_size() * header->get_segments_num();
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ class elfio
|
|||||||
seg->load( stream, (std::streamoff)offset + i * entry_size );
|
seg->load( stream, (std::streamoff)offset + i * entry_size );
|
||||||
seg->set_index( i );
|
seg->set_index( i );
|
||||||
|
|
||||||
// add sections to the segments (similar to readelfs algorithm)
|
// Add sections to the segments (similar to readelfs algorithm)
|
||||||
Elf64_Off segBaseOffset = seg->get_offset();
|
Elf64_Off segBaseOffset = seg->get_offset();
|
||||||
Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size();
|
Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size();
|
||||||
Elf64_Off segVBaseAddr = seg->get_virtual_address();
|
Elf64_Off segVBaseAddr = seg->get_virtual_address();
|
||||||
@ -483,19 +483,19 @@ class elfio
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool is_subsequence_of( segment* seg1, segment* seg2 )
|
bool is_subsequence_of( segment* seg1, segment* seg2 )
|
||||||
{
|
{
|
||||||
// Return 'true' if sections of seg1 are a subset of sections in seg2
|
// Return 'true' if sections of seg1 are a subset of sections in seg2
|
||||||
const std::vector<Elf_Half>& sections1 = seg1->get_sections();
|
const std::vector<Elf_Half>& sections1 = seg1->get_sections();
|
||||||
const std::vector<Elf_Half>& sections2 = seg2->get_sections();
|
const std::vector<Elf_Half>& sections2 = seg2->get_sections();
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if ( sections1.size() < sections2.size() ) {
|
if ( sections1.size() < sections2.size() ) {
|
||||||
found = std::includes( sections2.begin(), sections2.end(),
|
found = std::includes( sections2.begin(), sections2.end(),
|
||||||
sections1.begin(), sections1.end() );
|
sections1.begin(), sections1.end() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -508,7 +508,7 @@ class elfio
|
|||||||
std::copy( segments_.begin(), segments_.end(),
|
std::copy( segments_.begin(), segments_.end(),
|
||||||
std::back_inserter( worklist )) ;
|
std::back_inserter( worklist )) ;
|
||||||
|
|
||||||
// bring the segments which start at address 0 to the front
|
// Bring the segments which start at address 0 to the front
|
||||||
size_t nextSlot = 0;
|
size_t nextSlot = 0;
|
||||||
for( size_t i = 0; i < worklist.size(); ++i ) {
|
for( size_t i = 0; i < worklist.size(); ++i ) {
|
||||||
if( i != nextSlot && worklist[i]->is_offset_initialized()
|
if( i != nextSlot && worklist[i]->is_offset_initialized()
|
||||||
@ -573,40 +573,44 @@ class elfio
|
|||||||
std::vector<bool> section_generated(sections.size(),false);
|
std::vector<bool> section_generated(sections.size(),false);
|
||||||
std::vector<Elf_Xword> section_alignment(sections.size(),0);
|
std::vector<Elf_Xword> section_alignment(sections.size(),0);
|
||||||
|
|
||||||
// get segments in a order in where segments which contain a
|
// Get segments in a order in where segments which contain a
|
||||||
// sub sequence of other segments are located at the end
|
// sub sequence of other segments are located at the end
|
||||||
worklist = get_ordered_segments();
|
worklist = get_ordered_segments();
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < worklist.size(); ++i ) {
|
for ( unsigned int i = 0; i < worklist.size(); ++i ) {
|
||||||
Elf_Xword segment_memory = 0;
|
Elf_Xword segment_memory = 0;
|
||||||
Elf_Xword segment_filesize = 0;
|
Elf_Xword segment_filesize = 0;
|
||||||
Elf_Xword seg_start_pos = current_file_pos;
|
Elf_Xword seg_start_pos = current_file_pos;
|
||||||
segment* seg = worklist[i];
|
segment* seg = worklist[i];
|
||||||
|
|
||||||
// special case: PHDR segments
|
// Special case: PHDR segment
|
||||||
// this segment contains the program headers but no sections
|
// This segment contains the program headers but no sections
|
||||||
if( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
|
if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
|
||||||
seg_start_pos = header->get_segments_offset();
|
seg_start_pos = header->get_segments_offset();
|
||||||
segment_memory = segment_filesize =
|
segment_memory = segment_filesize =
|
||||||
header->get_segment_entry_size() * header->get_segments_num();
|
header->get_segment_entry_size() * header->get_segments_num();
|
||||||
// special case:
|
}
|
||||||
// segments which start with the NULL section and have further sections
|
// Special case:
|
||||||
} else if ( seg->get_sections_num() > 1
|
// Segments which start with the NULL section and have further sections
|
||||||
&& sections[seg->get_section_index_at( 0 )]->get_type() == SHT_NULL ) {
|
else if ( seg->get_sections_num() > 1
|
||||||
|
&& sections[seg->get_section_index_at( 0 )]->get_type() == SHT_NULL ) {
|
||||||
seg_start_pos = 0;
|
seg_start_pos = 0;
|
||||||
if( seg->get_sections_num() )
|
if ( seg->get_sections_num() ) {
|
||||||
segment_memory = segment_filesize = current_file_pos;
|
segment_memory = segment_filesize = current_file_pos;
|
||||||
// new segments with not generated sections
|
}
|
||||||
|
}
|
||||||
|
// New segments with not generated sections
|
||||||
// have to be aligned
|
// have to be aligned
|
||||||
} else if( seg->get_sections_num()
|
else if ( seg->get_sections_num()
|
||||||
&& !section_generated[seg->get_section_index_at( 0 )] ) {
|
&& !section_generated[seg->get_section_index_at( 0 )] ) {
|
||||||
Elf64_Off cur_page_alignment = current_file_pos % seg->get_align();
|
Elf64_Off cur_page_alignment = current_file_pos % seg->get_align();
|
||||||
Elf64_Off req_page_alignment = seg->get_virtual_address() % seg->get_align();
|
Elf64_Off req_page_alignment = seg->get_virtual_address() % seg->get_align();
|
||||||
Elf64_Off error = req_page_alignment - cur_page_alignment;
|
Elf64_Off error = req_page_alignment - cur_page_alignment;
|
||||||
|
|
||||||
current_file_pos += ( seg->get_align() + error ) % seg->get_align();
|
current_file_pos += ( seg->get_align() + error ) % seg->get_align();
|
||||||
seg_start_pos = current_file_pos;
|
seg_start_pos = current_file_pos;
|
||||||
} else if(seg->get_sections_num()) {
|
}
|
||||||
|
else if ( seg->get_sections_num() ) {
|
||||||
seg_start_pos = sections[seg->get_section_index_at( 0 )]->get_offset();
|
seg_start_pos = sections[seg->get_section_index_at( 0 )]->get_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,35 +620,36 @@ class elfio
|
|||||||
|
|
||||||
section* sec = sections[ index ];
|
section* sec = sections[ index ];
|
||||||
|
|
||||||
// the NULL section is always generated
|
// The NULL section is always generated
|
||||||
if( SHT_NULL == sec->get_type()) {
|
if ( SHT_NULL == sec->get_type()) {
|
||||||
section_generated[index] = true;
|
section_generated[index] = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf_Xword secAlign = 0;
|
Elf_Xword secAlign = 0;
|
||||||
// fix up the alignment
|
// Fix up the alignment
|
||||||
if ( !section_generated[index] && sec->is_address_initialized()
|
if ( !section_generated[index] && sec->is_address_initialized()
|
||||||
&& SHT_NOBITS != sec->get_type()
|
&& SHT_NOBITS != sec->get_type()
|
||||||
&& SHT_NULL != sec->get_type() ) {
|
&& SHT_NULL != sec->get_type() ) {
|
||||||
// align the sections based on the virtual addresses
|
// Align the sections based on the virtual addresses
|
||||||
// when possible (this is what matters for execution)
|
// when possible (this is what matters for execution)
|
||||||
Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address();
|
Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address();
|
||||||
Elf64_Off cur_offset = current_file_pos - seg_start_pos;
|
Elf64_Off cur_offset = current_file_pos - seg_start_pos;
|
||||||
secAlign = req_offset - cur_offset;
|
secAlign = req_offset - cur_offset;
|
||||||
} else if (!section_generated[index]) {
|
}
|
||||||
// if no address has been specified then only the section
|
else if (!section_generated[index]) {
|
||||||
|
// If no address has been specified then only the section
|
||||||
// alignment constraint has to be matched
|
// alignment constraint has to be matched
|
||||||
Elf64_Off error = current_file_pos % sec->get_addr_align();
|
Elf64_Off error = current_file_pos % sec->get_addr_align();
|
||||||
secAlign = ( sec->get_addr_align() - error ) % sec->get_addr_align();
|
secAlign = ( sec->get_addr_align() - error ) % sec->get_addr_align();
|
||||||
} else {
|
}
|
||||||
// alignment for already generated sections
|
else {
|
||||||
|
// Alignment for already generated sections
|
||||||
secAlign = sec->get_offset() - seg_start_pos - segment_filesize;
|
secAlign = sec->get_offset() - seg_start_pos - segment_filesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine the segment file and memory sizes
|
// Determine the segment file and memory sizes
|
||||||
// special case .tbss section (NOBITS) in non TLS segment
|
// Special case .tbss section (NOBITS) in non TLS segment
|
||||||
//
|
|
||||||
if ( (sec->get_flags() & SHF_ALLOC)
|
if ( (sec->get_flags() & SHF_ALLOC)
|
||||||
&& !( (sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS)
|
&& !( (sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS)
|
||||||
&& ( SHT_NOBITS == sec->get_type())) )
|
&& ( SHT_NOBITS == sec->get_type())) )
|
||||||
@ -652,14 +657,14 @@ class elfio
|
|||||||
if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
|
if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
|
||||||
segment_filesize += sec->get_size() + secAlign;
|
segment_filesize += sec->get_size() + secAlign;
|
||||||
|
|
||||||
// nothing to be done when generating nested segments
|
// Nothing to be done when generating nested segments
|
||||||
if(section_generated[index]) {
|
if(section_generated[index]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_file_pos += secAlign;
|
current_file_pos += secAlign;
|
||||||
|
|
||||||
// set the section addresses when missing
|
// Set the section addresses when missing
|
||||||
if ( !sec->is_address_initialized() )
|
if ( !sec->is_address_initialized() )
|
||||||
sec->set_address( seg->get_virtual_address()
|
sec->set_address( seg->get_virtual_address()
|
||||||
+ current_file_pos - seg_start_pos);
|
+ current_file_pos - seg_start_pos);
|
||||||
@ -683,7 +688,7 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool layout_section_table()
|
bool layout_section_table()
|
||||||
{
|
{
|
||||||
// simply place the section table at the end for now
|
// Simply place the section table at the end for now
|
||||||
Elf64_Off alignmentError = current_file_pos % 4;
|
Elf64_Off alignmentError = current_file_pos % 4;
|
||||||
current_file_pos += ( 4 - alignmentError ) % 4;
|
current_file_pos += ( 4 - alignmentError ) % 4;
|
||||||
header->set_sections_offset(current_file_pos);
|
header->set_sections_offset(current_file_pos);
|
||||||
|
@ -604,7 +604,7 @@ class dump
|
|||||||
<< " Name"
|
<< " Name"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
for ( Elf_Xword i = 0; i < sym_no; ++i ) {
|
for ( Elf_Half i = 0; i < sym_no; ++i ) {
|
||||||
std::string name;
|
std::string name;
|
||||||
Elf64_Addr value = 0;
|
Elf64_Addr value = 0;
|
||||||
Elf_Xword size = 0;
|
Elf_Xword size = 0;
|
||||||
@ -727,7 +727,7 @@ class dump
|
|||||||
if ( dyn_no > 0 ) {
|
if ( dyn_no > 0 ) {
|
||||||
out << "Dynamic section (" << sec->get_name() << ")" << std::endl;
|
out << "Dynamic section (" << sec->get_name() << ")" << std::endl;
|
||||||
out << "[ Nr ] Tag Name/Value" << std::endl;
|
out << "[ Nr ] Tag Name/Value" << std::endl;
|
||||||
for ( Elf_Xword i = 0; i < dyn_no; ++i ) {
|
for ( int i = 0; i < dyn_no; ++i ) {
|
||||||
Elf_Xword tag = 0;
|
Elf_Xword tag = 0;
|
||||||
Elf_Xword value = 0;
|
Elf_Xword value = 0;
|
||||||
std::string str;
|
std::string str;
|
||||||
|
@ -332,8 +332,10 @@ class relocation_section_accessor
|
|||||||
const endianess_convertor& convertor = elf_file.get_convertor();
|
const endianess_convertor& convertor = elf_file.get_convertor();
|
||||||
|
|
||||||
T entry;
|
T entry;
|
||||||
entry.r_offset = convertor( offset );
|
entry.r_offset = offset;
|
||||||
entry.r_info = convertor( info );
|
entry.r_info = info;
|
||||||
|
entry.r_offset = convertor( entry.r_offset );
|
||||||
|
entry.r_info = convertor( entry.r_info );
|
||||||
|
|
||||||
relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
|
relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user