Relocation entry endianness fix; Warnings elimination

This commit is contained in:
Serge Lamikhov-Center 2015-02-13 20:47:37 +02:00
parent ce2faaa00e
commit 8290078a64
4 changed files with 69 additions and 72 deletions

View File

@ -319,8 +319,8 @@ void checkExeAreEqual( std::string file_name1, std::string file_name2 )
Elf64_Off afterPHDR = file1.get_segments_offset() +
file1.get_segment_entry_size() * file1.segments.size();
if( file1.segments[i]->get_offset() < afterPHDR ) {
pdata1 = pdata1.substr(afterPHDR);
pdata2 = pdata2.substr(afterPHDR);
pdata1 = pdata1.substr( (unsigned int)afterPHDR );
pdata2 = pdata2.substr( (unsigned int)afterPHDR );
}
BOOST_CHECK_EQUAL_COLLECTIONS( pdata1.begin(), pdata1.end(),
@ -350,12 +350,12 @@ BOOST_AUTO_TEST_CASE( section_header_address_update )
{
elfio reader;
write_exe_i386( false, true, 0x0100 );
write_exe_i386( false, true, 0x08048100 );
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 );
BOOST_CHECK_EQUAL( sec->get_address(), 0x08048100 );
write_exe_i386( false, false, 0 );
@ -371,7 +371,7 @@ BOOST_AUTO_TEST_CASE( elfio_copy )
{
elfio e;
write_exe_i386( false, true, 0x0100 );
write_exe_i386( false, true, 0x08048100 );
e.load( "../elf_examples/write_exe_i386_32" );
Elf_Half num = e.sections.size();
@ -379,9 +379,6 @@ BOOST_AUTO_TEST_CASE( elfio_copy )
e.sections.add( "new" );
e.save( "../elf_examples/write_exe_i386_32" );
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" );
checkExeAreEqual( "../elf_examples/hello_arm_stripped",
"../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",
"../elf_examples/read_write_arm_elf32_input_copy" );
checkExeAreEqual( "../elf_examples/test_ppc",

View File

@ -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
of this software and associated documentation files (the "Software"), to deal
@ -156,7 +156,7 @@ class elfio
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 section table is variable and needs to be fixed
// before saving.
@ -165,7 +165,7 @@ class elfio
header->set_sections_num( sections.size() );
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() +
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->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 segEndOffset = segBaseOffset + seg->get_file_size();
Elf64_Off segVBaseAddr = seg->get_virtual_address();
@ -483,19 +483,19 @@ class elfio
}
//------------------------------------------------------------------------------
bool is_subsequence_of( segment* seg1, segment* 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>& sections2 = seg2->get_sections();
bool found = false;
if ( sections1.size() < sections2.size() ) {
found = std::includes( sections2.begin(), sections2.end(),
sections1.begin(), sections1.end() );
}
return found;
bool is_subsequence_of( segment* seg1, segment* 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>& sections2 = seg2->get_sections();
bool found = false;
if ( sections1.size() < sections2.size() ) {
found = std::includes( sections2.begin(), sections2.end(),
sections1.begin(), sections1.end() );
}
return found;
}
//------------------------------------------------------------------------------
@ -508,7 +508,7 @@ class elfio
std::copy( segments_.begin(), segments_.end(),
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;
for( size_t i = 0; i < worklist.size(); ++i ) {
if( i != nextSlot && worklist[i]->is_offset_initialized()
@ -573,40 +573,44 @@ class elfio
std::vector<bool> section_generated(sections.size(),false);
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
worklist = get_ordered_segments();
for ( unsigned int i = 0; i < worklist.size(); ++i ) {
Elf_Xword segment_memory = 0;
Elf_Xword segment_filesize = 0;
Elf_Xword seg_start_pos = current_file_pos;
segment* seg = worklist[i];
Elf_Xword seg_start_pos = current_file_pos;
segment* seg = worklist[i];
// special case: PHDR segments
// this segment contains the program headers but no sections
if( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
seg_start_pos = header->get_segments_offset();
segment_memory = segment_filesize =
header->get_segment_entry_size() * header->get_segments_num();
// special case:
// segments which start with the NULL section and have further sections
} else if ( seg->get_sections_num() > 1
&& sections[seg->get_section_index_at( 0 )]->get_type() == SHT_NULL ) {
// Special case: PHDR segment
// This segment contains the program headers but no sections
if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
seg_start_pos = header->get_segments_offset();
segment_memory = segment_filesize =
header->get_segment_entry_size() * header->get_segments_num();
}
// Special case:
// Segments which start with the NULL section and have further sections
else if ( seg->get_sections_num() > 1
&& sections[seg->get_section_index_at( 0 )]->get_type() == SHT_NULL ) {
seg_start_pos = 0;
if( seg->get_sections_num() )
if ( seg->get_sections_num() ) {
segment_memory = segment_filesize = current_file_pos;
// new segments with not generated sections
}
}
// New segments with not generated sections
// have to be aligned
} else if( seg->get_sections_num()
else if ( seg->get_sections_num()
&& !section_generated[seg->get_section_index_at( 0 )] ) {
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 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();
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();
}
@ -616,35 +620,36 @@ class elfio
section* sec = sections[ index ];
// the NULL section is always generated
if( SHT_NULL == sec->get_type()) {
section_generated[index] = true;
continue;
// The NULL section is always generated
if ( SHT_NULL == sec->get_type()) {
section_generated[index] = true;
continue;
}
Elf_Xword secAlign = 0;
// fix up the alignment
// Fix up the alignment
if ( !section_generated[index] && sec->is_address_initialized()
&& SHT_NOBITS != 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)
Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address();
Elf64_Off cur_offset = current_file_pos - seg_start_pos;
secAlign = req_offset - cur_offset;
} else if (!section_generated[index]) {
// if no address has been specified then only the section
secAlign = req_offset - cur_offset;
}
else if (!section_generated[index]) {
// If no address has been specified then only the section
// alignment constraint has to be matched
Elf64_Off error = current_file_pos % 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;
}
// determine the segment file and memory sizes
// special case .tbss section (NOBITS) in non TLS segment
//
// Determine the segment file and memory sizes
// Special case .tbss section (NOBITS) in non TLS segment
if ( (sec->get_flags() & SHF_ALLOC)
&& !( (sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS)
&& ( SHT_NOBITS == sec->get_type())) )
@ -652,14 +657,14 @@ class elfio
if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
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]) {
continue;
}
current_file_pos += secAlign;
// set the section addresses when missing
// Set the section addresses when missing
if ( !sec->is_address_initialized() )
sec->set_address( seg->get_virtual_address()
+ current_file_pos - seg_start_pos);
@ -683,7 +688,7 @@ class elfio
//------------------------------------------------------------------------------
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;
current_file_pos += ( 4 - alignmentError ) % 4;
header->set_sections_offset(current_file_pos);

View File

@ -604,7 +604,7 @@ class dump
<< " Name"
<< std::endl;
}
for ( Elf_Xword i = 0; i < sym_no; ++i ) {
for ( Elf_Half i = 0; i < sym_no; ++i ) {
std::string name;
Elf64_Addr value = 0;
Elf_Xword size = 0;
@ -727,7 +727,7 @@ class dump
if ( dyn_no > 0 ) {
out << "Dynamic section (" << sec->get_name() << ")" << 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 value = 0;
std::string str;

View File

@ -332,8 +332,10 @@ class relocation_section_accessor
const endianess_convertor& convertor = elf_file.get_convertor();
T entry;
entry.r_offset = convertor( offset );
entry.r_info = convertor( info );
entry.r_offset = offset;
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 ) );
}