mirror of
https://github.com/serge1/ELFIO.git
synced 2025-03-29 19:20:41 +00:00
Use unique_ptr instead of raw pointers
This commit is contained in:
parent
a3e2a1f07f
commit
af080f739e
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@ -10,8 +10,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/build/tests/ELFIOTest",
|
"program": "${workspaceFolder}/build/tests/ELFIOTest",
|
||||||
"args": [
|
"args": [
|
||||||
"-r",
|
"--gtest_filter=ELFIOTest.load32",
|
||||||
"short"
|
|
||||||
],
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}/build/tests",
|
"cwd": "${workspaceFolder}/build/tests",
|
||||||
|
319
elfio/elfio.hpp
319
elfio/elfio.hpp
@ -30,6 +30,7 @@ THE SOFTWARE.
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <elfio/elf_types.hpp>
|
#include <elfio/elf_types.hpp>
|
||||||
#include <elfio/elfio_version.hpp>
|
#include <elfio/elfio_version.hpp>
|
||||||
@ -63,19 +64,18 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
elfio() noexcept : sections( this ), segments( this )
|
elfio() noexcept : sections( this ), segments( this )
|
||||||
{
|
{
|
||||||
header = nullptr;
|
|
||||||
current_file_pos = 0;
|
|
||||||
create( ELFCLASS32, ELFDATA2LSB );
|
create( ELFCLASS32, ELFDATA2LSB );
|
||||||
}
|
}
|
||||||
|
|
||||||
elfio( elfio&& other ) noexcept : sections( this ), segments( this )
|
elfio( elfio&& other ) noexcept
|
||||||
|
: sections( this ), segments( this ),
|
||||||
|
current_file_pos( other.current_file_pos )
|
||||||
{
|
{
|
||||||
header = std::move( other.header );
|
header = std::move( other.header );
|
||||||
sections_ = std::move( other.sections_ );
|
sections_ = std::move( other.sections_ );
|
||||||
segments_ = std::move( other.segments_ );
|
segments_ = std::move( other.segments_ );
|
||||||
convertor = std::move( other.convertor );
|
convertor = std::move( other.convertor );
|
||||||
addr_translator = std::move( other.addr_translator );
|
addr_translator = std::move( other.addr_translator );
|
||||||
current_file_pos = std::move( other.current_file_pos );
|
|
||||||
|
|
||||||
other.header = nullptr;
|
other.header = nullptr;
|
||||||
other.sections_.clear();
|
other.sections_.clear();
|
||||||
@ -85,16 +85,15 @@ class elfio
|
|||||||
elfio& operator=( elfio&& other ) noexcept
|
elfio& operator=( elfio&& other ) noexcept
|
||||||
{
|
{
|
||||||
if ( this != &other ) {
|
if ( this != &other ) {
|
||||||
clean();
|
|
||||||
|
|
||||||
header = std::move( other.header );
|
header = std::move( other.header );
|
||||||
sections_ = std::move( other.sections_ );
|
sections_ = std::move( other.sections_ );
|
||||||
segments_ = std::move( other.segments_ );
|
segments_ = std::move( other.segments_ );
|
||||||
convertor = std::move( other.convertor );
|
convertor = std::move( other.convertor );
|
||||||
addr_translator = std::move( other.addr_translator );
|
addr_translator = std::move( other.addr_translator );
|
||||||
current_file_pos = std::move( other.current_file_pos );
|
current_file_pos = other.current_file_pos;
|
||||||
|
|
||||||
other.header = nullptr;
|
other.current_file_pos = 0;
|
||||||
|
other.header = nullptr;
|
||||||
other.sections_.clear();
|
other.sections_.clear();
|
||||||
other.segments_.clear();
|
other.segments_.clear();
|
||||||
}
|
}
|
||||||
@ -105,15 +104,14 @@ class elfio
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
elfio( const elfio& ) = delete;
|
elfio( const elfio& ) = delete;
|
||||||
elfio& operator=( const elfio& ) = delete;
|
elfio& operator=( const elfio& ) = delete;
|
||||||
|
~elfio() = default;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
~elfio() { clean(); }
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void create( unsigned char file_class, unsigned char encoding )
|
void create( unsigned char file_class, unsigned char encoding )
|
||||||
{
|
{
|
||||||
clean();
|
sections_.clear();
|
||||||
|
segments_.clear();
|
||||||
convertor.setup( encoding );
|
convertor.setup( encoding );
|
||||||
header = create_header( file_class, encoding );
|
header = create_header( file_class, encoding );
|
||||||
create_mandatory_sections();
|
create_mandatory_sections();
|
||||||
@ -139,7 +137,8 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool load( std::istream& stream )
|
bool load( std::istream& stream )
|
||||||
{
|
{
|
||||||
clean();
|
sections_.clear();
|
||||||
|
segments_.clear();
|
||||||
|
|
||||||
unsigned char e_ident[EI_NIDENT] = { 0 };
|
unsigned char e_ident[EI_NIDENT] = { 0 };
|
||||||
// Read ELF file signature
|
// Read ELF file signature
|
||||||
@ -361,45 +360,30 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
const section* find_prog_section_for_offset( Elf64_Off offset ) const
|
const section* find_prog_section_for_offset( Elf64_Off offset ) const
|
||||||
{
|
{
|
||||||
for ( auto* sec : sections ) {
|
for ( const auto& sec : sections ) {
|
||||||
if ( sec->get_type() == SHT_PROGBITS &&
|
if ( sec->get_type() == SHT_PROGBITS &&
|
||||||
is_offset_in_section( offset, sec ) ) {
|
is_offset_in_section( offset, sec.get() ) ) {
|
||||||
return sec;
|
return sec.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void clean()
|
std::unique_ptr<elf_header> create_header( unsigned char file_class,
|
||||||
|
unsigned char encoding )
|
||||||
{
|
{
|
||||||
delete header;
|
std::unique_ptr<elf_header> new_header;
|
||||||
header = nullptr;
|
|
||||||
|
|
||||||
for ( auto* it : sections_ ) {
|
|
||||||
delete it;
|
|
||||||
}
|
|
||||||
sections_.clear();
|
|
||||||
|
|
||||||
for ( auto* it : segments_ ) {
|
|
||||||
delete it;
|
|
||||||
}
|
|
||||||
segments_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
elf_header* create_header( unsigned char file_class,
|
|
||||||
unsigned char encoding )
|
|
||||||
{
|
|
||||||
elf_header* new_header = nullptr;
|
|
||||||
|
|
||||||
if ( file_class == ELFCLASS64 ) {
|
if ( file_class == ELFCLASS64 ) {
|
||||||
new_header = new elf_header_impl<Elf64_Ehdr>( &convertor, encoding,
|
new_header =
|
||||||
&addr_translator );
|
std::unique_ptr<elf_header>( new elf_header_impl<Elf64_Ehdr>(
|
||||||
|
&convertor, encoding, &addr_translator ) );
|
||||||
}
|
}
|
||||||
else if ( file_class == ELFCLASS32 ) {
|
else if ( file_class == ELFCLASS32 ) {
|
||||||
new_header = new elf_header_impl<Elf32_Ehdr>( &convertor, encoding,
|
new_header =
|
||||||
&addr_translator );
|
std::unique_ptr<elf_header>( new elf_header_impl<Elf32_Ehdr>(
|
||||||
|
&convertor, encoding, &addr_translator ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -492,7 +476,6 @@ class elfio
|
|||||||
sec->load( stream,
|
sec->load( stream,
|
||||||
static_cast<std::streamoff>( offset ) +
|
static_cast<std::streamoff>( offset ) +
|
||||||
static_cast<std::streampos>( i ) * entry_size );
|
static_cast<std::streampos>( i ) * entry_size );
|
||||||
sec->set_index( i );
|
|
||||||
// To mark that the section is not permitted to reassign address
|
// To mark that the section is not permitted to reassign address
|
||||||
// during layout calculation
|
// during layout calculation
|
||||||
sec->set_address( sec->get_address() );
|
sec->set_address( sec->get_address() );
|
||||||
@ -548,7 +531,6 @@ class elfio
|
|||||||
|
|
||||||
for ( Elf_Half i = 0; i < num; ++i ) {
|
for ( Elf_Half i = 0; i < num; ++i ) {
|
||||||
segment* seg = nullptr;
|
segment* seg = nullptr;
|
||||||
unsigned char file_class = header->get_class();
|
|
||||||
|
|
||||||
if ( file_class == ELFCLASS64 ) {
|
if ( file_class == ELFCLASS64 ) {
|
||||||
seg = new segment_impl<Elf64_Phdr>( &convertor,
|
seg = new segment_impl<Elf64_Phdr>( &convertor,
|
||||||
@ -578,7 +560,7 @@ class elfio
|
|||||||
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();
|
||||||
Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size();
|
Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size();
|
||||||
for ( auto* psec : sections ) {
|
for ( const auto& psec : sections ) {
|
||||||
// SHF_ALLOC sections are matched based on the virtual address
|
// SHF_ALLOC sections are matched based on the virtual address
|
||||||
// otherwise the file offset is matched
|
// otherwise the file offset is matched
|
||||||
if ( ( ( psec->get_flags() & SHF_ALLOC ) == SHF_ALLOC )
|
if ( ( ( psec->get_flags() & SHF_ALLOC ) == SHF_ALLOC )
|
||||||
@ -606,7 +588,7 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool save_sections( std::ostream& stream )
|
bool save_sections( std::ostream& stream )
|
||||||
{
|
{
|
||||||
for ( auto* sec : sections_ ) {
|
for ( const auto& sec : sections_ ) {
|
||||||
std::streampos headerPosition =
|
std::streampos headerPosition =
|
||||||
static_cast<std::streamoff>( header->get_sections_offset() ) +
|
static_cast<std::streamoff>( header->get_sections_offset() ) +
|
||||||
static_cast<std::streampos>(
|
static_cast<std::streampos>(
|
||||||
@ -621,7 +603,7 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool save_segments( std::ostream& stream )
|
bool save_segments( std::ostream& stream )
|
||||||
{
|
{
|
||||||
for ( auto* seg : segments_ ) {
|
for ( const auto& seg : segments_ ) {
|
||||||
std::streampos headerPosition =
|
std::streampos headerPosition =
|
||||||
static_cast<std::streamoff>( header->get_segments_offset() ) +
|
static_cast<std::streamoff>( header->get_segments_offset() ) +
|
||||||
static_cast<std::streampos>(
|
static_cast<std::streampos>(
|
||||||
@ -639,7 +621,7 @@ class elfio
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) {
|
for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) {
|
||||||
for ( unsigned int k = 0;
|
for ( Elf_Half k = 0;
|
||||||
!found && ( k < segments[j]->get_sections_num() ); ++k ) {
|
!found && ( k < segments[j]->get_sections_num() ); ++k ) {
|
||||||
found = segments[j]->get_section_index_at( k ) == section_index;
|
found = segments[j]->get_section_index_at( k ) == section_index;
|
||||||
}
|
}
|
||||||
@ -649,7 +631,7 @@ class elfio
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
static bool is_subsequence_of( segment* seg1, segment* seg2 )
|
static bool is_subsequence_of( const segment* seg1, const 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();
|
||||||
@ -671,8 +653,9 @@ class elfio
|
|||||||
std::deque<segment*> worklist;
|
std::deque<segment*> worklist;
|
||||||
|
|
||||||
res.reserve( segments.size() );
|
res.reserve( segments.size() );
|
||||||
std::copy( segments_.begin(), segments_.end(),
|
for ( const auto& seg : segments ) {
|
||||||
std::back_inserter( worklist ) );
|
worklist.emplace_back( seg.get() );
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
@ -714,7 +697,7 @@ class elfio
|
|||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < sections_.size(); ++i ) {
|
for ( unsigned int i = 0; i < sections_.size(); ++i ) {
|
||||||
if ( is_section_without_segment( i ) ) {
|
if ( is_section_without_segment( i ) ) {
|
||||||
section* sec = sections_[i];
|
const auto& sec = sections_[i];
|
||||||
|
|
||||||
Elf_Xword section_align = sec->get_addr_align();
|
Elf_Xword section_align = sec->get_addr_align();
|
||||||
if ( section_align > 1 &&
|
if ( section_align > 1 &&
|
||||||
@ -740,9 +723,9 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void calc_segment_alignment()
|
void calc_segment_alignment()
|
||||||
{
|
{
|
||||||
for ( auto* seg : segments_ ) {
|
for ( const auto& seg : segments_ ) {
|
||||||
for ( int i = 0; i < seg->get_sections_num(); ++i ) {
|
for ( Elf_Half i = 0; i < seg->get_sections_num(); ++i ) {
|
||||||
section* sect = sections_[seg->get_section_index_at( i )];
|
const auto& sect = sections_[seg->get_section_index_at( i )];
|
||||||
if ( sect->get_addr_align() > seg->get_align() ) {
|
if ( sect->get_addr_align() > seg->get_align() ) {
|
||||||
seg->set_align( sect->get_addr_align() );
|
seg->set_align( sect->get_addr_align() );
|
||||||
}
|
}
|
||||||
@ -798,87 +781,9 @@ class elfio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write segment's data
|
// Write segment's data
|
||||||
for ( auto j = 0; j < seg->get_sections_num(); ++j ) {
|
if ( !write_segment_data( seg, section_generated, segment_memory,
|
||||||
Elf_Half index = seg->get_section_index_at( j );
|
segment_filesize, seg_start_pos ) ) {
|
||||||
|
return false;
|
||||||
section* sec = sections[index];
|
|
||||||
|
|
||||||
// The NULL section is always generated
|
|
||||||
if ( SHT_NULL == sec->get_type() ) {
|
|
||||||
section_generated[index] = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Elf_Xword section_align = 0;
|
|
||||||
// Fix up the alignment
|
|
||||||
if ( !section_generated[index] &&
|
|
||||||
sec->is_address_initialized() &&
|
|
||||||
SHT_NOBITS != sec->get_type() &&
|
|
||||||
SHT_NULL != sec->get_type() && 0 != sec->get_size() ) {
|
|
||||||
// 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;
|
|
||||||
if ( req_offset < cur_offset ) {
|
|
||||||
// something has gone awfully wrong, abort!
|
|
||||||
// section_align would turn out negative, seeking backwards and overwriting previous data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
section_align = req_offset - cur_offset;
|
|
||||||
}
|
|
||||||
else if ( !section_generated[index] &&
|
|
||||||
!sec->is_address_initialized() ) {
|
|
||||||
// If no address has been specified then only the section
|
|
||||||
// alignment constraint has to be matched
|
|
||||||
Elf_Xword align = sec->get_addr_align();
|
|
||||||
if ( align == 0 ) {
|
|
||||||
align = 1;
|
|
||||||
}
|
|
||||||
Elf64_Off error = current_file_pos % align;
|
|
||||||
section_align = ( align - error ) % align;
|
|
||||||
}
|
|
||||||
else if ( section_generated[index] ) {
|
|
||||||
// Alignment for already generated sections
|
|
||||||
section_align =
|
|
||||||
sec->get_offset() - seg_start_pos - segment_filesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the segment file and memory sizes
|
|
||||||
// Special case .tbss section (NOBITS) in non TLS segment
|
|
||||||
if ( ( ( sec->get_flags() & SHF_ALLOC ) == SHF_ALLOC ) &&
|
|
||||||
!( ( ( sec->get_flags() & SHF_TLS ) == SHF_TLS ) &&
|
|
||||||
( seg->get_type() != PT_TLS ) &&
|
|
||||||
( SHT_NOBITS == sec->get_type() ) ) ) {
|
|
||||||
segment_memory += sec->get_size() + section_align;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( SHT_NOBITS != sec->get_type() ) {
|
|
||||||
segment_filesize += sec->get_size() + section_align;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing to be done when generating nested segments
|
|
||||||
if ( section_generated[index] ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_file_pos += section_align;
|
|
||||||
|
|
||||||
// Set the section addresses when missing
|
|
||||||
if ( !sec->is_address_initialized() ) {
|
|
||||||
sec->set_address( seg->get_virtual_address() +
|
|
||||||
current_file_pos - seg_start_pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 != sec->get_index() ) {
|
|
||||||
sec->set_offset( current_file_pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( SHT_NOBITS != sec->get_type() ) {
|
|
||||||
current_file_pos += sec->get_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
section_generated[index] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
seg->set_file_size( segment_filesize );
|
seg->set_file_size( segment_filesize );
|
||||||
@ -907,6 +812,98 @@ class elfio
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool write_segment_data( const segment* seg,
|
||||||
|
std::vector<bool>& section_generated,
|
||||||
|
Elf_Xword& segment_memory,
|
||||||
|
Elf_Xword& segment_filesize,
|
||||||
|
const Elf_Xword& seg_start_pos )
|
||||||
|
{
|
||||||
|
for ( Elf_Half j = 0; j < seg->get_sections_num(); ++j ) {
|
||||||
|
Elf_Half index = seg->get_section_index_at( j );
|
||||||
|
|
||||||
|
section* sec = sections[index];
|
||||||
|
|
||||||
|
// The NULL section is always generated
|
||||||
|
if ( SHT_NULL == sec->get_type() ) {
|
||||||
|
section_generated[index] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Elf_Xword section_align = 0;
|
||||||
|
// Fix up the alignment
|
||||||
|
if ( !section_generated[index] && sec->is_address_initialized() &&
|
||||||
|
SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() &&
|
||||||
|
0 != sec->get_size() ) {
|
||||||
|
// 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;
|
||||||
|
if ( req_offset < cur_offset ) {
|
||||||
|
// something has gone awfully wrong, abort!
|
||||||
|
// section_align would turn out negative, seeking backwards and overwriting previous data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
section_align = req_offset - cur_offset;
|
||||||
|
}
|
||||||
|
else if ( !section_generated[index] &&
|
||||||
|
!sec->is_address_initialized() ) {
|
||||||
|
// If no address has been specified then only the section
|
||||||
|
// alignment constraint has to be matched
|
||||||
|
Elf_Xword align = sec->get_addr_align();
|
||||||
|
if ( align == 0 ) {
|
||||||
|
align = 1;
|
||||||
|
}
|
||||||
|
Elf64_Off error = current_file_pos % align;
|
||||||
|
section_align = ( align - error ) % align;
|
||||||
|
}
|
||||||
|
else if ( section_generated[index] ) {
|
||||||
|
// Alignment for already generated sections
|
||||||
|
section_align =
|
||||||
|
sec->get_offset() - seg_start_pos - segment_filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the segment file and memory sizes
|
||||||
|
// Special case .tbss section (NOBITS) in non TLS segment
|
||||||
|
if ( ( ( sec->get_flags() & SHF_ALLOC ) == SHF_ALLOC ) &&
|
||||||
|
!( ( ( sec->get_flags() & SHF_TLS ) == SHF_TLS ) &&
|
||||||
|
( seg->get_type() != PT_TLS ) &&
|
||||||
|
( SHT_NOBITS == sec->get_type() ) ) ) {
|
||||||
|
segment_memory += sec->get_size() + section_align;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( SHT_NOBITS != sec->get_type() ) {
|
||||||
|
segment_filesize += sec->get_size() + section_align;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing to be done when generating nested segments
|
||||||
|
if ( section_generated[index] ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_file_pos += section_align;
|
||||||
|
|
||||||
|
// Set the section addresses when missing
|
||||||
|
if ( !sec->is_address_initialized() ) {
|
||||||
|
sec->set_address( seg->get_virtual_address() +
|
||||||
|
current_file_pos - seg_start_pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 0 != sec->get_index() ) {
|
||||||
|
sec->set_offset( current_file_pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( SHT_NOBITS != sec->get_type() ) {
|
||||||
|
current_file_pos += sec->get_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
section_generated[index] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
public:
|
public:
|
||||||
friend class Sections;
|
friend class Sections;
|
||||||
@ -928,7 +925,7 @@ class elfio
|
|||||||
section* sec = nullptr;
|
section* sec = nullptr;
|
||||||
|
|
||||||
if ( index < parent->sections_.size() ) {
|
if ( index < parent->sections_.size() ) {
|
||||||
sec = parent->sections_[index];
|
sec = parent->sections_[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
return sec;
|
return sec;
|
||||||
@ -939,9 +936,9 @@ class elfio
|
|||||||
{
|
{
|
||||||
section* sec = nullptr;
|
section* sec = nullptr;
|
||||||
|
|
||||||
for ( auto* it : parent->sections_ ) {
|
for ( const auto& it : parent->sections_ ) {
|
||||||
if ( it->get_name() == name ) {
|
if ( it->get_name() == name ) {
|
||||||
sec = it;
|
sec = it.get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -956,7 +953,7 @@ class elfio
|
|||||||
new_section->set_name( name );
|
new_section->set_name( name );
|
||||||
|
|
||||||
Elf_Half str_index = parent->get_section_name_str_index();
|
Elf_Half str_index = parent->get_section_name_str_index();
|
||||||
section* string_table( parent->sections_[str_index] );
|
section* string_table( parent->sections_[str_index].get() );
|
||||||
string_section_accessor str_writer( string_table );
|
string_section_accessor str_writer( string_table );
|
||||||
Elf_Word pos = str_writer.add_string( name );
|
Elf_Word pos = str_writer.add_string( name );
|
||||||
new_section->set_name_string_offset( pos );
|
new_section->set_name_string_offset( pos );
|
||||||
@ -965,25 +962,25 @@ class elfio
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<section*>::iterator begin()
|
std::vector<std::unique_ptr<section>>::iterator begin()
|
||||||
{
|
{
|
||||||
return parent->sections_.begin();
|
return parent->sections_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<section*>::iterator end()
|
std::vector<std::unique_ptr<section>>::iterator end()
|
||||||
{
|
{
|
||||||
return parent->sections_.end();
|
return parent->sections_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<section*>::const_iterator begin() const
|
std::vector<std::unique_ptr<section>>::const_iterator begin() const
|
||||||
{
|
{
|
||||||
return parent->sections_.cbegin();
|
return parent->sections_.cbegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<section*>::const_iterator end() const
|
std::vector<std::unique_ptr<section>>::const_iterator end() const
|
||||||
{
|
{
|
||||||
return parent->sections_.cend();
|
return parent->sections_.cend();
|
||||||
}
|
}
|
||||||
@ -991,7 +988,8 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
private:
|
private:
|
||||||
elfio* parent;
|
elfio* parent;
|
||||||
} sections;
|
};
|
||||||
|
Sections sections;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
friend class Segments;
|
friend class Segments;
|
||||||
@ -1010,32 +1008,32 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
segment* operator[]( unsigned int index ) const
|
segment* operator[]( unsigned int index ) const
|
||||||
{
|
{
|
||||||
return parent->segments_[index];
|
return parent->segments_[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
segment* add() { return parent->create_segment(); }
|
segment* add() { return parent->create_segment(); }
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<segment*>::iterator begin()
|
std::vector<std::unique_ptr<segment>>::iterator begin()
|
||||||
{
|
{
|
||||||
return parent->segments_.begin();
|
return parent->segments_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<segment*>::iterator end()
|
std::vector<std::unique_ptr<segment>>::iterator end()
|
||||||
{
|
{
|
||||||
return parent->segments_.end();
|
return parent->segments_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<segment*>::const_iterator begin() const
|
std::vector<std::unique_ptr<segment>>::const_iterator begin() const
|
||||||
{
|
{
|
||||||
return parent->segments_.cbegin();
|
return parent->segments_.cbegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
std::vector<segment*>::const_iterator end() const
|
std::vector<std::unique_ptr<segment>>::const_iterator end() const
|
||||||
{
|
{
|
||||||
return parent->segments_.cend();
|
return parent->segments_.cend();
|
||||||
}
|
}
|
||||||
@ -1043,17 +1041,18 @@ class elfio
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
private:
|
private:
|
||||||
elfio* parent;
|
elfio* parent;
|
||||||
} segments;
|
};
|
||||||
|
Segments segments;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
private:
|
private:
|
||||||
elf_header* header;
|
std::unique_ptr<elf_header> header = nullptr;
|
||||||
std::vector<section*> sections_;
|
std::vector<std::unique_ptr<section>> sections_;
|
||||||
std::vector<segment*> segments_;
|
std::vector<std::unique_ptr<segment>> segments_;
|
||||||
endianess_convertor convertor;
|
endianess_convertor convertor;
|
||||||
address_translator addr_translator;
|
address_translator addr_translator;
|
||||||
|
|
||||||
Elf_Xword current_file_pos;
|
Elf_Xword current_file_pos = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ELFIO
|
} // namespace ELFIO
|
||||||
|
@ -108,7 +108,7 @@ template <class T> class section_impl : public section
|
|||||||
std::string get_name() const override { return name; }
|
std::string get_name() const override { return name; }
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void set_name( std::string name ) override { this->name = name; }
|
void set_name( std::string name_prm ) override { this->name = name_prm; }
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void set_address( Elf64_Addr value ) override
|
void set_address( Elf64_Addr value ) override
|
||||||
@ -207,7 +207,7 @@ template <class T> class section_impl : public section
|
|||||||
'\0' );
|
'\0' );
|
||||||
|
|
||||||
if ( translator->empty() ) {
|
if ( translator->empty() ) {
|
||||||
stream.seekg( 0, stream.end );
|
stream.seekg( 0, std::istream::end );
|
||||||
set_stream_size( size_t( stream.tellg() ) );
|
set_stream_size( size_t( stream.tellg() ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -51,7 +51,7 @@ using namespace ELFIO;
|
|||||||
|
|
||||||
void overwrite_data( const std::string& filename,
|
void overwrite_data( const std::string& filename,
|
||||||
Elf64_Off offset,
|
Elf64_Off offset,
|
||||||
std::string& str )
|
const std::string& str )
|
||||||
{
|
{
|
||||||
std::ofstream file( filename,
|
std::ofstream file( filename,
|
||||||
std::ios::in | std::ios::out | std::ios::binary );
|
std::ios::in | std::ios::out | std::ios::binary );
|
||||||
@ -92,12 +92,11 @@ int main( int argc, char** argv )
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( auto section = reader.sections.begin();
|
for ( const auto& section : reader.sections ) {
|
||||||
section != reader.sections.end(); ++section ) {
|
if ( section->get_type() == SHT_STRTAB &&
|
||||||
if ( ( *section )->get_type() == SHT_STRTAB &&
|
std::string( section->get_name() ) ==
|
||||||
std::string( ( *section )->get_name() ) ==
|
|
||||||
std::string( ".strtab" ) ) {
|
std::string( ".strtab" ) ) {
|
||||||
process_string_table( *section, filename );
|
process_string_table( section.get(), filename );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -224,6 +224,12 @@ TEST( ELFIOTest, load32 )
|
|||||||
sec = reader.sections[27];
|
sec = reader.sections[27];
|
||||||
checkSection( sec, 27, ".strtab", SHT_STRTAB, 0, 0x0, 0x259, 0, 0, 1, 0 );
|
checkSection( sec, 27, ".strtab", SHT_STRTAB, 0, 0x0, 0x259, 0, 0, 1, 0 );
|
||||||
|
|
||||||
|
for ( Elf_Half i = 0; i < reader.sections.size(); ++i )
|
||||||
|
{
|
||||||
|
sec = reader.sections[i];
|
||||||
|
EXPECT_EQ( sec->get_index(), i );
|
||||||
|
}
|
||||||
|
|
||||||
const section* sec1 = reader.sections[".strtab"];
|
const section* sec1 = reader.sections[".strtab"];
|
||||||
EXPECT_EQ( sec->get_index(), sec1->get_index() );
|
EXPECT_EQ( sec->get_index(), sec1->get_index() );
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user