mirror of
https://github.com/serge1/ELFIO.git
synced 2024-12-26 09:14:29 +00:00
Implement free_data() for sections too
free_data() has no effect if is_lazy was not set
This commit is contained in:
parent
0399b9f8df
commit
c86883b906
BIN
doc/elfio.docx
BIN
doc/elfio.docx
Binary file not shown.
BIN
doc/elfio.pdf
BIN
doc/elfio.pdf
Binary file not shown.
@ -51,6 +51,7 @@ class section
|
||||
ELFIO_GET_ACCESS_DECL( Elf64_Off, offset );
|
||||
|
||||
virtual const char* get_data() const = 0;
|
||||
virtual void free_data() const = 0;
|
||||
virtual void set_data( const char* raw_data, Elf_Word size ) = 0;
|
||||
virtual void set_data( const std::string& data ) = 0;
|
||||
virtual void append_data( const char* raw_data, Elf_Word size ) = 0;
|
||||
@ -123,12 +124,21 @@ template <class T> class section_impl : public section
|
||||
//------------------------------------------------------------------------------
|
||||
const char* get_data() const override
|
||||
{
|
||||
if ( is_lazy ) {
|
||||
if ( !is_loaded ) {
|
||||
load_data();
|
||||
}
|
||||
return data.get();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void free_data() const override
|
||||
{
|
||||
if ( is_lazy ) {
|
||||
data.reset( nullptr );
|
||||
is_loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void set_data( const char* raw_data, Elf_Word size ) override
|
||||
{
|
||||
@ -248,15 +258,14 @@ template <class T> class section_impl : public section
|
||||
stream.seekg( ( *translator )[header_offset] );
|
||||
stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
|
||||
|
||||
if ( !is_lazy || is_compressed() ) {
|
||||
|
||||
if ( !( is_lazy || is_loaded ) ) {
|
||||
bool ret = load_data();
|
||||
|
||||
if ( is_compressed() ) {
|
||||
Elf_Xword size = get_size();
|
||||
Elf_Xword uncompressed_size = 0;
|
||||
auto decompressed_data = compression->inflate(
|
||||
data.get(), convertor, size, uncompressed_size );
|
||||
data.get(), convertor, size, uncompressed_size );
|
||||
if ( decompressed_data != nullptr ) {
|
||||
set_size( uncompressed_size );
|
||||
data = std::move( decompressed_data );
|
||||
@ -271,7 +280,6 @@ template <class T> class section_impl : public section
|
||||
|
||||
bool load_data() const
|
||||
{
|
||||
is_lazy = false;
|
||||
Elf_Xword size = get_size();
|
||||
if ( nullptr == data && SHT_NULL != get_type() &&
|
||||
SHT_NOBITS != get_type() && size < get_stream_size() ) {
|
||||
@ -297,6 +305,8 @@ template <class T> class section_impl : public section
|
||||
}
|
||||
}
|
||||
|
||||
is_loaded = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -338,7 +348,7 @@ template <class T> class section_impl : public section
|
||||
Elf_Xword decompressed_size = get_size();
|
||||
Elf_Xword compressed_size = 0;
|
||||
auto compressed_ptr = compression->deflate(
|
||||
data.get(), convertor, decompressed_size, compressed_size );
|
||||
data.get(), convertor, decompressed_size, compressed_size );
|
||||
stream.write( compressed_ptr.get(), compressed_size );
|
||||
}
|
||||
else {
|
||||
@ -360,6 +370,7 @@ template <class T> class section_impl : public section
|
||||
bool is_address_set = false;
|
||||
size_t stream_size = 0;
|
||||
mutable bool is_lazy = false;
|
||||
mutable bool is_loaded = false;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
|
@ -99,7 +99,7 @@ template <class T> class segment_impl : public segment
|
||||
//------------------------------------------------------------------------------
|
||||
const char* get_data() const override
|
||||
{
|
||||
if ( is_lazy ) {
|
||||
if ( !is_loaded ) {
|
||||
load_data();
|
||||
}
|
||||
return data.get();
|
||||
@ -108,8 +108,10 @@ template <class T> class segment_impl : public segment
|
||||
//------------------------------------------------------------------------------
|
||||
void free_data() const override
|
||||
{
|
||||
data.reset( nullptr );
|
||||
is_lazy = true;
|
||||
if ( is_lazy ) {
|
||||
data.reset( nullptr );
|
||||
is_loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -190,7 +192,7 @@ template <class T> class segment_impl : public segment
|
||||
stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );
|
||||
is_offset_set = true;
|
||||
|
||||
if ( !is_lazy ) {
|
||||
if ( !( is_lazy || is_loaded ) ) {
|
||||
return load_data();
|
||||
}
|
||||
|
||||
@ -200,7 +202,6 @@ template <class T> class segment_impl : public segment
|
||||
//------------------------------------------------------------------------------
|
||||
bool load_data() const
|
||||
{
|
||||
is_lazy = false;
|
||||
if ( PT_NULL == get_type() || 0 == get_file_size() ) {
|
||||
return true;
|
||||
}
|
||||
@ -223,6 +224,8 @@ template <class T> class segment_impl : public segment
|
||||
}
|
||||
}
|
||||
|
||||
is_loaded = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -255,6 +258,7 @@ template <class T> class segment_impl : public segment
|
||||
size_t stream_size = 0;
|
||||
bool is_offset_set = false;
|
||||
mutable bool is_lazy = false;
|
||||
mutable bool is_loaded = false;
|
||||
};
|
||||
|
||||
} // namespace ELFIO
|
||||
|
@ -211,48 +211,59 @@ TEST( ELFIOTest, load32 )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check sections
|
||||
const section* sec = reader.sections[0];
|
||||
// sec->free_data();
|
||||
checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
|
||||
|
||||
sec = reader.sections[1];
|
||||
// sec->free_data();
|
||||
checkSection( sec, 1, ".interp", SHT_PROGBITS, SHF_ALLOC, 0x08048114,
|
||||
0x13, 0, 0, 1, 0 );
|
||||
|
||||
sec = reader.sections[9];
|
||||
// sec->free_data();
|
||||
checkSection( sec, 9, ".rel.plt", SHT_REL, SHF_ALLOC, 0x08048234, 0x18,
|
||||
4, 11, 4, 8 );
|
||||
|
||||
sec = reader.sections[19];
|
||||
// sec->free_data();
|
||||
checkSection( sec, 19, ".dynamic", SHT_DYNAMIC, SHF_WRITE | SHF_ALLOC,
|
||||
0x080494a0, 0xc8, 5, 0, 4, 8 );
|
||||
|
||||
sec = reader.sections[27];
|
||||
// sec->free_data();
|
||||
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];
|
||||
// sec->free_data();
|
||||
EXPECT_EQ( sec->get_index(), i );
|
||||
}
|
||||
|
||||
const section* sec1 = reader.sections[".strtab"];
|
||||
// sec1->free_data();
|
||||
EXPECT_EQ( sec->get_index(), sec1->get_index() );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check segments
|
||||
const segment* seg = reader.segments[0];
|
||||
seg->free_data();
|
||||
checkSegment( seg, PT_PHDR, 0x08048034, 0x08048034, 0x000e0, 0x000e0,
|
||||
PF_R + PF_X, 4 );
|
||||
|
||||
seg = reader.segments[4];
|
||||
seg->free_data();
|
||||
checkSegment( seg, PT_DYNAMIC, 0x080494a0, 0x080494a0, 0x000c8, 0x000c8,
|
||||
PF_R + PF_W, 4 );
|
||||
|
||||
seg = reader.segments[6];
|
||||
seg->free_data();
|
||||
checkSegment( seg, 0x6474E551, 0x0, 0x0, 0x0, 0x0, PF_R + PF_W, 4 );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check symbol table
|
||||
sec = reader.sections[".symtab"];
|
||||
// sec->free_data();
|
||||
|
||||
const_symbol_section_accessor sr( reader, sec );
|
||||
|
||||
@ -274,6 +285,7 @@ TEST( ELFIOTest, load32 )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check relocation table
|
||||
sec = reader.sections[".rel.dyn"];
|
||||
// sec->free_data();
|
||||
|
||||
const_relocation_section_accessor reloc( reader, sec );
|
||||
EXPECT_EQ( reloc.get_entries_num(), 1 );
|
||||
@ -282,6 +294,7 @@ TEST( ELFIOTest, load32 )
|
||||
R_386_GLOB_DAT, 0, 0 );
|
||||
|
||||
sec = reader.sections[".rel.plt"];
|
||||
// sec->free_data();
|
||||
|
||||
const_relocation_section_accessor reloc1( reader, sec );
|
||||
EXPECT_EQ( reloc1.get_entries_num(), 3 );
|
||||
@ -322,26 +335,30 @@ TEST( ELFIOTest, load64 )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check sections
|
||||
const section* sec = reader.sections[0];
|
||||
// sec->free_data();
|
||||
|
||||
checkSection( sec, 0, "", SHT_NULL, 0, 0, 0, 0, 0, 0, 0 );
|
||||
|
||||
sec = reader.sections[1];
|
||||
// sec->free_data();
|
||||
|
||||
checkSection( sec, 1, ".interp", SHT_PROGBITS, SHF_ALLOC,
|
||||
0x0000000000400200, 0x1c, 0, 0, 1, 0 );
|
||||
|
||||
sec = reader.sections[9];
|
||||
// sec->free_data();
|
||||
|
||||
checkSection( sec, 9, ".rela.plt", SHT_RELA, SHF_ALLOC,
|
||||
0x0000000000400340, 0x30, 4, 11, 8, 0x18 );
|
||||
|
||||
sec = reader.sections[20];
|
||||
// sec->free_data();
|
||||
|
||||
checkSection( sec, 20, ".dynamic", SHT_DYNAMIC, SHF_WRITE | SHF_ALLOC,
|
||||
0x0000000000600698, 0x190, 5, 0, 8, 0x10 );
|
||||
|
||||
sec = reader.sections[28];
|
||||
|
||||
// sec->free_data();
|
||||
checkSection( sec, 28, ".strtab", SHT_STRTAB, 0, 0x0, 0x23f, 0, 0, 1,
|
||||
0 );
|
||||
|
||||
@ -351,20 +368,24 @@ TEST( ELFIOTest, load64 )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check segments
|
||||
const segment* seg = reader.segments[0];
|
||||
seg->free_data();
|
||||
checkSegment( seg, PT_PHDR, 0x0000000000400040, 0x0000000000400040,
|
||||
0x00000000000001c0, 0x00000000000001c0, PF_R + PF_X, 8 );
|
||||
|
||||
seg = reader.segments[2];
|
||||
seg->free_data();
|
||||
checkSegment( seg, PT_LOAD, 0x0000000000400000, 0x0000000000400000,
|
||||
0x000000000000066c, 0x000000000000066c, PF_R + PF_X,
|
||||
0x200000 );
|
||||
|
||||
seg = reader.segments[7];
|
||||
seg->free_data();
|
||||
checkSegment( seg, 0x6474E551, 0x0, 0x0, 0x0, 0x0, PF_R + PF_W, 8 );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check symbol table
|
||||
sec = reader.sections[".symtab"];
|
||||
// sec->free_data();
|
||||
|
||||
const_symbol_section_accessor sr( reader, sec );
|
||||
|
||||
@ -387,6 +408,7 @@ TEST( ELFIOTest, load64 )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check relocation table
|
||||
sec = reader.sections[".rela.dyn"];
|
||||
// sec->free_data();
|
||||
|
||||
const_relocation_section_accessor reloc( reader, sec );
|
||||
EXPECT_EQ( reloc.get_entries_num(), 1 );
|
||||
@ -407,6 +429,7 @@ TEST( ELFIOTest, load64 )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Check note reader
|
||||
sec = reader.sections[".note.ABI-tag"];
|
||||
// sec->free_data();
|
||||
|
||||
const_note_section_accessor notes( reader, sec );
|
||||
EXPECT_EQ( notes.get_notes_num(), 1u );
|
||||
@ -1086,3 +1109,43 @@ TEST( ELFIOTest, test_dynamic_64_3 )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST( ELFIOTest, test_is_lazy )
|
||||
{
|
||||
bool is_lazy = false;
|
||||
do {
|
||||
is_lazy = !is_lazy;
|
||||
|
||||
elfio reader;
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/main", is_lazy ), true );
|
||||
|
||||
for ( const auto& sec : reader.sections ) {
|
||||
if ( sec->get_size() == 0 || sec->get_data() == nullptr )
|
||||
continue;
|
||||
|
||||
std::vector<char> data;
|
||||
std::copy( sec->get_data(), sec->get_data() + sec->get_size(),
|
||||
std::back_inserter( data ) );
|
||||
|
||||
sec->free_data();
|
||||
|
||||
EXPECT_TRUE( 0 == std::memcmp( data.data(), sec->get_data(),
|
||||
sec->get_size() ) );
|
||||
}
|
||||
|
||||
for ( const auto& seg : reader.segments ) {
|
||||
if ( seg->get_file_size() == 0 || seg->get_data() == nullptr )
|
||||
continue;
|
||||
|
||||
std::vector<char> data;
|
||||
std::copy( seg->get_data(), seg->get_data() + seg->get_file_size(),
|
||||
std::back_inserter( data ) );
|
||||
|
||||
seg->free_data();
|
||||
|
||||
EXPECT_TRUE( 0 == std::memcmp( data.data(), seg->get_data(),
|
||||
seg->get_file_size() ) );
|
||||
}
|
||||
} while ( is_lazy );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user