mirror of
https://github.com/serge1/ELFIO.git
synced 2025-03-15 16:21:02 +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() +
|
||||
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",
|
||||
|
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
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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 ) );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user