Squashed 'external/ELFIO/' content from commit 94f7706
git-subtree-dir: external/ELFIO git-subtree-split: 94f7706b5325b2ad9872e4481278278592cf86c9
This commit is contained in:
@@ -0,0 +1,848 @@
|
||||
/*
|
||||
Copyright (C) 2025-present 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <ario/ario.hpp>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
using namespace ARIO;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, wrong_file_name )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/does_not_exist.a" ).ok(), false );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, wrong_file_magic )
|
||||
{
|
||||
ario archive;
|
||||
auto result = archive.load( "ario/invalid_magic.a" );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
ASSERT_EQ( result.what(), "Invalid archive format. Expected magic: "
|
||||
"!<arch>\n, but got !<arkh>\n" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, simple_text_load )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).what(), "No errors" );
|
||||
ASSERT_EQ( archive.members.size(), 6 );
|
||||
EXPECT_EQ( archive.members[0].name, "hello.c" );
|
||||
EXPECT_EQ( archive.members[0].size, 45 );
|
||||
EXPECT_EQ( archive.members[1].name, "hello2.c" );
|
||||
EXPECT_EQ( archive.members[1].size, 7 );
|
||||
EXPECT_EQ( archive.members[2].name, "hello3.c" );
|
||||
EXPECT_EQ( archive.members[2].size, 8 );
|
||||
EXPECT_EQ( archive.members[3].name, "hello4.c" );
|
||||
EXPECT_EQ( archive.members[3].size, 10 );
|
||||
EXPECT_EQ( archive.members[4].name, "hello41.c" );
|
||||
EXPECT_EQ( archive.members[4].size, 11 );
|
||||
EXPECT_EQ( archive.members[5].name, "hello5.c" );
|
||||
EXPECT_EQ( archive.members[5].size, 8 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, long_name_load )
|
||||
{
|
||||
ario archive;
|
||||
auto result = archive.load( "ario/long_name.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( result.what(), "No errors" );
|
||||
|
||||
ASSERT_EQ( archive.members.size(), 9 );
|
||||
EXPECT_EQ( archive.members[0].name, "hello.c" );
|
||||
EXPECT_EQ( archive.members[0].size, 45 );
|
||||
EXPECT_EQ( archive.members[1].name, "hello2.c" );
|
||||
EXPECT_EQ( archive.members[1].size, 7 );
|
||||
EXPECT_EQ( archive.members[6].name, "a_file_with_very_long_name.txt" );
|
||||
EXPECT_EQ( archive.members[6].size, 6 );
|
||||
EXPECT_EQ( archive.members[7].name, "a_file_with_very_long_name2.txt" );
|
||||
EXPECT_EQ( archive.members[7].size, 6 );
|
||||
EXPECT_EQ( archive.members[8].name, "a_file_with_very_long_name3.txt" );
|
||||
EXPECT_EQ( archive.members[8].size, 6 );
|
||||
|
||||
EXPECT_EQ( archive.members["a_file_with_very_long_name.txt"].name,
|
||||
archive.members[6].name );
|
||||
EXPECT_EQ( archive.members["a_file_with_very_long_name3.txt"].name,
|
||||
archive.members[8].name );
|
||||
EXPECT_EQ( archive.members["hello2.c"].name, archive.members[1].name );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, load_libgcov )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/libgcov.a" ).ok(), true );
|
||||
|
||||
ASSERT_EQ( archive.members.size(), 29 );
|
||||
EXPECT_EQ( archive.members[0].name, "_gcov_merge_add.o" );
|
||||
EXPECT_EQ( archive.members[0].size, 1416 );
|
||||
EXPECT_EQ( archive.members[0].mode, 0644 );
|
||||
EXPECT_EQ( archive.members[0].data().substr( 0, 4 ), "\x7F"
|
||||
"ELF" );
|
||||
EXPECT_EQ( archive.members[6].name, "_gcov_interval_profiler_atomic.o" );
|
||||
EXPECT_EQ( archive.members[6].size, 1264 );
|
||||
EXPECT_EQ( archive.members[6].mode, 0644 );
|
||||
EXPECT_EQ( archive.members[6].data().substr( 0, 4 ), "\x7F"
|
||||
"ELF" );
|
||||
EXPECT_EQ( archive.members[17].name,
|
||||
"_gcov_indirect_call_topn_profiler.o" );
|
||||
EXPECT_EQ( archive.members[17].size, 2104 );
|
||||
EXPECT_EQ( archive.members[17].mode, 0644 );
|
||||
EXPECT_EQ( archive.members[17].data().substr( 0, 4 ), "\x7F"
|
||||
"ELF" );
|
||||
EXPECT_EQ( archive.members[28].name, "_gcov.o" );
|
||||
EXPECT_EQ( archive.members[28].size, 16768 );
|
||||
EXPECT_EQ( archive.members[28].mode, 0644 );
|
||||
EXPECT_EQ( archive.members[28].data().substr( 0, 4 ), "\x7F"
|
||||
"ELF" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, find_symbol_libgcov )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/libgcov.a" ).ok(), true );
|
||||
|
||||
std::optional<std::reference_wrapper<const ario::Member>> member =
|
||||
std::nullopt;
|
||||
auto result = archive.find_symbol( "__gcov_merge_add", member );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( member->get().name, "_gcov_merge_add.o" );
|
||||
|
||||
result =
|
||||
archive.find_symbol( "__gcov_indirect_call_topn_profiler", member );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( member->get().name, "_gcov_indirect_call_topn_profiler.o" );
|
||||
|
||||
result = archive.find_symbol( "__not_found", member );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
ASSERT_EQ( member.has_value(), false );
|
||||
|
||||
result = archive.find_symbol( "__gcov_write_counter", member );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( member->get().name, "_gcov.o" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, get_symbols_for_member_libgcov )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/libgcov.a" ).ok(), true );
|
||||
|
||||
std::vector<std::string> symbols;
|
||||
|
||||
auto result = archive.get_symbols_for_member( archive.members[0], symbols );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( symbols.size(), 1 );
|
||||
ASSERT_EQ( symbols[0], "__gcov_merge_add" );
|
||||
|
||||
result = archive.get_symbols_for_member( archive.members[6], symbols );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( symbols.size(), 1 );
|
||||
ASSERT_EQ( symbols[0], "__gcov_interval_profiler_atomic" );
|
||||
|
||||
result = archive.get_symbols_for_member( archive.members[28], symbols );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( symbols.size(), 20 );
|
||||
// We cannot garantee the order of symbols in the symbol table,
|
||||
// so we just check that some of them are present
|
||||
ASSERT_NE( std::find( symbols.begin(), symbols.end(), "__gcov_exit" ),
|
||||
symbols.end() );
|
||||
ASSERT_NE( std::find( symbols.begin(), symbols.end(), "__gcov_var" ),
|
||||
symbols.end() );
|
||||
ASSERT_NE(
|
||||
std::find( symbols.begin(), symbols.end(), "__gcov_read_counter" ),
|
||||
symbols.end() );
|
||||
ASSERT_EQ( std::find( symbols.begin(), symbols.end(), "doesn't exist" ),
|
||||
symbols.end() );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, get_symbols_for_ELF_files_in_archive )
|
||||
{
|
||||
// Load the archive file containing ELF object files
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/libgcov.a" ).ok(), true );
|
||||
|
||||
// Iterate over each member (object file) in the archive
|
||||
for ( const auto& member : archive.members ) {
|
||||
// Extract the raw data of the member (should be an ELF file)
|
||||
std::string content = member.data();
|
||||
std::istringstream iss( content );
|
||||
|
||||
// Parse the member's data as an ELF file using ELFIO
|
||||
elfio elf_reader;
|
||||
ASSERT_EQ( elf_reader.load( iss ), true );
|
||||
|
||||
std::uint32_t counter = 0;
|
||||
|
||||
// Iterate over all sections in the ELF file
|
||||
for ( const auto& sec : elf_reader.sections ) {
|
||||
// Look for the symbol table section
|
||||
if ( sec->get_type() == SHT_SYMTAB ) {
|
||||
// Access the symbols in the symbol table
|
||||
symbol_section_accessor symbols( elf_reader, sec.get() );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind = 0, type = 0;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
|
||||
std::optional<std::reference_wrapper<const ario::Member>>
|
||||
found_member = std::nullopt;
|
||||
// Iterate over all symbols in the symbol table
|
||||
for ( Elf_Xword i = 0; i < symbols.get_symbols_num(); ++i ) {
|
||||
// Extract symbol properties
|
||||
ASSERT_EQ( symbols.get_symbol( i, name, value, size, bind,
|
||||
type, section_index, other ),
|
||||
true );
|
||||
// For each global function or object symbol, check that the archive symbol table can find it
|
||||
if ( ( type == STT_FUNC || type == STT_OBJECT ||
|
||||
type == STT_TLS || type == STT_COMMON ) &&
|
||||
bind == STB_GLOBAL ) {
|
||||
++counter;
|
||||
ASSERT_EQ(
|
||||
archive.find_symbol( name, found_member ).ok(),
|
||||
true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the number of global symbols found matches the expected count
|
||||
std::vector<std::string> symbols_from_the_member;
|
||||
ASSERT_EQ(
|
||||
archive.get_symbols_for_member( member, symbols_from_the_member )
|
||||
.ok(),
|
||||
true );
|
||||
ASSERT_EQ( counter, symbols_from_the_member.size() );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, basic_header_save )
|
||||
{
|
||||
ario archive;
|
||||
std::ostringstream oss;
|
||||
|
||||
auto result = archive.save( oss );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
ASSERT_EQ( oss.str(), "!<arch>\n" );
|
||||
}
|
||||
|
||||
void compare_archives( const ario& archive1, const ario& archive2 )
|
||||
{
|
||||
ASSERT_EQ( archive1.members.size(), archive2.members.size() );
|
||||
|
||||
for ( size_t i = 0; i < archive1.members.size(); ++i ) {
|
||||
EXPECT_EQ( archive1.members[i].name, archive2.members[i].name );
|
||||
EXPECT_EQ( archive1.members[i].date, archive2.members[i].date );
|
||||
EXPECT_EQ( archive1.members[i].uid, archive2.members[i].uid );
|
||||
EXPECT_EQ( archive1.members[i].gid, archive2.members[i].gid );
|
||||
EXPECT_EQ( archive1.members[i].mode, archive2.members[i].mode );
|
||||
EXPECT_EQ( archive1.members[i].size, archive2.members[i].size );
|
||||
EXPECT_EQ( archive1.members[i].data(), archive2.members[i].data() );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, header_save )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
|
||||
// Save the archive to a new file
|
||||
ASSERT_EQ( archive.save( "ario/simple_text_saved.a" ).ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/simple_text_saved.a" ).ok(), true );
|
||||
|
||||
compare_archives( loaded_archive, archive );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, long_name_dir_save )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/long_name.a" ).ok(), true );
|
||||
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/long_name_saved.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/long_name_saved.a" ).ok(), true );
|
||||
|
||||
compare_archives( loaded_archive, archive );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, long_name_save )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/long_name.a" ).ok(), true );
|
||||
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/long_name_saved.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/long_name_saved.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), archive.members.size() );
|
||||
EXPECT_EQ( loaded_archive.members[0].name, archive.members[0].name );
|
||||
EXPECT_EQ( loaded_archive.members[0].size, archive.members[0].size );
|
||||
EXPECT_EQ( loaded_archive.members[archive.members.size() - 1].name,
|
||||
archive.members[archive.members.size() - 1].name );
|
||||
EXPECT_EQ( loaded_archive.members[archive.members.size() - 1].size,
|
||||
archive.members[archive.members.size() - 1].size );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, libgcov_save )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/libgcov.a" ).ok(), true );
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/libgcov_saved.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/libgcov_saved.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), archive.members.size() );
|
||||
EXPECT_EQ( loaded_archive.members[0].name, archive.members[0].name );
|
||||
EXPECT_EQ( loaded_archive.members[0].size, archive.members[0].size );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 1].name,
|
||||
archive.members[archive.members.size() - 1].name );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 1].size,
|
||||
archive.members[archive.members.size() - 1].size );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, add_simple_member )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
|
||||
ario::Member m;
|
||||
m.name = "added_text.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "The content\nof this\nmember" );
|
||||
m.name = "added_text1.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "The content\nof this\nmember\n" );
|
||||
m.name = "added_text2.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "" );
|
||||
m.name = "added_text3.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "Hello\n" );
|
||||
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/simple_text_saved.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.load( "ario/simple_text_saved.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), archive.members.size() + 4 );
|
||||
EXPECT_EQ( loaded_archive.members[0].name, archive.members[0].name );
|
||||
EXPECT_EQ( loaded_archive.members[0].size, archive.members[0].size );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 5].name,
|
||||
archive.members[archive.members.size() - 1].name );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 5].size,
|
||||
archive.members[archive.members.size() - 1].size );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 4].name,
|
||||
"added_text.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 4].data(),
|
||||
"The content\nof this\nmember" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 3].name,
|
||||
"added_text1.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 3].data(),
|
||||
"The content\nof this\nmember\n" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 2].name,
|
||||
"added_text2.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 2].data(),
|
||||
"" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 1].name,
|
||||
"added_text3.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 1].data(),
|
||||
"Hello\n" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, add_long_name_member )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
|
||||
ario::Member m;
|
||||
std::optional<std::reference_wrapper<const ario::Member>> added_member =
|
||||
std::nullopt;
|
||||
m.name = "long_name_member_added_text.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "The content\nof this\nmember" );
|
||||
m.name = "long_name_member_added_text1.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "The content\nof this\nmember\n" );
|
||||
m.name = "long_name_member_added_text2.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "" );
|
||||
m.name = "long_name_member_added_text333.txt";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "Hello\n" );
|
||||
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/long_name_saved.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.load( "ario/long_name_saved.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), archive.members.size() + 4 );
|
||||
EXPECT_EQ( loaded_archive.members[0].name, archive.members[0].name );
|
||||
EXPECT_EQ( loaded_archive.members[0].size, archive.members[0].size );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 5].name,
|
||||
archive.members[archive.members.size() - 1].name );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 5].size,
|
||||
archive.members[archive.members.size() - 1].size );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 4].name,
|
||||
"long_name_member_added_text.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 4].data(),
|
||||
"The content\nof this\nmember" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 3].name,
|
||||
"long_name_member_added_text1.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 3].data(),
|
||||
"The content\nof this\nmember\n" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 2].name,
|
||||
"long_name_member_added_text2.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 2].data(),
|
||||
"" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 1].name,
|
||||
"long_name_member_added_text333.txt" );
|
||||
EXPECT_EQ( loaded_archive.members[loaded_archive.members.size() - 1].data(),
|
||||
"Hello\n" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, new_text_lib )
|
||||
{
|
||||
ario archive;
|
||||
|
||||
ario::Member m;
|
||||
std::optional<std::reference_wrapper<const ario::Member>> added_member =
|
||||
std::nullopt;
|
||||
m.name = "123456789012345";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data\n" );
|
||||
m.name = "1234567890123456";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data\n" );
|
||||
m.name = "12345678901234567";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data\n" );
|
||||
m.name = "12345";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data\n" );
|
||||
m.name = "123456789012345678";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data\n" );
|
||||
m.name = "1234567";
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data\n" );
|
||||
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/new_text_lib.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/new_text_lib.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), 6 );
|
||||
std::vector<std::string> ref_names = {
|
||||
"123456789012345", "1234567890123456", "12345678901234567",
|
||||
"12345", "123456789012345678", "1234567" };
|
||||
for ( size_t i = 0; i < loaded_archive.members.size(); i++ ) {
|
||||
EXPECT_EQ( loaded_archive.members[i].name, ref_names[i] );
|
||||
EXPECT_EQ( loaded_archive.members[i].size, 5 );
|
||||
EXPECT_EQ( loaded_archive.members[i].data(), "data\n" );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, new_text_lib_with_symbols )
|
||||
{
|
||||
ario archive;
|
||||
|
||||
for ( auto i = 0; i < 20; i++ ) {
|
||||
ario::Member m;
|
||||
m.name = "name__________" + std::to_string( i );
|
||||
m.date = 0;
|
||||
m.gid = 1234;
|
||||
m.uid = 5678;
|
||||
m.mode = 0644;
|
||||
ASSERT_EQ(
|
||||
archive.add_member( m, "data" + std::to_string( i ) + "\n" ).ok(),
|
||||
true );
|
||||
|
||||
std::vector<std::string> symbols = {};
|
||||
for ( auto j = 0; j < i; j++ ) {
|
||||
symbols.emplace_back( "symbol_" + std::to_string( 100 * i + j ) );
|
||||
}
|
||||
ASSERT_EQ(
|
||||
archive.add_symbols_for_member( archive.members.back(), symbols )
|
||||
.ok(),
|
||||
true );
|
||||
}
|
||||
// Save the archive to a new file
|
||||
auto result = archive.save( "ario/new_text_lib_with_symbols.a" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
|
||||
// Load the saved archive and check its contents
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/new_text_lib_with_symbols.a" ).ok(),
|
||||
true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), 20 );
|
||||
for ( const auto& m : loaded_archive.members ) {
|
||||
auto index = std::stoi( m.name.c_str() + 14 );
|
||||
ASSERT_EQ( loaded_archive.members[index].name, m.name );
|
||||
|
||||
std::vector<std::string> symbols = {};
|
||||
ASSERT_EQ( loaded_archive.get_symbols_for_member( m, symbols ).ok(),
|
||||
true );
|
||||
ASSERT_EQ( symbols.size(), index );
|
||||
for ( const auto& symbol : symbols ) {
|
||||
std::optional<std::reference_wrapper<const ario::Member>> ms =
|
||||
std::nullopt;
|
||||
ASSERT_EQ( loaded_archive.find_symbol( symbol, ms ).ok(), true );
|
||||
ASSERT_EQ( ms->get().name, m.name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, load_empty_archive )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/empty.a" ).ok(), true );
|
||||
ASSERT_EQ( archive.members.size(), 0 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, add_duplicate_member )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
|
||||
ario::Member m = archive.members[0];
|
||||
std::optional<std::reference_wrapper<const ario::Member>> added_member =
|
||||
std::nullopt;
|
||||
auto result = archive.add_member( m, "duplicate content" );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
ASSERT_NE( std::string( result.what() ).find( "already exists" ),
|
||||
std::string::npos );
|
||||
}
|
||||
|
||||
TEST( ARIOTest, add_symbols_for_nonexistent_member )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
|
||||
ario::Member fake_member;
|
||||
fake_member.name = "not_in_archive.txt";
|
||||
std::vector<std::string> symbols = { "fake_symbol" };
|
||||
auto result = archive.add_symbols_for_member( fake_member, symbols );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
ASSERT_NE( std::string( result.what() ).find( "not found" ),
|
||||
std::string::npos );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, get_symbols_for_nonexistent_member )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
|
||||
ario::Member fake_member;
|
||||
fake_member.name = "not_in_archive.txt";
|
||||
std::vector<std::string> symbols;
|
||||
auto result = archive.get_symbols_for_member( fake_member, symbols );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
ASSERT_NE( std::string( result.what() ).find( "not found" ),
|
||||
std::string::npos );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, save_and_reload_empty_archive )
|
||||
{
|
||||
ario archive;
|
||||
std::ostringstream oss;
|
||||
ASSERT_EQ( archive.save( oss ).ok(), true );
|
||||
std::istringstream iss( oss.str() );
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ(
|
||||
loaded_archive.load( std::make_unique<std::istringstream>( oss.str() ) )
|
||||
.ok(),
|
||||
true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), 0 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, member_access_out_of_range )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
// Index out of range
|
||||
EXPECT_THROW( archive.members[1000], std::out_of_range );
|
||||
// Name not found
|
||||
EXPECT_THROW( archive.members["not_in_archive.txt"], std::out_of_range );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, find_symbol_not_present )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
std::optional<std::reference_wrapper<const ario::Member>> member =
|
||||
std::nullopt;
|
||||
auto result = archive.find_symbol( "not_a_symbol", member );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
ASSERT_EQ( member.has_value(), false );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test: Remove all members and save
|
||||
TEST( ARIOTest, remove_all_members_and_save )
|
||||
{
|
||||
ario archive;
|
||||
ASSERT_EQ( archive.load( "ario/simple_text.a" ).ok(), true );
|
||||
// Remove all members by creating a new archive and not adding any
|
||||
ario empty_archive;
|
||||
ASSERT_EQ( empty_archive.save( "ario/removed_all.a" ).ok(), true );
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/removed_all.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), 0 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test: Add member with empty name
|
||||
TEST( ARIOTest, add_member_with_empty_name )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "";
|
||||
m.mode = 0644;
|
||||
std::optional<std::reference_wrapper<const ario::Member>> added_member =
|
||||
std::nullopt;
|
||||
auto result = archive.add_member( m, "data" );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test: Add member with duplicate symbols
|
||||
TEST( ARIOTest, add_duplicate_symbols_for_member )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "dup_symbol.o";
|
||||
m.mode = 0644;
|
||||
ASSERT_EQ( archive.add_member( m, "data" ).ok(), true );
|
||||
std::vector<std::string> symbols = { "sym1", "sym1", "sym2" };
|
||||
ASSERT_EQ(
|
||||
archive.add_symbols_for_member( archive.members.back(), symbols ).ok(),
|
||||
true );
|
||||
std::vector<std::string> out_symbols;
|
||||
ASSERT_EQ(
|
||||
archive.get_symbols_for_member( archive.members.back(), out_symbols )
|
||||
.ok(),
|
||||
true );
|
||||
// Should contain all symbols, including duplicates
|
||||
ASSERT_EQ( std::count( out_symbols.begin(), out_symbols.end(), "sym1" ),
|
||||
1 );
|
||||
ASSERT_EQ( std::count( out_symbols.begin(), out_symbols.end(), "sym2" ),
|
||||
1 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test: Add member with special characters in name
|
||||
TEST( ARIOTest, add_member_with_special_characters )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "spécial_名.o";
|
||||
m.mode = 0644;
|
||||
ASSERT_EQ( archive.add_member( m, "data" ).ok(), true );
|
||||
ASSERT_EQ( archive.members.back().name, "spécial_名.o" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, add_member_with_non_ascii_name )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = u8"тест.o";
|
||||
m.mode = 0644;
|
||||
auto result = archive.add_member( m, "data" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( archive.members.back().name, u8"тест.o" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test: Save and load archive with only one member
|
||||
TEST( ARIOTest, save_and_load_single_member_archive )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "single.o";
|
||||
m.mode = 0644;
|
||||
std::optional<std::reference_wrapper<const ario::Member>> added_member =
|
||||
std::nullopt;
|
||||
ASSERT_EQ( archive.add_member( m, "data" ).ok(), true );
|
||||
ASSERT_EQ( archive.save( "ario/single_member.a" ).ok(), true );
|
||||
ario loaded_archive;
|
||||
ASSERT_EQ( loaded_archive.load( "ario/single_member.a" ).ok(), true );
|
||||
ASSERT_EQ( loaded_archive.members.size(), 1 );
|
||||
ASSERT_EQ( loaded_archive.members[0].name, "single.o" );
|
||||
ASSERT_EQ( loaded_archive.members[0].data(), "data" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test: Add member with zero size data
|
||||
TEST( ARIOTest, add_member_with_zero_size_data )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "empty.o";
|
||||
m.mode = 0644;
|
||||
ASSERT_EQ( archive.add_member( m, "" ).ok(), true );
|
||||
ASSERT_EQ( archive.members.back().size, 0 );
|
||||
ASSERT_EQ( archive.members.back().data(), "" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, add_member_with_large_data )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "large.o";
|
||||
m.mode = 0644;
|
||||
std::string large_data( 10 * 1024 * 1024, 'A' ); // 10 MB
|
||||
auto result = archive.add_member( m, large_data );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( archive.members.back().size, large_data.size() );
|
||||
ASSERT_EQ( archive.members.back().data(), large_data );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, save_to_invalid_path )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = "file.o";
|
||||
m.mode = 0644;
|
||||
archive.add_member( m, "data" );
|
||||
auto result = archive.save( "/invalid_path/should_fail.a" );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, load_corrupted_archive )
|
||||
{
|
||||
ario archive;
|
||||
// Create a corrupted archive in memory
|
||||
std::string corrupted = "!<arch>\ncorrupted data";
|
||||
std::istringstream iss( corrupted );
|
||||
auto result =
|
||||
archive.load( std::make_unique<std::istringstream>( corrupted ) );
|
||||
ASSERT_EQ( result.ok(), false );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ARIOTest, add_member_with_max_name_length )
|
||||
{
|
||||
ario archive;
|
||||
ario::Member m;
|
||||
m.name = std::string( 255, 'a' ); // 255 chars
|
||||
m.mode = 0644;
|
||||
auto result = archive.add_member( m, "data" );
|
||||
ASSERT_EQ( result.ok(), true );
|
||||
ASSERT_EQ( archive.members.back().name.size(), 255 );
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
include(FetchContent)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.24.0")
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
URL https://github.com/google/googletest/archive/530d5c8c84.zip
|
||||
)
|
||||
else()
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
URL https://github.com/google/googletest/archive/refs/tags/v1.16.0.zip
|
||||
FIND_PACKAGE_ARGS NAMES GTest
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP = TRUE
|
||||
)
|
||||
endif()
|
||||
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
enable_testing()
|
||||
|
||||
# Find all the binary files used for testing and copy them into the build
|
||||
# directory. This allows the test to be run from the build directory
|
||||
|
||||
# First, create an elf_examples folder under the current build directory
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/elf_examples)
|
||||
|
||||
# Second, glob all files under elf_examples
|
||||
file(GLOB elf_examples
|
||||
LIST_DIRECTORIES
|
||||
false
|
||||
CONFIGURE_DEPENDS
|
||||
elf_examples/*)
|
||||
|
||||
# Third, copy each file globbed to the elf_examples folder under the current
|
||||
# build directory
|
||||
foreach(example ${elf_examples})
|
||||
configure_file(${example} ${CMAKE_CURRENT_BINARY_DIR}/elf_examples COPYONLY)
|
||||
endforeach()
|
||||
|
||||
# First, create an ario folder under the current build directory
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ario)
|
||||
|
||||
# Second, glob all files under ario
|
||||
file(GLOB ario
|
||||
LIST_DIRECTORIES
|
||||
false
|
||||
CONFIGURE_DEPENDS
|
||||
ario/*)
|
||||
|
||||
# Third, copy each file globbed to the ario folder under the current
|
||||
# build directory
|
||||
foreach(example ${ario})
|
||||
configure_file(${example} ${CMAKE_CURRENT_BINARY_DIR}/ario COPYONLY)
|
||||
endforeach()
|
||||
|
||||
|
||||
# Lastly, copy the script to run the tests
|
||||
configure_file(runELFtests ${CMAKE_CURRENT_BINARY_DIR}/runELFtests COPYONLY)
|
||||
|
||||
add_executable(
|
||||
ELFIOTest
|
||||
ELFIOTest.cpp
|
||||
ELFIOTest1.cpp
|
||||
ELFIOTest2.cpp
|
||||
ARIOTest.cpp)
|
||||
|
||||
target_link_libraries(
|
||||
ELFIOTest
|
||||
PRIVATE
|
||||
elfio::elfio
|
||||
ario::ario
|
||||
gtest_main
|
||||
GTest::gtest_main)
|
||||
|
||||
add_test(
|
||||
NAME
|
||||
ELFIOTest
|
||||
COMMAND
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ELFIOTest
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_executable(
|
||||
elfio_fuzzer
|
||||
elfio_fuzzer.cpp)
|
||||
|
||||
target_link_libraries(
|
||||
elfio_fuzzer
|
||||
PRIVATE
|
||||
elfio::elfio)
|
||||
|
||||
target_compile_options(elfio_fuzzer
|
||||
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O1 -fsanitize=fuzzer,address>
|
||||
)
|
||||
|
||||
target_link_libraries(elfio_fuzzer
|
||||
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address>
|
||||
)
|
||||
endif()
|
||||
|
||||
add_dependencies(check ELFIOTest)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(ELFIOTest)
|
||||
+1236
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,895 @@
|
||||
/*
|
||||
Copyright (C) 2001-present 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
enum Tests
|
||||
{
|
||||
SEG_ALIGN = 1
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool write_obj_i386( bool is64bit )
|
||||
{
|
||||
elfio writer;
|
||||
|
||||
writer.create( is64bit ? ELFCLASS64 : ELFCLASS32, ELFDATA2LSB );
|
||||
writer.set_type( ET_REL );
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_machine( is64bit ? EM_X86_64 : EM_386 );
|
||||
|
||||
// Create code section*
|
||||
section* text_sec = writer.sections.add( ".text" );
|
||||
text_sec->set_type( SHT_PROGBITS );
|
||||
text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec->set_addr_align( 0x10 );
|
||||
|
||||
// Add data into it
|
||||
char text[] = {
|
||||
'\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
||||
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
||||
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
|
||||
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
||||
'\xCD', '\x80', // int 0x80
|
||||
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
|
||||
'\xCD', '\x80' // int 0x80
|
||||
};
|
||||
text_sec->set_data( text, sizeof( text ) );
|
||||
|
||||
// Create data section*
|
||||
section* data_sec = writer.sections.add( ".data" );
|
||||
data_sec->set_type( SHT_PROGBITS );
|
||||
data_sec->set_flags( SHF_ALLOC | SHF_WRITE );
|
||||
data_sec->set_addr_align( 4 );
|
||||
|
||||
char data[] = {
|
||||
'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
||||
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
||||
'\x6C', '\x64', '\x21', '\x0A' };
|
||||
data_sec->set_data( data, sizeof( data ) );
|
||||
|
||||
section* str_sec = writer.sections.add( ".strtab" );
|
||||
str_sec->set_type( SHT_STRTAB );
|
||||
str_sec->set_addr_align( 0x1 );
|
||||
|
||||
string_section_accessor str_writer( str_sec );
|
||||
Elf_Word nStrIndex = str_writer.add_string( "msg" );
|
||||
|
||||
section* sym_sec = writer.sections.add( ".symtab" );
|
||||
sym_sec->set_type( SHT_SYMTAB );
|
||||
sym_sec->set_info( 2 );
|
||||
sym_sec->set_link( str_sec->get_index() );
|
||||
sym_sec->set_addr_align( 4 );
|
||||
sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
|
||||
|
||||
symbol_section_accessor symbol_writer( writer, sym_sec );
|
||||
Elf_Word nSymIndex = symbol_writer.add_symbol(
|
||||
nStrIndex, 0, 0, STB_LOCAL, STT_NOTYPE, 0, data_sec->get_index() );
|
||||
|
||||
// Another way to add symbol
|
||||
symbol_writer.add_symbol( str_writer, "_start", 0x00000000, 0, STB_WEAK,
|
||||
STT_FUNC, 0, text_sec->get_index() );
|
||||
|
||||
// Create relocation table section*
|
||||
section* rel_sec = writer.sections.add( ".rel.text" );
|
||||
rel_sec->set_type( SHT_REL );
|
||||
rel_sec->set_info( text_sec->get_index() );
|
||||
rel_sec->set_link( sym_sec->get_index() );
|
||||
rel_sec->set_addr_align( 4 );
|
||||
rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
|
||||
|
||||
relocation_section_accessor rel_writer( writer, rel_sec );
|
||||
rel_writer.add_entry( 11, nSymIndex, (unsigned char)R_386_RELATIVE );
|
||||
|
||||
// Another method to add the same relocation entry
|
||||
// pRelWriter->AddEntry( pStrWriter, "msg",
|
||||
// pSymWriter, 29, 0,
|
||||
// ELF32_ST_INFO( STB_GLOBAL, STT_OBJECT ), 0,
|
||||
// data_sec->GetIndex(),
|
||||
// 0, (unsigned char)R_386_RELATIVE );
|
||||
|
||||
// Create note section*
|
||||
section* note_sec = writer.sections.add( ".note" );
|
||||
note_sec->set_type( SHT_NOTE );
|
||||
note_sec->set_addr_align( 1 );
|
||||
|
||||
// Create notes writer
|
||||
note_section_accessor note_writer( writer, note_sec );
|
||||
note_writer.add_note( 0x77, "Created by ELFIO", 0, 0 );
|
||||
|
||||
// Create ELF file
|
||||
writer.save( is64bit ? "elf_examples/write_obj_i386_64.o"
|
||||
: "elf_examples/write_obj_i386_32.o" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool write_exe_i386( const std::string& filename,
|
||||
bool is64bit,
|
||||
bool set_addr = false,
|
||||
Elf64_Addr addr = 0 )
|
||||
{
|
||||
elfio writer;
|
||||
|
||||
writer.create( is64bit ? ELFCLASS64 : ELFCLASS32, ELFDATA2LSB );
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_type( ET_EXEC );
|
||||
writer.set_machine( is64bit ? EM_X86_64 : EM_386 );
|
||||
|
||||
// Create code section*
|
||||
section* text_sec = writer.sections.add( ".text" );
|
||||
text_sec->set_type( SHT_PROGBITS );
|
||||
text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec->set_addr_align( 0x10 );
|
||||
if ( set_addr ) {
|
||||
text_sec->set_address( addr );
|
||||
}
|
||||
|
||||
// Add data into it
|
||||
char text[] = {
|
||||
'\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
||||
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
||||
'\xB9', '\x20', '\x80', '\x04', '\x08', // mov ecx, msg
|
||||
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
||||
'\xCD', '\x80', // int 0x80
|
||||
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
|
||||
'\xCD', '\x80' // int 0x80
|
||||
};
|
||||
text_sec->set_data( text, sizeof( text ) );
|
||||
|
||||
segment* text_seg = writer.segments.add();
|
||||
text_seg->set_type( PT_LOAD );
|
||||
text_seg->set_virtual_address( 0x08048000 );
|
||||
text_seg->set_physical_address( 0x08048000 );
|
||||
text_seg->set_flags( PF_X | PF_R );
|
||||
text_seg->set_align( 0x1000 );
|
||||
text_seg->add_section( text_sec, text_sec->get_addr_align() );
|
||||
|
||||
// Create data section*
|
||||
section* data_sec = writer.sections.add( ".data" );
|
||||
data_sec->set_type( SHT_PROGBITS );
|
||||
data_sec->set_flags( SHF_ALLOC | SHF_WRITE );
|
||||
data_sec->set_addr_align( 0x4 );
|
||||
|
||||
char data[] = {
|
||||
'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
||||
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
||||
'\x6C', '\x64', '\x21', '\x0A' };
|
||||
data_sec->set_data( data, sizeof( data ) );
|
||||
|
||||
segment* data_seg = writer.segments.add();
|
||||
data_seg->set_type( PT_LOAD );
|
||||
data_seg->set_virtual_address( 0x08048020 );
|
||||
data_seg->set_physical_address( 0x08048020 );
|
||||
data_seg->set_flags( PF_W | PF_R );
|
||||
data_seg->set_align( 0x10 );
|
||||
data_seg->add_section_index( data_sec->get_index(),
|
||||
data_sec->get_addr_align() );
|
||||
|
||||
section* note_sec = writer.sections.add( ".note" );
|
||||
note_sec->set_type( SHT_NOTE );
|
||||
note_sec->set_addr_align( 1 );
|
||||
note_section_accessor note_writer( writer, note_sec );
|
||||
note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
|
||||
char descr[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 };
|
||||
note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );
|
||||
|
||||
// Create ELF file
|
||||
writer.set_entry( 0x08048000 );
|
||||
|
||||
writer.save( filename );
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void checkObjestsAreEqual( std::string file_name1, std::string file_name2 )
|
||||
{
|
||||
elfio file1;
|
||||
elfio file2;
|
||||
ASSERT_EQ( file1.load( file_name1 ), true );
|
||||
EXPECT_EQ( file1.save( file_name2 ), true );
|
||||
ASSERT_EQ( file1.load( file_name1 ), true );
|
||||
ASSERT_EQ( file2.load( file_name2 ), true );
|
||||
|
||||
for ( int i = 0; i < file1.sections.size(); ++i ) {
|
||||
EXPECT_EQ( file1.sections[i]->get_address(),
|
||||
file2.sections[i]->get_address() );
|
||||
EXPECT_EQ( file1.sections[i]->get_addr_align(),
|
||||
file2.sections[i]->get_addr_align() );
|
||||
EXPECT_EQ( file1.sections[i]->get_entry_size(),
|
||||
file2.sections[i]->get_entry_size() );
|
||||
EXPECT_EQ( file1.sections[i]->get_flags(),
|
||||
file2.sections[i]->get_flags() );
|
||||
EXPECT_EQ( file1.sections[i]->get_index(),
|
||||
file2.sections[i]->get_index() );
|
||||
EXPECT_EQ( file1.sections[i]->get_info(),
|
||||
file2.sections[i]->get_info() );
|
||||
EXPECT_EQ( file1.sections[i]->get_link(),
|
||||
file2.sections[i]->get_link() );
|
||||
EXPECT_EQ( file1.sections[i]->get_name(),
|
||||
file2.sections[i]->get_name() );
|
||||
EXPECT_EQ( file1.sections[i]->get_name_string_offset(),
|
||||
file2.sections[i]->get_name_string_offset() );
|
||||
EXPECT_EQ( file1.sections[i]->get_size(),
|
||||
file2.sections[i]->get_size() );
|
||||
EXPECT_EQ( file1.sections[i]->get_type(),
|
||||
file2.sections[i]->get_type() );
|
||||
|
||||
if ( file1.sections[i]->get_type() == SHT_NULL ||
|
||||
file1.sections[i]->get_type() == SHT_NOBITS ) {
|
||||
continue;
|
||||
}
|
||||
ASSERT_NE( file1.sections[i]->get_data(), (const char*)0 );
|
||||
ASSERT_NE( file2.sections[i]->get_data(), (const char*)0 );
|
||||
std::string pdata1( file1.sections[i]->get_data(),
|
||||
file1.sections[i]->get_data() +
|
||||
file1.sections[i]->get_size() );
|
||||
std::string pdata2( file2.sections[i]->get_data(),
|
||||
file2.sections[i]->get_data() +
|
||||
file2.sections[i]->get_size() );
|
||||
|
||||
EXPECT_EQ( file1.sections[i]->get_size(),
|
||||
file2.sections[i]->get_size() );
|
||||
if ( ( file2.sections[i]->get_type() != SHT_NULL ) &&
|
||||
( file2.sections[i]->get_type() != SHT_NOBITS ) ) {
|
||||
EXPECT_EQ_COLLECTIONS( pdata1.begin(), pdata1.end(), pdata2.begin(),
|
||||
pdata2.end() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void checkExeAreEqual( std::string file_name1,
|
||||
std::string file_name2,
|
||||
int skipTests = 0 )
|
||||
{
|
||||
checkObjestsAreEqual( file_name1, file_name2 );
|
||||
|
||||
elfio file1;
|
||||
elfio file2;
|
||||
|
||||
ASSERT_EQ( file1.load( file_name1 ), true );
|
||||
ASSERT_EQ( file2.load( file_name2 ), true );
|
||||
|
||||
for ( int i = 0; i < file1.segments.size(); ++i ) {
|
||||
if ( !( skipTests & SEG_ALIGN ) )
|
||||
EXPECT_EQ( file1.segments[i]->get_align(),
|
||||
file2.segments[i]->get_align() );
|
||||
EXPECT_EQ( file1.segments[i]->get_file_size(),
|
||||
file2.segments[i]->get_file_size() );
|
||||
EXPECT_EQ( file1.segments[i]->get_memory_size(),
|
||||
file2.segments[i]->get_memory_size() );
|
||||
EXPECT_EQ( file1.segments[i]->get_type(),
|
||||
file2.segments[i]->get_type() );
|
||||
|
||||
// skip data comparisons of the program header and of empty segments
|
||||
if ( file1.segments[i]->get_type() == PT_PHDR ||
|
||||
!file1.segments[i]->get_file_size() )
|
||||
continue;
|
||||
|
||||
ASSERT_NE( file1.segments[i]->get_data(), (const char*)0 );
|
||||
ASSERT_NE( file2.segments[i]->get_data(), (const char*)0 );
|
||||
|
||||
std::string pdata1( file1.segments[i]->get_data(),
|
||||
file1.segments[i]->get_data() +
|
||||
file1.segments[i]->get_file_size() );
|
||||
std::string pdata2( file2.segments[i]->get_data(),
|
||||
file2.segments[i]->get_data() +
|
||||
file2.segments[i]->get_file_size() );
|
||||
|
||||
// truncate the data if the header and the segment table is
|
||||
// part of the segment
|
||||
Elf64_Off afterPHDR =
|
||||
file1.get_segments_offset() +
|
||||
file1.get_segment_entry_size() * (Elf64_Off)file1.segments.size();
|
||||
if ( file1.segments[i]->get_offset() < afterPHDR ) {
|
||||
pdata1 = pdata1.substr( (unsigned int)afterPHDR );
|
||||
pdata2 = pdata2.substr( (unsigned int)afterPHDR );
|
||||
}
|
||||
|
||||
EXPECT_EQ_COLLECTIONS( pdata1.begin(), pdata1.end(), pdata2.begin(),
|
||||
pdata2.end() );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, write_obj_i386_32 )
|
||||
{
|
||||
EXPECT_EQ( true, write_obj_i386( false ) );
|
||||
output_test_stream output( "elf_examples/write_obj_i386_32_match.o", true,
|
||||
false );
|
||||
std::ifstream input( "elf_examples/write_obj_i386_32.o", std::ios::binary );
|
||||
output << input.rdbuf();
|
||||
BOOST_CHECK( output.match_pattern() );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, write_obj_i386_64 )
|
||||
{
|
||||
EXPECT_EQ( true, write_obj_i386( true ) );
|
||||
output_test_stream output( "elf_examples/write_obj_i386_64_match.o", true,
|
||||
false );
|
||||
std::ifstream input( "elf_examples/write_obj_i386_64.o", std::ios::binary );
|
||||
output << input.rdbuf();
|
||||
BOOST_CHECK( output.match_pattern() );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, write_exe_i386_32 )
|
||||
{
|
||||
const std::string generated_file( "elf_examples/write_exe_i386_32" );
|
||||
const std::string reference_file( "elf_examples/write_exe_i386_32_match" );
|
||||
EXPECT_EQ( true, write_exe_i386( generated_file, false ) );
|
||||
output_test_stream output( reference_file, true, false );
|
||||
std::ifstream input( generated_file, std::ios::binary );
|
||||
output << input.rdbuf();
|
||||
BOOST_CHECK_MESSAGE( output.match_pattern(), "Comparing " + generated_file +
|
||||
" and " + reference_file );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, elf_object_copy_32 )
|
||||
{
|
||||
checkObjestsAreEqual( "elf_examples/hello_32.o",
|
||||
"elf_examples/hello_32_copy.o" );
|
||||
checkObjestsAreEqual( "elf_examples/hello_64.o",
|
||||
"elf_examples/hello_64_copy.o" );
|
||||
checkObjestsAreEqual( "elf_examples/test_ppc.o",
|
||||
"elf_examples/test_ppc_copy.o" );
|
||||
checkObjestsAreEqual( "elf_examples/write_obj_i386_32.o",
|
||||
"elf_examples/write_obj_i386_32_copy.o" );
|
||||
checkObjestsAreEqual( "elf_examples/write_obj_i386_64.o",
|
||||
"elf_examples/write_obj_i386_64_copy.o" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, section_header_address_update )
|
||||
{
|
||||
elfio reader;
|
||||
|
||||
const std::string file_w_addr( "elf_examples/write_exe_i386_32_w_addr" );
|
||||
write_exe_i386( file_w_addr, false, true, 0x08048100 );
|
||||
reader.load( file_w_addr );
|
||||
section* sec = reader.sections[".text"];
|
||||
ASSERT_NE( sec, (section*)0 );
|
||||
EXPECT_EQ( sec->get_address(), 0x08048100 );
|
||||
|
||||
const std::string file_wo_addr( "elf_examples/write_exe_i386_32_wo_addr" );
|
||||
write_exe_i386( file_wo_addr, false, false, 0 );
|
||||
reader.load( file_wo_addr );
|
||||
sec = reader.sections[".text"];
|
||||
ASSERT_NE( sec, (section*)0 );
|
||||
EXPECT_EQ( sec->get_address(), 0x08048000 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, elfio_copy )
|
||||
{
|
||||
elfio e;
|
||||
|
||||
const std::string filename(
|
||||
"elf_examples/write_exe_i386_32_section_added" );
|
||||
write_exe_i386( filename, false, true, 0x08048100 );
|
||||
|
||||
e.load( filename );
|
||||
Elf_Half num = e.sections.size();
|
||||
//section* new_sec =
|
||||
e.sections.add( "new" );
|
||||
e.save( filename );
|
||||
EXPECT_EQ( num + 1, e.sections.size() );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, elf_exe_copy_64 )
|
||||
{
|
||||
checkExeAreEqual( "elf_examples/64bitLOAD.elf",
|
||||
"elf_examples/64bitLOAD_copy.elf" );
|
||||
checkExeAreEqual( "elf_examples/asm64", "elf_examples/asm64_copy" );
|
||||
checkExeAreEqual( "elf_examples/hello_64", "elf_examples/hello_64_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/main",
|
||||
// "elf_examples/main_copy" );
|
||||
// checkExeAreEqual( "elf_examples/ls",
|
||||
// "elf_examples/ls_copy" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, elf_exe_copy_32 )
|
||||
{
|
||||
checkExeAreEqual( "elf_examples/asm", "elf_examples/asm_copy" );
|
||||
checkExeAreEqual( "elf_examples/arm_v7m_test_debug.elf",
|
||||
"elf_examples/arm_v7m_test_debug_copy.elf" );
|
||||
checkExeAreEqual( "elf_examples/arm_v7m_test_release.elf",
|
||||
"elf_examples/arm_v7m_test_release_copy.elf" );
|
||||
checkExeAreEqual( "elf_examples/hello_32", "elf_examples/hello_32_copy" );
|
||||
checkExeAreEqual( "elf_examples/hello_arm", "elf_examples/hello_arm_copy" );
|
||||
checkExeAreEqual( "elf_examples/hello_arm_stripped",
|
||||
"elf_examples/hello_arm_stripped_copy" );
|
||||
checkExeAreEqual( "elf_examples/read_write_arm_elf32_input",
|
||||
"elf_examples/read_write_arm_elf32_input_copy" );
|
||||
checkExeAreEqual( "elf_examples/test_ppc", "elf_examples/test_ppc_copy" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, elf_exe_loadsave_ppc32big3 )
|
||||
{
|
||||
std::string in = "elf_examples/ppc-32bit-specimen3.elf";
|
||||
std::string out = "elf_examples/ppc-32bit-testcopy3.elf";
|
||||
elfio elf;
|
||||
ASSERT_EQ( elf.load( in ), true );
|
||||
ASSERT_EQ( elf.save( out ), true );
|
||||
|
||||
checkObjestsAreEqual( in, out );
|
||||
checkExeAreEqual( in, out, SEG_ALIGN );
|
||||
}
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, get_symbol_32 )
|
||||
{
|
||||
elfio elf;
|
||||
std::string name;
|
||||
ELFIO::Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
ELFIO::Elf_Half section_index;
|
||||
unsigned char other;
|
||||
std::string in = "elf_examples/hello_32";
|
||||
|
||||
ASSERT_EQ( elf.load( in ), true );
|
||||
section* psymsec = elf.sections[".symtab"];
|
||||
const symbol_section_accessor symbols( elf, psymsec );
|
||||
|
||||
EXPECT_EQ( true, symbols.get_symbol( 0x08048478, name, size, bind, type,
|
||||
section_index, other ) );
|
||||
EXPECT_EQ( "_IO_stdin_used", name );
|
||||
EXPECT_EQ( 14, section_index );
|
||||
EXPECT_EQ( 4, size );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, get_symbol_64 )
|
||||
{
|
||||
elfio elf;
|
||||
std::string name;
|
||||
ELFIO::Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
ELFIO::Elf_Half section_index;
|
||||
unsigned char other;
|
||||
std::string in = "elf_examples/hello_64";
|
||||
|
||||
ASSERT_EQ( elf.load( in ), true );
|
||||
section* psymsec = elf.sections[".symtab"];
|
||||
const symbol_section_accessor symbols( elf, psymsec );
|
||||
|
||||
EXPECT_EQ( true, symbols.get_symbol( 0x00400498, name, size, bind, type,
|
||||
section_index, other ) );
|
||||
EXPECT_EQ( "main", name );
|
||||
EXPECT_EQ( 12, section_index );
|
||||
EXPECT_EQ( 21, size );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, null_section_inside_segment )
|
||||
{
|
||||
// This test case checks the load/save of SHT_NULL sections in a segment
|
||||
// See https://github.com/serge1/ELFIO/issues/19
|
||||
//
|
||||
// Note: The test case checking the load/save of a segment containing no section
|
||||
// is covered by elf_object_copy_32: elf_examples/hello_32 has empty segments
|
||||
|
||||
// Create an ELF file with SHT_NULL sections at the beginning/middle/end of a segment
|
||||
elfio writer;
|
||||
writer.create( ELFCLASS32, ELFDATA2LSB );
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_type( ET_EXEC );
|
||||
writer.set_machine( EM_386 );
|
||||
// Create code section 1
|
||||
section* text_sec1 = writer.sections.add( ".text1" );
|
||||
text_sec1->set_type( SHT_PROGBITS );
|
||||
text_sec1->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec1->set_addr_align( 0x10 );
|
||||
text_sec1->set_address( 0x08048000 );
|
||||
char text[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
text_sec1->set_data( text, sizeof( text ) );
|
||||
// Create code section 2
|
||||
section* text_sec2 = writer.sections.add( ".text2" );
|
||||
text_sec2->set_type( SHT_PROGBITS );
|
||||
text_sec2->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec2->set_addr_align( 0x10 );
|
||||
text_sec2->set_address( 0x08048010 );
|
||||
text_sec2->set_data( text, sizeof( text ) );
|
||||
// Create null sections
|
||||
section* null_sec1 = writer.sections.add( "null" );
|
||||
null_sec1->set_type( SHT_NULL );
|
||||
null_sec1->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
null_sec1->set_address( 0x08048000 );
|
||||
section* null_sec2 = writer.sections.add( "null" );
|
||||
null_sec2->set_type( SHT_NULL );
|
||||
null_sec2->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
null_sec2->set_address( 0x08048010 );
|
||||
section* null_sec3 = writer.sections.add( "null" );
|
||||
null_sec3->set_type( SHT_NULL );
|
||||
null_sec3->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
null_sec3->set_address( 0x08048020 );
|
||||
// Create a loadable segment
|
||||
segment* text_seg = writer.segments.add();
|
||||
text_seg->set_type( PT_LOAD );
|
||||
text_seg->set_virtual_address( 0x08048000 );
|
||||
text_seg->set_physical_address( 0x08048000 );
|
||||
text_seg->set_flags( PF_X | PF_R );
|
||||
text_seg->set_align( 0x1000 );
|
||||
// Add sections into the loadable segment
|
||||
text_seg->add_section_index( null_sec1->get_index(),
|
||||
null_sec1->get_addr_align() );
|
||||
text_seg->add_section_index( text_sec1->get_index(),
|
||||
text_sec1->get_addr_align() );
|
||||
text_seg->add_section_index( null_sec2->get_index(),
|
||||
null_sec2->get_addr_align() );
|
||||
text_seg->add_section_index( text_sec2->get_index(),
|
||||
text_sec2->get_addr_align() );
|
||||
text_seg->add_section_index( null_sec3->get_index(),
|
||||
null_sec3->get_addr_align() );
|
||||
// Setup entry point
|
||||
writer.set_entry( 0x08048000 );
|
||||
// Create ELF file
|
||||
std::string f1 = "elf_examples/null_section_inside_segment1";
|
||||
std::string f2 = "elf_examples/null_section_inside_segment2";
|
||||
EXPECT_EQ( writer.save( f1 ), true );
|
||||
|
||||
// Load and check the ELF file created above
|
||||
elfio elf;
|
||||
EXPECT_EQ( elf.load( f1 ), true );
|
||||
EXPECT_EQ( elf.save( f2 ), true );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, invalid_file )
|
||||
{
|
||||
elfio elf;
|
||||
std::string name;
|
||||
ELFIO::Elf64_Addr value;
|
||||
ELFIO::Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
ELFIO::Elf_Half section_index;
|
||||
unsigned char other;
|
||||
std::string in = "elf_examples/crash.elf";
|
||||
|
||||
ASSERT_EQ( elf.load( in ), true );
|
||||
section* psymsec = elf.sections[".symtab"];
|
||||
ASSERT_NE( psymsec, (void*)0 );
|
||||
const symbol_section_accessor symbols( elf, psymsec );
|
||||
|
||||
EXPECT_EQ( true, symbols.get_symbol( "main", value, size, bind, type,
|
||||
section_index, other ) );
|
||||
EXPECT_EQ( 0x402560, value );
|
||||
|
||||
EXPECT_EQ( true, symbols.get_symbol( "frame_dummy", value, size, bind, type,
|
||||
section_index, other ) );
|
||||
EXPECT_EQ( 0x402550, value );
|
||||
|
||||
EXPECT_EQ( false, symbols.get_symbol( 0x00400498, name, size, bind, type,
|
||||
section_index, other ) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, rearrange_local_symbols )
|
||||
{
|
||||
std::string name = "";
|
||||
ELFIO::Elf64_Addr value = 0;
|
||||
ELFIO::Elf_Xword size = 0;
|
||||
unsigned char bind = STB_LOCAL;
|
||||
unsigned char type = STT_FUNC;
|
||||
ELFIO::Elf_Half section_index = 0;
|
||||
unsigned char other = 0;
|
||||
const std::string file_name = "elf_examples/test_symbols_order.elf";
|
||||
|
||||
elfio writer;
|
||||
writer.create( ELFCLASS64, ELFDATA2LSB );
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_type( ET_EXEC );
|
||||
writer.set_machine( EM_X86_64 );
|
||||
|
||||
section* str_sec = writer.sections.add( ".strtab" );
|
||||
str_sec->set_type( SHT_STRTAB );
|
||||
str_sec->set_addr_align( 0x1 );
|
||||
string_section_accessor str_writer( str_sec );
|
||||
|
||||
section* sym_sec = writer.sections.add( ".symtab" );
|
||||
sym_sec->set_type( SHT_SYMTAB );
|
||||
sym_sec->set_info( 0 );
|
||||
sym_sec->set_link( str_sec->get_index() );
|
||||
sym_sec->set_addr_align( 4 );
|
||||
sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
|
||||
symbol_section_accessor symbols( writer, sym_sec );
|
||||
|
||||
auto sym_num = symbols.get_symbols_num();
|
||||
|
||||
name = "Str1";
|
||||
bind = STB_GLOBAL;
|
||||
value = 1;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str2";
|
||||
bind = STB_LOCAL;
|
||||
value = 2;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str3";
|
||||
bind = STB_WEAK;
|
||||
value = 3;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str4";
|
||||
bind = STB_LOCAL;
|
||||
value = 4;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str5";
|
||||
bind = STB_LOCAL;
|
||||
value = 5;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str6";
|
||||
bind = STB_GLOBAL;
|
||||
value = 6;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str7";
|
||||
bind = STB_LOCAL;
|
||||
value = 7;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
name = "Str8";
|
||||
bind = STB_WEAK;
|
||||
value = 8;
|
||||
symbols.add_symbol( str_writer, name.c_str(), value, size, bind, type,
|
||||
other, section_index );
|
||||
|
||||
ASSERT_EQ( symbols.get_symbols_num(), sym_num + 9 );
|
||||
|
||||
symbols.arrange_local_symbols( [&]( Elf_Xword first, Elf_Xword ) -> void {
|
||||
static int counter = 0;
|
||||
EXPECT_EQ( first, ++counter );
|
||||
} );
|
||||
|
||||
ASSERT_EQ( writer.save( file_name ), true );
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
elfio reader;
|
||||
ASSERT_EQ( reader.load( file_name ), true );
|
||||
|
||||
auto psymsec = reader.sections[".symtab"];
|
||||
ASSERT_NE( psymsec, nullptr );
|
||||
|
||||
const_symbol_section_accessor rsymbols( reader, psymsec );
|
||||
|
||||
auto bound = psymsec->get_info();
|
||||
auto num = rsymbols.get_symbols_num();
|
||||
|
||||
EXPECT_LE( (Elf_Xword)bound, num );
|
||||
|
||||
// Check that all symbols are LOCAL until the bound value
|
||||
for ( Elf_Word i = 0; i < bound; i++ ) {
|
||||
rsymbols.get_symbol( i, name, value, size, bind, type, section_index,
|
||||
other );
|
||||
EXPECT_EQ( bind, (unsigned char)STB_LOCAL );
|
||||
}
|
||||
EXPECT_EQ( name, "Str7" );
|
||||
|
||||
// Check that all symbols are not LOCAL after the bound value
|
||||
for ( Elf_Word i = bound; i < num; i++ ) {
|
||||
rsymbols.get_symbol( i, name, value, size, bind, type, section_index,
|
||||
other );
|
||||
|
||||
EXPECT_NE( bind, (unsigned char)STB_LOCAL );
|
||||
}
|
||||
EXPECT_EQ( name, "Str8" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, rearrange_local_symbols_with_reallocation )
|
||||
{
|
||||
std::string name = "";
|
||||
ELFIO::Elf64_Addr value = 0;
|
||||
ELFIO::Elf_Xword size = 0;
|
||||
unsigned char bind = STB_LOCAL;
|
||||
unsigned char type = STT_FUNC;
|
||||
ELFIO::Elf_Half section_index = 0;
|
||||
unsigned char other = 0;
|
||||
const std::string file_name = "elf_examples/test_symbols_order.elf";
|
||||
|
||||
elfio writer;
|
||||
writer.create( ELFCLASS64, ELFDATA2LSB );
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_type( ET_EXEC );
|
||||
writer.set_machine( EM_X86_64 );
|
||||
|
||||
section* text_sec = writer.sections.add( ".text" );
|
||||
text_sec->set_type( SHT_PROGBITS );
|
||||
text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec->set_addr_align( 0x10 );
|
||||
|
||||
section* str_sec = writer.sections.add( ".strtab" );
|
||||
str_sec->set_type( SHT_STRTAB );
|
||||
str_sec->set_addr_align( 0x1 );
|
||||
string_section_accessor str_writer( str_sec );
|
||||
|
||||
section* sym_sec = writer.sections.add( ".symtab" );
|
||||
sym_sec->set_type( SHT_SYMTAB );
|
||||
sym_sec->set_info( 0 );
|
||||
sym_sec->set_link( str_sec->get_index() );
|
||||
sym_sec->set_addr_align( 4 );
|
||||
sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
|
||||
symbol_section_accessor symbols( writer, sym_sec );
|
||||
|
||||
name = "Str1";
|
||||
bind = STB_GLOBAL;
|
||||
value = 1;
|
||||
Elf_Word sym1 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
name = "Str2";
|
||||
bind = STB_LOCAL;
|
||||
value = 2;
|
||||
Elf_Word sym2 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
name = "Str3";
|
||||
bind = STB_WEAK;
|
||||
value = 3;
|
||||
Elf_Word sym3 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
name = "Str4";
|
||||
bind = STB_LOCAL;
|
||||
value = 4;
|
||||
Elf_Word sym4 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
name = "Str5";
|
||||
bind = STB_LOCAL;
|
||||
value = 5;
|
||||
Elf_Word sym5 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
name = "Str6";
|
||||
bind = STB_GLOBAL;
|
||||
value = 6;
|
||||
Elf_Word sym6 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
name = "Str7";
|
||||
bind = STB_LOCAL;
|
||||
value = 7;
|
||||
Elf_Word sym7 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
auto sym_num = symbols.get_symbols_num();
|
||||
|
||||
name = "Str8";
|
||||
bind = STB_WEAK;
|
||||
value = 8;
|
||||
Elf_Word sym8 = symbols.add_symbol( str_writer, name.c_str(), value, size,
|
||||
bind, type, other, section_index );
|
||||
|
||||
ASSERT_EQ( ( symbols.get_symbols_num() ), ( sym_num + 1 ) );
|
||||
|
||||
section* rel_sec = writer.sections.add( ".rel.text" );
|
||||
rel_sec->set_type( SHT_REL );
|
||||
rel_sec->set_info( text_sec->get_index() );
|
||||
rel_sec->set_addr_align( 0x4 );
|
||||
rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
|
||||
rel_sec->set_link( sym_sec->get_index() );
|
||||
|
||||
relocation_section_accessor rela( writer, rel_sec );
|
||||
// Add relocation entry (adjust address at offset 11)
|
||||
rela.add_entry( 1, sym1, R_386_RELATIVE );
|
||||
rela.add_entry( 8, sym8, R_386_RELATIVE );
|
||||
rela.add_entry( 6, sym6, R_386_RELATIVE );
|
||||
rela.add_entry( 2, sym2, R_386_RELATIVE );
|
||||
rela.add_entry( 3, sym3, R_386_RELATIVE );
|
||||
rela.add_entry( 8, sym8, R_386_RELATIVE );
|
||||
rela.add_entry( 7, sym7, R_386_RELATIVE );
|
||||
rela.add_entry( 2, sym2, R_386_RELATIVE );
|
||||
rela.add_entry( 11, sym1, R_386_RELATIVE );
|
||||
rela.add_entry( 18, sym8, R_386_RELATIVE );
|
||||
rela.add_entry( 16, sym6, R_386_RELATIVE );
|
||||
rela.add_entry( 12, sym2, R_386_RELATIVE );
|
||||
rela.add_entry( 13, sym3, R_386_RELATIVE );
|
||||
rela.add_entry( 17, sym7, R_386_RELATIVE );
|
||||
rela.add_entry( 14, sym4, R_386_RELATIVE );
|
||||
rela.add_entry( 15, sym5, R_386_RELATIVE );
|
||||
|
||||
std::vector<std::string> before;
|
||||
|
||||
for ( Elf_Word i = 0; i < rela.get_entries_num(); i++ ) {
|
||||
Elf64_Addr offset;
|
||||
Elf_Word symbol;
|
||||
unsigned rtype;
|
||||
Elf_Sxword addend;
|
||||
|
||||
rela.get_entry( i, offset, symbol, rtype, addend );
|
||||
symbols.get_symbol( symbol, name, value, size, bind, type,
|
||||
section_index, other );
|
||||
before.emplace_back( name );
|
||||
}
|
||||
|
||||
symbols.arrange_local_symbols( [&]( Elf_Xword first, Elf_Xword second ) {
|
||||
rela.swap_symbols( first, second );
|
||||
} );
|
||||
|
||||
ASSERT_EQ( writer.save( file_name ), true );
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
elfio reader;
|
||||
ASSERT_EQ( reader.load( file_name ), true );
|
||||
|
||||
auto prelsec = reader.sections[".rel.text"];
|
||||
auto psyms = reader.sections[".symtab"];
|
||||
|
||||
ASSERT_NE( prelsec, nullptr );
|
||||
ASSERT_NE( psyms, nullptr );
|
||||
|
||||
const_relocation_section_accessor rel( reader, prelsec );
|
||||
const_symbol_section_accessor syms( reader, psyms );
|
||||
|
||||
std::vector<std::string> after;
|
||||
|
||||
for ( Elf_Word i = 0; i < rel.get_entries_num(); i++ ) {
|
||||
Elf64_Addr offset;
|
||||
Elf_Word symbol;
|
||||
unsigned rtype;
|
||||
Elf_Sxword addend;
|
||||
|
||||
rel.get_entry( i, offset, symbol, rtype, addend );
|
||||
syms.get_symbol( symbol, name, value, size, bind, type, section_index,
|
||||
other );
|
||||
after.emplace_back( name );
|
||||
}
|
||||
|
||||
EXPECT_EQ( before, after );
|
||||
// EXPECT_EQ_COLLECTIONS( before.begin(), before.end(), after.begin(),
|
||||
// after.end() );
|
||||
}
|
||||
|
||||
TEST( ELFIOTest, detect_mismatched_section_segment_tables )
|
||||
{
|
||||
/* This file is a hacked copy of hello_32
|
||||
* The error introduced is:
|
||||
* Virtual address of segment 3 (0x804948c) conflicts
|
||||
* with address of section .ctors (0x804948e) at offset 0x48e
|
||||
*/
|
||||
std::string in = "elf_examples/mismatched_segments.elf";
|
||||
elfio elf;
|
||||
ASSERT_EQ( elf.load( in ), true );
|
||||
ASSERT_TRUE( elf.validate().length() > 0 );
|
||||
}
|
||||
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
Copyright (C) 2001-present 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, modinfo_read )
|
||||
{
|
||||
elfio reader;
|
||||
ASSERT_EQ( reader.load( "elf_examples/zavl.ko" ), true );
|
||||
|
||||
section* modinfo_sec = reader.sections[".modinfo"];
|
||||
ASSERT_NE( modinfo_sec, nullptr );
|
||||
|
||||
const_modinfo_section_accessor modinfo( modinfo_sec );
|
||||
ASSERT_EQ( modinfo.get_attribute_num(), (Elf_Word)9 );
|
||||
|
||||
struct
|
||||
{
|
||||
std::string field;
|
||||
std::string value;
|
||||
} attributes[] = { { "version", "0.8.3-1ubuntu12.1" },
|
||||
{ "license", "CDDL" },
|
||||
{ "author", "OpenZFS on Linux" },
|
||||
{ "description", "Generic AVL tree implementation" },
|
||||
{ "srcversion", "98E85778E754CF75DEF9E8E" },
|
||||
{ "depends", "spl" },
|
||||
{ "retpoline", "Y" },
|
||||
{ "name", "zavl" },
|
||||
{ "vermagic", "5.4.0-42-generic SMP mod_unload " } };
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( i, field, value );
|
||||
|
||||
EXPECT_EQ( field, attributes[i].field );
|
||||
EXPECT_EQ( value, attributes[i].value );
|
||||
}
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field = attributes[i].field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( field, value );
|
||||
|
||||
EXPECT_EQ( value, attributes[i].value );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, modinfo_write )
|
||||
{
|
||||
elfio writer;
|
||||
ASSERT_EQ( writer.load( "elf_examples/zavl.ko" ), true );
|
||||
|
||||
section* modinfo_sec = writer.sections[".modinfo"];
|
||||
ASSERT_NE( modinfo_sec, nullptr );
|
||||
|
||||
modinfo_section_accessor modinfo( modinfo_sec );
|
||||
ASSERT_EQ( modinfo.get_attribute_num(), (Elf_Word)9 );
|
||||
|
||||
modinfo.add_attribute( "test1", "value1" );
|
||||
modinfo.add_attribute( "test2", "value2" );
|
||||
|
||||
ASSERT_EQ( modinfo.get_attribute_num(), (Elf_Word)11 );
|
||||
|
||||
ASSERT_EQ( writer.save( "elf_examples/zavl_gen.ko" ), true );
|
||||
|
||||
elfio reader;
|
||||
ASSERT_EQ( reader.load( "elf_examples/zavl_gen.ko" ), true );
|
||||
|
||||
modinfo_sec = reader.sections[".modinfo"];
|
||||
ASSERT_NE( modinfo_sec, nullptr );
|
||||
|
||||
const_modinfo_section_accessor modinfo1( modinfo_sec );
|
||||
ASSERT_EQ( modinfo1.get_attribute_num(), (Elf_Word)11 );
|
||||
|
||||
struct
|
||||
{
|
||||
std::string field;
|
||||
std::string value;
|
||||
} attributes[] = { { "version", "0.8.3-1ubuntu12.1" },
|
||||
{ "license", "CDDL" },
|
||||
{ "author", "OpenZFS on Linux" },
|
||||
{ "description", "Generic AVL tree implementation" },
|
||||
{ "srcversion", "98E85778E754CF75DEF9E8E" },
|
||||
{ "depends", "spl" },
|
||||
{ "retpoline", "Y" },
|
||||
{ "name", "zavl" },
|
||||
{ "vermagic", "5.4.0-42-generic SMP mod_unload " },
|
||||
{ "test1", "value1" },
|
||||
{ "test2", "value2" } };
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( i, field, value );
|
||||
|
||||
EXPECT_EQ( field, attributes[i].field );
|
||||
EXPECT_EQ( value, attributes[i].value );
|
||||
}
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field = attributes[i].field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( field, value );
|
||||
|
||||
EXPECT_EQ( value, attributes[i].value );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, array_read_32 )
|
||||
{
|
||||
elfio reader;
|
||||
ASSERT_EQ( reader.load( "elf_examples/hello_32" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".ctors"];
|
||||
ASSERT_NE( array_sec, nullptr );
|
||||
|
||||
const_array_section_accessor<> array( reader, array_sec );
|
||||
ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
|
||||
Elf64_Addr addr;
|
||||
EXPECT_EQ( array.get_entry( 0, addr ), true );
|
||||
EXPECT_EQ( addr, 0xFFFFFFFF );
|
||||
EXPECT_EQ( array.get_entry( 1, addr ), true );
|
||||
EXPECT_EQ( addr, 0x00000000 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, array_read_64 )
|
||||
{
|
||||
elfio reader;
|
||||
ASSERT_EQ( reader.load( "elf_examples/hello_64" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".ctors"];
|
||||
ASSERT_NE( array_sec, nullptr );
|
||||
|
||||
const_array_section_accessor<Elf64_Addr> array( reader, array_sec );
|
||||
ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
|
||||
Elf64_Addr addr;
|
||||
EXPECT_EQ( array.get_entry( 0, addr ), true );
|
||||
EXPECT_EQ( addr, 0xFFFFFFFFFFFFFFFF );
|
||||
EXPECT_EQ( array.get_entry( 1, addr ), true );
|
||||
EXPECT_EQ( addr, 0x0000000000000000 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, init_array_read_64 )
|
||||
{
|
||||
elfio reader;
|
||||
Elf64_Addr addr;
|
||||
ASSERT_EQ( reader.load( "elf_examples/ctors" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".init_array"];
|
||||
ASSERT_NE( array_sec, nullptr );
|
||||
|
||||
const_array_section_accessor<Elf64_Addr> array( reader, array_sec );
|
||||
ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
|
||||
EXPECT_EQ( array.get_entry( 0, addr ), true );
|
||||
EXPECT_EQ( addr, 0x12C0 );
|
||||
EXPECT_EQ( array.get_entry( 1, addr ), true );
|
||||
EXPECT_EQ( addr, 0x149F );
|
||||
|
||||
array_sec = reader.sections[".fini_array"];
|
||||
ASSERT_NE( array_sec, nullptr );
|
||||
|
||||
array_section_accessor<Elf64_Addr> arrayf( reader, array_sec );
|
||||
ASSERT_EQ( arrayf.get_entries_num(), (Elf_Xword)1 );
|
||||
EXPECT_EQ( arrayf.get_entry( 0, addr ), true );
|
||||
EXPECT_EQ( addr, 0x1280 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, init_array_write_64 )
|
||||
{
|
||||
elfio reader;
|
||||
Elf64_Addr addr;
|
||||
ASSERT_EQ( reader.load( "elf_examples/ctors" ), true );
|
||||
|
||||
section* array_sec = reader.sections[".init_array"];
|
||||
ASSERT_NE( array_sec, nullptr );
|
||||
|
||||
array_section_accessor<Elf64_Addr> array( reader, array_sec );
|
||||
ASSERT_EQ( array.get_entries_num(), (Elf_Xword)2 );
|
||||
EXPECT_EQ( array.get_entry( 0, addr ), true );
|
||||
EXPECT_EQ( addr, 0x12C0 );
|
||||
EXPECT_EQ( array.get_entry( 1, addr ), true );
|
||||
EXPECT_EQ( addr, 0x149F );
|
||||
|
||||
array.add_entry( 0x12345678 );
|
||||
|
||||
ASSERT_EQ( array.get_entries_num(), (Elf_Xword)3 );
|
||||
EXPECT_EQ( array.get_entry( 0, addr ), true );
|
||||
EXPECT_EQ( addr, 0x12C0 );
|
||||
EXPECT_EQ( array.get_entry( 1, addr ), true );
|
||||
EXPECT_EQ( addr, 0x149F );
|
||||
EXPECT_EQ( array.get_entry( 2, addr ), true );
|
||||
EXPECT_EQ( addr, 0x12345678 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, test_hex )
|
||||
{
|
||||
EXPECT_EQ( to_hex_string( 1 ), "0x1" );
|
||||
EXPECT_EQ( to_hex_string( 10 ), "0xA" );
|
||||
EXPECT_EQ( to_hex_string( 0x12345678 ), "0x12345678" );
|
||||
EXPECT_EQ( to_hex_string( 0xFFFFFFFF ), "0xFFFFFFFF" );
|
||||
EXPECT_EQ( to_hex_string( 0xFFFFFFFFFFFFFFFF ), "0xFFFFFFFFFFFFFFFF" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, hash32_le )
|
||||
{
|
||||
elfio reader;
|
||||
// Load ELF data
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/ARMSCII-8.so" ), true );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
section* symsec = reader.sections[".dynsym"];
|
||||
symbol_section_accessor syms( reader, symsec );
|
||||
|
||||
for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
|
||||
ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, hash32_be )
|
||||
{
|
||||
elfio reader;
|
||||
// Load ELF data
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/test_ppc" ), true );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
section* symsec = reader.sections[".dynsym"];
|
||||
symbol_section_accessor syms( reader, symsec );
|
||||
|
||||
for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
|
||||
ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, gnu_hash32_le )
|
||||
{
|
||||
elfio reader;
|
||||
// Load ELF data
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/hello_32" ), true );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
section* symsec = reader.sections[".dynsym"];
|
||||
symbol_section_accessor syms( reader, symsec );
|
||||
|
||||
for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
|
||||
ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, gnu_hash64_le )
|
||||
{
|
||||
elfio reader;
|
||||
// Load ELF data
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/main" ), true );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
section* symsec = reader.sections[".dynsym"];
|
||||
symbol_section_accessor syms( reader, symsec );
|
||||
|
||||
for ( Elf_Xword i = 0; i < syms.get_symbols_num(); i++ ) {
|
||||
ASSERT_EQ( syms.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
EXPECT_EQ( syms.get_symbol( name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, gnu_version_64_le )
|
||||
{
|
||||
elfio reader;
|
||||
// Load ELF data
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/hello_64" ), true );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
|
||||
section* dynsym = reader.sections[".dynsym"];
|
||||
const_symbol_section_accessor dynsym_acc( reader, dynsym );
|
||||
|
||||
section* gnu_version = reader.sections[".gnu.version"];
|
||||
const_versym_section_accessor gnu_version_arr( gnu_version );
|
||||
|
||||
const section* gnu_version_r = reader.sections[".gnu.version_r"];
|
||||
const_versym_r_section_accessor gnu_version_r_arr( reader, gnu_version_r );
|
||||
|
||||
section* dynstr = reader.sections[".dynstr"];
|
||||
|
||||
EXPECT_EQ( gnu_version->get_link(), dynsym->get_index() );
|
||||
EXPECT_EQ( gnu_version_r->get_link(), dynstr->get_index() );
|
||||
|
||||
EXPECT_EQ( dynsym_acc.get_symbols_num(),
|
||||
gnu_version_arr.get_entries_num() );
|
||||
|
||||
for ( Elf64_Word i = 0; i < dynsym_acc.get_symbols_num(); i++ ) {
|
||||
ASSERT_EQ( dynsym_acc.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
|
||||
Elf64_Half verindex = 0;
|
||||
gnu_version_arr.get_entry( i, verindex );
|
||||
if ( i < 2 )
|
||||
EXPECT_EQ( 0, verindex );
|
||||
else
|
||||
EXPECT_EQ( 2, verindex );
|
||||
}
|
||||
|
||||
EXPECT_EQ( gnu_version_r_arr.get_entries_num(), 1 );
|
||||
|
||||
Elf_Half version;
|
||||
std::string file_name;
|
||||
Elf_Word hash;
|
||||
Elf_Half flags;
|
||||
Elf_Half vna_other;
|
||||
std::string dep_name;
|
||||
gnu_version_r_arr.get_entry( 0, version, file_name, hash, flags, vna_other,
|
||||
dep_name );
|
||||
EXPECT_EQ( version, 1 );
|
||||
EXPECT_EQ( file_name, "libc.so.6" );
|
||||
EXPECT_EQ( hash, 0x09691a75 );
|
||||
EXPECT_EQ( flags, 0 );
|
||||
EXPECT_EQ( vna_other, 2 );
|
||||
EXPECT_EQ( dep_name, "GLIBC_2.2.5" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, gnu_version_d_64_le )
|
||||
{
|
||||
elfio reader;
|
||||
// Load ELF data
|
||||
|
||||
ASSERT_EQ( reader.load( "elf_examples/libversion_d.so" ), true );
|
||||
|
||||
section* dynsym = reader.sections[".dynsym"];
|
||||
const_symbol_section_accessor dynsym_acc( reader, dynsym );
|
||||
|
||||
section* gnu_version = reader.sections[".gnu.version"];
|
||||
const_versym_section_accessor gnu_version_arr( gnu_version );
|
||||
|
||||
const section* gnu_version_d = reader.sections[".gnu.version_d"];
|
||||
const_versym_d_section_accessor gnu_version_d_arr( reader, gnu_version_d );
|
||||
|
||||
section* dynstr = reader.sections[".dynstr"];
|
||||
|
||||
EXPECT_EQ( gnu_version_d->get_link(), dynstr->get_index() );
|
||||
|
||||
EXPECT_EQ( dynsym_acc.get_symbols_num(),
|
||||
gnu_version_arr.get_entries_num() );
|
||||
|
||||
EXPECT_EQ( dynsym_acc.get_symbols_num(), 10 );
|
||||
|
||||
EXPECT_EQ( gnu_version_d_arr.get_entries_num(), 3 );
|
||||
|
||||
auto v_check = [&]( const std::string& symbol,
|
||||
const std::string& vername ) -> void {
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
Elf64_Half verindex;
|
||||
|
||||
for ( Elf64_Word i = 0; i < dynsym_acc.get_symbols_num(); i++ ) {
|
||||
ASSERT_EQ( dynsym_acc.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other ),
|
||||
true );
|
||||
|
||||
Elf64_Half vi;
|
||||
ASSERT_EQ( gnu_version_arr.get_entry( i, vi ), true );
|
||||
if ( name == symbol ) {
|
||||
verindex = vi;
|
||||
}
|
||||
}
|
||||
ASSERT_NE( verindex, 0 );
|
||||
|
||||
for ( Elf64_Word i = 0; i < gnu_version_d_arr.get_entries_num(); i++ ) {
|
||||
Elf_Half flags;
|
||||
Elf_Half version_index;
|
||||
Elf_Word hash;
|
||||
std::string dep_name;
|
||||
ASSERT_EQ( gnu_version_d_arr.get_entry( i, flags, version_index,
|
||||
hash, dep_name ),
|
||||
true );
|
||||
if ( version_index == verindex ) {
|
||||
EXPECT_EQ( flags, 0 );
|
||||
EXPECT_EQ( dep_name, vername );
|
||||
return;
|
||||
}
|
||||
}
|
||||
FAIL() << "version entry is not found";
|
||||
};
|
||||
v_check( "_Z20print_hello_world_v1v", "HELLO_1.0" );
|
||||
v_check( "_Z20print_hello_world_v2v", "HELLO_2.0" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TEST( ELFIOTest, gnu_version_64_le_modify )
|
||||
// {
|
||||
// elfio reader;
|
||||
// // Load ELF data
|
||||
|
||||
// ASSERT_EQ( reader.load( "elf_examples/hello_64" ), true );
|
||||
|
||||
// std::string name;
|
||||
// Elf64_Addr value;
|
||||
// Elf_Xword size;
|
||||
// unsigned char bind;
|
||||
// unsigned char type;
|
||||
// Elf_Half section_index;
|
||||
// unsigned char other;
|
||||
|
||||
// section* gnu_version = reader.sections[".gnu.version"];
|
||||
// versym_section_accessor gnu_version_arr( gnu_version );
|
||||
|
||||
// section* gnu_version_r = reader.sections[".gnu.version_r"];
|
||||
// versym_r_section_accessor gnu_version_r_arr( reader, gnu_version_r );
|
||||
|
||||
// auto orig_entries_num = gnu_version_arr.get_entries_num();
|
||||
// Elf64_Word i = 0;
|
||||
// for ( i = 0; i < orig_entries_num; i++ ) {
|
||||
// gnu_version_arr.modify_entry( i, i + 10 );
|
||||
// }
|
||||
// gnu_version_arr.add_entry( i + 10 );
|
||||
// gnu_version_arr.add_entry( i + 11 );
|
||||
// EXPECT_EQ( orig_entries_num + 2,
|
||||
// gnu_version_arr.get_entries_num() );
|
||||
|
||||
// for ( i = 0; i < gnu_version_arr.get_entries_num(); i++ ) {
|
||||
// Elf_Half value;
|
||||
// gnu_version_arr.get_entry( i, value );
|
||||
// EXPECT_EQ( i + 10, value );
|
||||
// }
|
||||
// }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST( ELFIOTest, move_constructor_and_assignment )
|
||||
{
|
||||
elfio r1;
|
||||
|
||||
// Load ELF data
|
||||
ASSERT_EQ( r1.load( "elf_examples/hello_64" ), true );
|
||||
Elf64_Addr entry = r1.get_entry();
|
||||
std::string sec_name = r1.sections[".text"]->get_name();
|
||||
Elf_Xword seg_size = r1.segments[1]->get_memory_size();
|
||||
|
||||
// Move to a vector element
|
||||
std::vector<elfio> v;
|
||||
v.emplace_back( std::move( r1 ) );
|
||||
EXPECT_EQ( v[0].get_entry(), entry );
|
||||
EXPECT_EQ( v[0].sections[".text"]->get_name(), sec_name );
|
||||
EXPECT_EQ( v[0].segments[1]->get_memory_size(), seg_size );
|
||||
|
||||
elfio r2;
|
||||
r2 = std::move( v[0] );
|
||||
EXPECT_EQ( r2.get_entry(), entry );
|
||||
EXPECT_EQ( r2.sections[".text"]->get_name(), sec_name );
|
||||
EXPECT_EQ( r2.segments[1]->get_memory_size(), seg_size );
|
||||
}
|
||||
|
||||
TEST( ELFIOTest, address_translation_test )
|
||||
{
|
||||
std::vector<address_translation> ranges;
|
||||
|
||||
ranges.emplace_back( 0, 100, 500 );
|
||||
ranges.emplace_back( 500, 1000, 1000 );
|
||||
ranges.emplace_back( 2000, 1000, 3000 );
|
||||
|
||||
address_translator tr;
|
||||
tr.set_address_translation( ranges );
|
||||
|
||||
EXPECT_EQ( tr[0], 500 );
|
||||
EXPECT_EQ( tr[510], 1010 );
|
||||
EXPECT_EQ( tr[1710], 1710 );
|
||||
EXPECT_EQ( tr[2710], 3710 );
|
||||
EXPECT_EQ( tr[3710], 3710 );
|
||||
|
||||
ranges.clear();
|
||||
tr.set_address_translation( ranges );
|
||||
|
||||
EXPECT_EQ( tr[0], 0 );
|
||||
EXPECT_EQ( tr[510], 510 );
|
||||
EXPECT_EQ( tr[1710], 1710 );
|
||||
EXPECT_EQ( tr[2710], 2710 );
|
||||
EXPECT_EQ( tr[3710], 3710 );
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
!<arch>
|
||||
@@ -0,0 +1,20 @@
|
||||
!<arkh>
|
||||
hello.c/ 0 0 0 644 45 `
|
||||
int my_func(int param)
|
||||
{
|
||||
return 2*param;
|
||||
}
|
||||
|
||||
hello2.c/ 0 0 0 644 7 `
|
||||
Hello2
|
||||
|
||||
hello3.c/ 0 0 0 644 8 `
|
||||
Hello23
|
||||
hello4.c/ 0 0 0 644 10 `
|
||||
Hello24==
|
||||
hello41.c/ 0 0 0 644 11 `
|
||||
Hello24==
|
||||
|
||||
|
||||
hello5.c/ 0 0 0 644 8 `
|
||||
Hello25
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
!<arch>
|
||||
// 98 `
|
||||
a_file_with_very_long_name.txt/
|
||||
a_file_with_very_long_name2.txt/
|
||||
a_file_with_very_long_name3.txt/
|
||||
hello.c/ 0 0 0 644 45 `
|
||||
int my_func(int param)
|
||||
{
|
||||
return 2*param;
|
||||
}
|
||||
|
||||
hello2.c/ 0 0 0 644 7 `
|
||||
Hello2
|
||||
|
||||
hello3.c/ 0 0 0 644 8 `
|
||||
Hello23
|
||||
hello4.c/ 0 0 0 644 10 `
|
||||
Hello24==
|
||||
hello41.c/ 0 0 0 644 11 `
|
||||
Hello24==
|
||||
|
||||
|
||||
hello5.c/ 0 0 0 644 8 `
|
||||
Hello25
|
||||
/0 0 0 0 644 6 `
|
||||
Hello
|
||||
/32 0 0 0 644 6 `
|
||||
Hello
|
||||
/65 0 0 0 644 6 `
|
||||
Hello
|
||||
@@ -0,0 +1,20 @@
|
||||
!<arch>
|
||||
hello.c/ 0 0 0 644 45 `
|
||||
int my_func(int param)
|
||||
{
|
||||
return 2*param;
|
||||
}
|
||||
|
||||
hello2.c/ 0 0 0 644 7 `
|
||||
Hello2
|
||||
|
||||
hello3.c/ 0 0 0 644 8 `
|
||||
Hello23
|
||||
hello4.c/ 0 0 0 644 10 `
|
||||
Hello24==
|
||||
hello41.c/ 0 0 0 644 11 `
|
||||
Hello24==
|
||||
|
||||
|
||||
hello5.c/ 0 0 0 644 8 `
|
||||
Hello25
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
1 ; nasm -f elf hello.asm # this will produce hello.o ELF object file
|
||||
2 ; ld -s -o hello hello.o # this will produce hello executable
|
||||
3
|
||||
4 section .text
|
||||
5 global _start ;must be declared for linker (ld)
|
||||
6
|
||||
7 _start: ;tell linker entry point
|
||||
8
|
||||
9 00000000 BA0E000000 mov edx,len ;message length
|
||||
10 00000005 B9[00000000] mov ecx,msg ;message to write
|
||||
11 0000000A BB01000000 mov ebx,1 ;file descriptor (stdout)
|
||||
12 0000000F B804000000 mov eax,4 ;system call number (sys_write)
|
||||
13 00000014 CD80 int 0x80 ;call kernel
|
||||
14
|
||||
15 00000016 B801000000 mov eax,1 ;system call number (sys_exit)
|
||||
16 0000001B CD80 int 0x80 ;call kernel
|
||||
17
|
||||
18 section .data
|
||||
19
|
||||
20 00000000 48656C6C6F2C20776F- msg db 'Hello, world!',0xa ;our dear string
|
||||
21 00000009 726C64210A
|
||||
22 len equ $ - msg ;length of our dear string
|
||||
23
|
||||
Binary file not shown.
@@ -0,0 +1,51 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF32
|
||||
Data: 2's complement, little endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: EXEC (Executable file)
|
||||
Machine: Intel 80386
|
||||
Version: 0x1
|
||||
Entry point address: 0x8048080
|
||||
Start of program headers: 52 (bytes into file)
|
||||
Start of section headers: 200 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 52 (bytes)
|
||||
Size of program headers: 32 (bytes)
|
||||
Number of program headers: 2
|
||||
Size of section headers: 40 (bytes)
|
||||
Number of section headers: 4
|
||||
Section header string table index: 3
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
|
||||
[ 0] NULL 00000000 000000 000000 00 0 0 0
|
||||
[ 1] .text PROGBITS 08048080 000080 00001d 00 AX 0 0 16
|
||||
[ 2] .data PROGBITS 080490a0 0000a0 00000e 00 WA 0 0 4
|
||||
[ 3] .shstrtab STRTAB 00000000 0000ae 000017 00 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
Program Headers:
|
||||
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
LOAD 0x000000 0x08048000 0x08048000 0x0009d 0x0009d R E 0x1000
|
||||
LOAD 0x0000a0 0x080490a0 0x080490a0 0x0000e 0x0000e RW 0x1000
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00 .text
|
||||
01 .data
|
||||
|
||||
There is no dynamic section in this file.
|
||||
|
||||
There are no relocations in this file.
|
||||
|
||||
The decoding of unwind sections for machine type Intel 80386 is not currently supported.
|
||||
|
||||
No version information found in this file.
|
||||
@@ -0,0 +1,22 @@
|
||||
; nasm -f elf hello.asm # this will produce hello.o ELF object file
|
||||
; ld -s -o hello hello.o # this will produce hello executable
|
||||
|
||||
section .text
|
||||
global _start ;must be declared for linker (ld)
|
||||
|
||||
_start: ;tell linker entry point
|
||||
|
||||
mov edx,len ;message length
|
||||
mov ecx,msg ;message to write
|
||||
mov ebx,1 ;file descriptor (stdout)
|
||||
mov eax,4 ;system call number (sys_write)
|
||||
int 0x80 ;call kernel
|
||||
|
||||
mov eax,1 ;system call number (sys_exit)
|
||||
int 0x80 ;call kernel
|
||||
|
||||
section .data
|
||||
|
||||
msg db 'Hello, world!',0xa ;our dear string
|
||||
len equ $ - msg ;length of our dear string
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
1 ; nasm -f elf hello.asm # this will produce hello.o ELF object file
|
||||
2 ; ld -s -o hello hello.o # this will produce hello executable
|
||||
3
|
||||
4 section .text
|
||||
5 global _start ;must be declared for linker (ld)
|
||||
6
|
||||
7 _start: ;tell linker entry point
|
||||
8
|
||||
9 00000000 BA0E000000 mov edx,len ;message length
|
||||
10 00000005 B9[00000000] mov ecx,msg ;message to write
|
||||
11 0000000A BB01000000 mov ebx,1 ;file descriptor (stdout)
|
||||
12 0000000F B804000000 mov eax,4 ;system call number (sys_write)
|
||||
13 00000014 CD80 int 0x80 ;call kernel
|
||||
14
|
||||
15 00000016 B801000000 mov eax,1 ;system call number (sys_exit)
|
||||
16 0000001B CD80 int 0x80 ;call kernel
|
||||
17
|
||||
18 section .data
|
||||
19
|
||||
20 00000000 48656C6C6F2C20776F- msg db 'Hello, world!',0xa ;our dear string
|
||||
21 00000009 726C64210A
|
||||
22 len equ $ - msg ;length of our dear string
|
||||
23
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf( "Hello\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,211 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF32
|
||||
Data: 2's complement, little endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: EXEC (Executable file)
|
||||
Machine: Intel 80386
|
||||
Version: 0x1
|
||||
Entry point address: 0x80482b0
|
||||
Start of program headers: 52 (bytes into file)
|
||||
Start of section headers: 1912 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 52 (bytes)
|
||||
Size of program headers: 32 (bytes)
|
||||
Number of program headers: 7
|
||||
Size of section headers: 40 (bytes)
|
||||
Number of section headers: 28
|
||||
Section header string table index: 25
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
|
||||
[ 0] NULL 00000000 000000 000000 00 0 0 0
|
||||
[ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1
|
||||
[ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4
|
||||
[ 3] .gnu.hash GNU_HASH 08048148 000148 000020 04 A 4 0 4
|
||||
[ 4] .dynsym DYNSYM 08048168 000168 000050 10 A 5 1 4
|
||||
[ 5] .dynstr STRTAB 080481b8 0001b8 00004a 00 A 0 0 1
|
||||
[ 6] .gnu.version VERSYM 08048202 000202 00000a 02 A 4 0 2
|
||||
[ 7] .gnu.version_r VERNEED 0804820c 00020c 000020 00 A 5 1 4
|
||||
[ 8] .rel.dyn REL 0804822c 00022c 000008 08 A 4 0 4
|
||||
[ 9] .rel.plt REL 08048234 000234 000018 08 A 4 11 4
|
||||
[10] .init PROGBITS 0804824c 00024c 000017 00 AX 0 0 4
|
||||
[11] .plt PROGBITS 08048264 000264 000040 04 AX 0 0 4
|
||||
[12] .text PROGBITS 080482b0 0002b0 0001a8 00 AX 0 0 16
|
||||
[13] .fini PROGBITS 08048458 000458 00001c 00 AX 0 0 4
|
||||
[14] .rodata PROGBITS 08048474 000474 000012 00 A 0 0 4
|
||||
[15] .eh_frame PROGBITS 08048488 000488 000004 00 A 0 0 4
|
||||
[16] .ctors PROGBITS 0804948c 00048c 000008 00 WA 0 0 4
|
||||
[17] .dtors PROGBITS 08049494 000494 000008 00 WA 0 0 4
|
||||
[18] .jcr PROGBITS 0804949c 00049c 000004 00 WA 0 0 4
|
||||
[19] .dynamic DYNAMIC 080494a0 0004a0 0000c8 08 WA 5 0 4
|
||||
[20] .got PROGBITS 08049568 000568 000004 04 WA 0 0 4
|
||||
[21] .got.plt PROGBITS 0804956c 00056c 000018 04 WA 0 0 4
|
||||
[22] .data PROGBITS 08049584 000584 000004 00 WA 0 0 4
|
||||
[23] .bss NOBITS 08049588 000588 000008 00 WA 0 0 4
|
||||
[24] .comment PROGBITS 00000000 000588 000114 00 0 0 1
|
||||
[25] .shstrtab STRTAB 00000000 00069c 0000db 00 0 0 1
|
||||
[26] .symtab SYMTAB 00000000 000bd8 000440 10 27 48 4
|
||||
[27] .strtab STRTAB 00000000 001018 000259 00 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
Program Headers:
|
||||
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4
|
||||
INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1
|
||||
[Requesting program interpreter: /lib/ld-linux.so.2]
|
||||
LOAD 0x000000 0x08048000 0x08048000 0x0048c 0x0048c R E 0x1000
|
||||
LOAD 0x00048c 0x0804948c 0x0804948c 0x000fc 0x00104 RW 0x1000
|
||||
DYNAMIC 0x0004a0 0x080494a0 0x080494a0 0x000c8 0x000c8 RW 0x4
|
||||
NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4
|
||||
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00
|
||||
01 .interp
|
||||
02 .interp .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
|
||||
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
|
||||
04 .dynamic
|
||||
05 .note.ABI-tag
|
||||
06
|
||||
|
||||
Dynamic section at offset 0x4a0 contains 20 entries:
|
||||
Tag Type Name/Value
|
||||
0x00000001 (NEEDED) Shared library: [libc.so.6]
|
||||
0x0000000c (INIT) 0x804824c
|
||||
0x0000000d (FINI) 0x8048458
|
||||
0x6ffffef5 (GNU_HASH) 0x8048148
|
||||
0x00000005 (STRTAB) 0x80481b8
|
||||
0x00000006 (SYMTAB) 0x8048168
|
||||
0x0000000a (STRSZ) 74 (bytes)
|
||||
0x0000000b (SYMENT) 16 (bytes)
|
||||
0x00000015 (DEBUG) 0x0
|
||||
0x00000003 (PLTGOT) 0x804956c
|
||||
0x00000002 (PLTRELSZ) 24 (bytes)
|
||||
0x00000014 (PLTREL) REL
|
||||
0x00000017 (JMPREL) 0x8048234
|
||||
0x00000011 (REL) 0x804822c
|
||||
0x00000012 (RELSZ) 8 (bytes)
|
||||
0x00000013 (RELENT) 8 (bytes)
|
||||
0x6ffffffe (VERNEED) 0x804820c
|
||||
0x6fffffff (VERNEEDNUM) 1
|
||||
0x6ffffff0 (VERSYM) 0x8048202
|
||||
0x00000000 (NULL) 0x0
|
||||
|
||||
Relocation section '.rel.dyn' at offset 0x22c contains 1 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
08049568 00000106 R_386_GLOB_DAT 00000000 __gmon_start__
|
||||
|
||||
Relocation section '.rel.plt' at offset 0x234 contains 3 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
08049578 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__
|
||||
0804957c 00000207 R_386_JUMP_SLOT 00000000 __libc_start_main
|
||||
08049580 00000307 R_386_JUMP_SLOT 00000000 puts
|
||||
|
||||
There are no unwind sections in this file.
|
||||
|
||||
Symbol table '.dynsym' contains 5 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
|
||||
2: 00000000 415 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2)
|
||||
3: 00000000 399 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0 (2)
|
||||
4: 08048478 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used
|
||||
|
||||
Symbol table '.symtab' contains 68 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 08048114 0 SECTION LOCAL DEFAULT 1
|
||||
2: 08048128 0 SECTION LOCAL DEFAULT 2
|
||||
3: 08048148 0 SECTION LOCAL DEFAULT 3
|
||||
4: 08048168 0 SECTION LOCAL DEFAULT 4
|
||||
5: 080481b8 0 SECTION LOCAL DEFAULT 5
|
||||
6: 08048202 0 SECTION LOCAL DEFAULT 6
|
||||
7: 0804820c 0 SECTION LOCAL DEFAULT 7
|
||||
8: 0804822c 0 SECTION LOCAL DEFAULT 8
|
||||
9: 08048234 0 SECTION LOCAL DEFAULT 9
|
||||
10: 0804824c 0 SECTION LOCAL DEFAULT 10
|
||||
11: 08048264 0 SECTION LOCAL DEFAULT 11
|
||||
12: 080482b0 0 SECTION LOCAL DEFAULT 12
|
||||
13: 08048458 0 SECTION LOCAL DEFAULT 13
|
||||
14: 08048474 0 SECTION LOCAL DEFAULT 14
|
||||
15: 08048488 0 SECTION LOCAL DEFAULT 15
|
||||
16: 0804948c 0 SECTION LOCAL DEFAULT 16
|
||||
17: 08049494 0 SECTION LOCAL DEFAULT 17
|
||||
18: 0804949c 0 SECTION LOCAL DEFAULT 18
|
||||
19: 080494a0 0 SECTION LOCAL DEFAULT 19
|
||||
20: 08049568 0 SECTION LOCAL DEFAULT 20
|
||||
21: 0804956c 0 SECTION LOCAL DEFAULT 21
|
||||
22: 08049584 0 SECTION LOCAL DEFAULT 22
|
||||
23: 08049588 0 SECTION LOCAL DEFAULT 23
|
||||
24: 00000000 0 SECTION LOCAL DEFAULT 24
|
||||
25: 080482d4 0 FUNC LOCAL DEFAULT 12 call_gmon_start
|
||||
26: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
|
||||
27: 0804948c 0 OBJECT LOCAL DEFAULT 16 __CTOR_LIST__
|
||||
28: 08049494 0 OBJECT LOCAL DEFAULT 17 __DTOR_LIST__
|
||||
29: 0804949c 0 OBJECT LOCAL DEFAULT 18 __JCR_LIST__
|
||||
30: 08049588 4 OBJECT LOCAL DEFAULT 23 dtor_idx.5805
|
||||
31: 0804958c 1 OBJECT LOCAL DEFAULT 23 completed.5803
|
||||
32: 08048300 0 FUNC LOCAL DEFAULT 12 __do_global_dtors_aux
|
||||
33: 08048360 0 FUNC LOCAL DEFAULT 12 frame_dummy
|
||||
34: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
|
||||
35: 08049490 0 OBJECT LOCAL DEFAULT 16 __CTOR_END__
|
||||
36: 08048488 0 OBJECT LOCAL DEFAULT 15 __FRAME_END__
|
||||
37: 0804949c 0 OBJECT LOCAL DEFAULT 18 __JCR_END__
|
||||
38: 08048430 0 FUNC LOCAL DEFAULT 12 __do_global_ctors_aux
|
||||
39: 00000000 0 FILE LOCAL DEFAULT ABS hello.c
|
||||
40: 0804948c 0 NOTYPE LOCAL HIDDEN 16 __preinit_array_start
|
||||
41: 0804948c 0 NOTYPE LOCAL HIDDEN 16 __fini_array_end
|
||||
42: 0804956c 0 OBJECT LOCAL HIDDEN 21 _GLOBAL_OFFSET_TABLE_
|
||||
43: 0804948c 0 NOTYPE LOCAL HIDDEN 16 __preinit_array_end
|
||||
44: 0804948c 0 NOTYPE LOCAL HIDDEN 16 __fini_array_start
|
||||
45: 0804948c 0 NOTYPE LOCAL HIDDEN 16 __init_array_end
|
||||
46: 0804948c 0 NOTYPE LOCAL HIDDEN 16 __init_array_start
|
||||
47: 080494a0 0 OBJECT LOCAL HIDDEN 19 _DYNAMIC
|
||||
48: 08049584 0 NOTYPE WEAK DEFAULT 22 data_start
|
||||
49: 080483b0 5 FUNC GLOBAL DEFAULT 12 __libc_csu_fini
|
||||
50: 080482b0 0 FUNC GLOBAL DEFAULT 12 _start
|
||||
51: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
|
||||
52: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
|
||||
53: 08048474 4 OBJECT GLOBAL DEFAULT 14 _fp_hw
|
||||
54: 08048458 0 FUNC GLOBAL DEFAULT 13 _fini
|
||||
55: 00000000 415 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
|
||||
56: 08048478 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used
|
||||
57: 08049584 0 NOTYPE GLOBAL DEFAULT 22 __data_start
|
||||
58: 0804847c 0 OBJECT GLOBAL HIDDEN 14 __dso_handle
|
||||
59: 08049498 0 OBJECT GLOBAL HIDDEN 17 __DTOR_END__
|
||||
60: 080483c0 105 FUNC GLOBAL DEFAULT 12 __libc_csu_init
|
||||
61: 08049588 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
62: 08049590 0 NOTYPE GLOBAL DEFAULT ABS _end
|
||||
63: 00000000 399 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.0
|
||||
64: 08049588 0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
65: 08048429 0 FUNC GLOBAL HIDDEN 12 __i686.get_pc_thunk.bx
|
||||
66: 08048384 43 FUNC GLOBAL DEFAULT 12 main
|
||||
67: 0804824c 0 FUNC GLOBAL DEFAULT 10 _init
|
||||
|
||||
Histogram for `.gnu.hash' bucket list length (total of 2 buckets):
|
||||
Length Number % of total Coverage
|
||||
0 1 ( 50.0%)
|
||||
1 1 ( 50.0%) 100.0%
|
||||
|
||||
Version symbols section '.gnu.version' contains 5 entries:
|
||||
Addr: 0000000008048202 Offset: 0x000202 Link: 4 (.dynsym)
|
||||
000: 0 (*local*) 0 (*local*) 2 (GLIBC_2.0) 2 (GLIBC_2.0)
|
||||
004: 1 (*global*)
|
||||
|
||||
Version needs section '.gnu.version_r' contains 1 entries:
|
||||
Addr: 0x000000000804820c Offset: 0x00020c Link to section: 5 (.dynstr)
|
||||
000000: Version: 1 File: libc.so.6 Cnt: 1
|
||||
0x0010: Name: GLIBC_2.0 Flags: none Version: 2
|
||||
|
||||
Notes at offset 0x00000128 with length 0x00000020:
|
||||
Owner Data size Description
|
||||
GNU 0x00000010 NT_VERSION (version)
|
||||
@@ -0,0 +1,64 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF32
|
||||
Data: 2's complement, little endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: REL (Relocatable file)
|
||||
Machine: Intel 80386
|
||||
Version: 0x1
|
||||
Entry point address: 0x0
|
||||
Start of program headers: 0 (bytes into file)
|
||||
Start of section headers: 232 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 52 (bytes)
|
||||
Size of program headers: 0 (bytes)
|
||||
Number of program headers: 0
|
||||
Size of section headers: 40 (bytes)
|
||||
Number of section headers: 11
|
||||
Section header string table index: 8
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
|
||||
[ 0] NULL 00000000 000000 000000 00 0 0 0
|
||||
[ 1] .text PROGBITS 00000000 000034 00002b 00 AX 0 0 4
|
||||
[ 2] .rel.text REL 00000000 000354 000010 08 9 1 4
|
||||
[ 3] .data PROGBITS 00000000 000060 000000 00 WA 0 0 4
|
||||
[ 4] .bss NOBITS 00000000 000060 000000 00 WA 0 0 4
|
||||
[ 5] .rodata PROGBITS 00000000 000060 000006 00 A 0 0 1
|
||||
[ 6] .comment PROGBITS 00000000 000066 00002e 00 0 0 1
|
||||
[ 7] .note.GNU-stack PROGBITS 00000000 000094 000000 00 0 0 1
|
||||
[ 8] .shstrtab STRTAB 00000000 000094 000051 00 0 0 1
|
||||
[ 9] .symtab SYMTAB 00000000 0002a0 0000a0 10 10 8 4
|
||||
[10] .strtab STRTAB 00000000 000340 000013 00 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
There are no program headers in this file.
|
||||
|
||||
Relocation section '.rel.text' at offset 0x354 contains 2 entries:
|
||||
Offset Info Type Sym.Value Sym. Name
|
||||
00000014 00000501 R_386_32 00000000 .rodata
|
||||
00000019 00000902 R_386_PC32 00000000 puts
|
||||
|
||||
There are no unwind sections in this file.
|
||||
|
||||
Symbol table '.symtab' contains 10 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 00000000 0 FILE LOCAL DEFAULT ABS hello.c
|
||||
2: 00000000 0 SECTION LOCAL DEFAULT 1
|
||||
3: 00000000 0 SECTION LOCAL DEFAULT 3
|
||||
4: 00000000 0 SECTION LOCAL DEFAULT 4
|
||||
5: 00000000 0 SECTION LOCAL DEFAULT 5
|
||||
6: 00000000 0 SECTION LOCAL DEFAULT 7
|
||||
7: 00000000 0 SECTION LOCAL DEFAULT 6
|
||||
8: 00000000 43 FUNC GLOBAL DEFAULT 1 main
|
||||
9: 00000000 0 NOTYPE GLOBAL DEFAULT UND puts
|
||||
|
||||
No version information found in this file.
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,244 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF64
|
||||
Data: 2's complement, little endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: EXEC (Executable file)
|
||||
Machine: Advanced Micro Devices X86-64
|
||||
Version: 0x1
|
||||
Entry point address: 0x4003c0
|
||||
Start of program headers: 64 (bytes into file)
|
||||
Start of section headers: 2656 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 64 (bytes)
|
||||
Size of program headers: 56 (bytes)
|
||||
Number of program headers: 8
|
||||
Size of section headers: 64 (bytes)
|
||||
Number of section headers: 29
|
||||
Section header string table index: 26
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Address Offset
|
||||
Size EntSize Flags Link Info Align
|
||||
[ 0] NULL 0000000000000000 00000000
|
||||
0000000000000000 0000000000000000 0 0 0
|
||||
[ 1] .interp PROGBITS 0000000000400200 00000200
|
||||
000000000000001c 0000000000000000 A 0 0 1
|
||||
[ 2] .note.ABI-tag NOTE 000000000040021c 0000021c
|
||||
0000000000000020 0000000000000000 A 0 0 4
|
||||
[ 3] .gnu.hash GNU_HASH 0000000000400240 00000240
|
||||
000000000000001c 0000000000000000 A 4 0 8
|
||||
[ 4] .dynsym DYNSYM 0000000000400260 00000260
|
||||
0000000000000060 0000000000000018 A 5 1 8
|
||||
[ 5] .dynstr STRTAB 00000000004002c0 000002c0
|
||||
000000000000003d 0000000000000000 A 0 0 1
|
||||
[ 6] .gnu.version VERSYM 00000000004002fe 000002fe
|
||||
0000000000000008 0000000000000002 A 4 0 2
|
||||
[ 7] .gnu.version_r VERNEED 0000000000400308 00000308
|
||||
0000000000000020 0000000000000000 A 5 1 8
|
||||
[ 8] .rela.dyn RELA 0000000000400328 00000328
|
||||
0000000000000018 0000000000000018 A 4 0 8
|
||||
[ 9] .rela.plt RELA 0000000000400340 00000340
|
||||
0000000000000030 0000000000000018 A 4 11 8
|
||||
[10] .init PROGBITS 0000000000400370 00000370
|
||||
0000000000000018 0000000000000000 AX 0 0 4
|
||||
[11] .plt PROGBITS 0000000000400388 00000388
|
||||
0000000000000030 0000000000000010 AX 0 0 4
|
||||
[12] .text PROGBITS 00000000004003c0 000003c0
|
||||
00000000000001c8 0000000000000000 AX 0 0 16
|
||||
[13] .fini PROGBITS 0000000000400588 00000588
|
||||
000000000000000e 0000000000000000 AX 0 0 4
|
||||
[14] .rodata PROGBITS 0000000000400598 00000598
|
||||
0000000000000016 0000000000000000 A 0 0 8
|
||||
[15] .eh_frame_hdr PROGBITS 00000000004005b0 000005b0
|
||||
0000000000000024 0000000000000000 A 0 0 4
|
||||
[16] .eh_frame PROGBITS 00000000004005d8 000005d8
|
||||
0000000000000094 0000000000000000 A 0 0 8
|
||||
[17] .ctors PROGBITS 0000000000600670 00000670
|
||||
0000000000000010 0000000000000000 WA 0 0 8
|
||||
[18] .dtors PROGBITS 0000000000600680 00000680
|
||||
0000000000000010 0000000000000000 WA 0 0 8
|
||||
[19] .jcr PROGBITS 0000000000600690 00000690
|
||||
0000000000000008 0000000000000000 WA 0 0 8
|
||||
[20] .dynamic DYNAMIC 0000000000600698 00000698
|
||||
0000000000000190 0000000000000010 WA 5 0 8
|
||||
[21] .got PROGBITS 0000000000600828 00000828
|
||||
0000000000000008 0000000000000008 WA 0 0 8
|
||||
[22] .got.plt PROGBITS 0000000000600830 00000830
|
||||
0000000000000028 0000000000000008 WA 0 0 8
|
||||
[23] .data PROGBITS 0000000000600858 00000858
|
||||
0000000000000004 0000000000000000 WA 0 0 4
|
||||
[24] .bss NOBITS 0000000000600860 0000085c
|
||||
0000000000000010 0000000000000000 WA 0 0 8
|
||||
[25] .comment PROGBITS 0000000000000000 0000085c
|
||||
0000000000000114 0000000000000000 0 0 1
|
||||
[26] .shstrtab STRTAB 0000000000000000 00000970
|
||||
00000000000000eb 0000000000000000 0 0 1
|
||||
[27] .symtab SYMTAB 0000000000000000 000011a0
|
||||
0000000000000648 0000000000000018 28 49 8
|
||||
[28] .strtab STRTAB 0000000000000000 000017e8
|
||||
000000000000023f 0000000000000000 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
Program Headers:
|
||||
Type Offset VirtAddr PhysAddr
|
||||
FileSiz MemSiz Flags Align
|
||||
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
|
||||
0x00000000000001c0 0x00000000000001c0 R E 8
|
||||
INTERP 0x0000000000000200 0x0000000000400200 0x0000000000400200
|
||||
0x000000000000001c 0x000000000000001c R 1
|
||||
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
|
||||
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
|
||||
0x000000000000066c 0x000000000000066c R E 200000
|
||||
LOAD 0x0000000000000670 0x0000000000600670 0x0000000000600670
|
||||
0x00000000000001ec 0x0000000000000200 RW 200000
|
||||
DYNAMIC 0x0000000000000698 0x0000000000600698 0x0000000000600698
|
||||
0x0000000000000190 0x0000000000000190 RW 8
|
||||
NOTE 0x000000000000021c 0x000000000040021c 0x000000000040021c
|
||||
0x0000000000000020 0x0000000000000020 R 4
|
||||
GNU_EH_FRAME 0x00000000000005b0 0x00000000004005b0 0x00000000004005b0
|
||||
0x0000000000000024 0x0000000000000024 R 4
|
||||
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
|
||||
0x0000000000000000 0x0000000000000000 RW 8
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00
|
||||
01 .interp
|
||||
02 .interp .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
|
||||
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
|
||||
04 .dynamic
|
||||
05 .note.ABI-tag
|
||||
06 .eh_frame_hdr
|
||||
07
|
||||
|
||||
Dynamic section at offset 0x698 contains 20 entries:
|
||||
Tag Type Name/Value
|
||||
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
|
||||
0x000000000000000c (INIT) 0x400370
|
||||
0x000000000000000d (FINI) 0x400588
|
||||
0x000000006ffffef5 (GNU_HASH) 0x400240
|
||||
0x0000000000000005 (STRTAB) 0x4002c0
|
||||
0x0000000000000006 (SYMTAB) 0x400260
|
||||
0x000000000000000a (STRSZ) 61 (bytes)
|
||||
0x000000000000000b (SYMENT) 24 (bytes)
|
||||
0x0000000000000015 (DEBUG) 0x0
|
||||
0x0000000000000003 (PLTGOT) 0x600830
|
||||
0x0000000000000002 (PLTRELSZ) 48 (bytes)
|
||||
0x0000000000000014 (PLTREL) RELA
|
||||
0x0000000000000017 (JMPREL) 0x400340
|
||||
0x0000000000000007 (RELA) 0x400328
|
||||
0x0000000000000008 (RELASZ) 24 (bytes)
|
||||
0x0000000000000009 (RELAENT) 24 (bytes)
|
||||
0x000000006ffffffe (VERNEED) 0x400308
|
||||
0x000000006fffffff (VERNEEDNUM) 1
|
||||
0x000000006ffffff0 (VERSYM) 0x4002fe
|
||||
0x0000000000000000 (NULL) 0x0
|
||||
|
||||
Relocation section '.rela.dyn' at offset 0x328 contains 1 entries:
|
||||
Offset Info Type Sym. Value Sym. Name + Addend
|
||||
000000600828 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
|
||||
|
||||
Relocation section '.rela.plt' at offset 0x340 contains 2 entries:
|
||||
Offset Info Type Sym. Value Sym. Name + Addend
|
||||
000000600848 000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0
|
||||
000000600850 000300000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
|
||||
|
||||
There are no unwind sections in this file.
|
||||
|
||||
Symbol table '.dynsym' contains 4 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
|
||||
2: 0000000000000000 396 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
|
||||
3: 0000000000000000 421 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
|
||||
|
||||
Symbol table '.symtab' contains 67 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
|
||||
2: 000000000040021c 0 SECTION LOCAL DEFAULT 2
|
||||
3: 0000000000400240 0 SECTION LOCAL DEFAULT 3
|
||||
4: 0000000000400260 0 SECTION LOCAL DEFAULT 4
|
||||
5: 00000000004002c0 0 SECTION LOCAL DEFAULT 5
|
||||
6: 00000000004002fe 0 SECTION LOCAL DEFAULT 6
|
||||
7: 0000000000400308 0 SECTION LOCAL DEFAULT 7
|
||||
8: 0000000000400328 0 SECTION LOCAL DEFAULT 8
|
||||
9: 0000000000400340 0 SECTION LOCAL DEFAULT 9
|
||||
10: 0000000000400370 0 SECTION LOCAL DEFAULT 10
|
||||
11: 0000000000400388 0 SECTION LOCAL DEFAULT 11
|
||||
12: 00000000004003c0 0 SECTION LOCAL DEFAULT 12
|
||||
13: 0000000000400588 0 SECTION LOCAL DEFAULT 13
|
||||
14: 0000000000400598 0 SECTION LOCAL DEFAULT 14
|
||||
15: 00000000004005b0 0 SECTION LOCAL DEFAULT 15
|
||||
16: 00000000004005d8 0 SECTION LOCAL DEFAULT 16
|
||||
17: 0000000000600670 0 SECTION LOCAL DEFAULT 17
|
||||
18: 0000000000600680 0 SECTION LOCAL DEFAULT 18
|
||||
19: 0000000000600690 0 SECTION LOCAL DEFAULT 19
|
||||
20: 0000000000600698 0 SECTION LOCAL DEFAULT 20
|
||||
21: 0000000000600828 0 SECTION LOCAL DEFAULT 21
|
||||
22: 0000000000600830 0 SECTION LOCAL DEFAULT 22
|
||||
23: 0000000000600858 0 SECTION LOCAL DEFAULT 23
|
||||
24: 0000000000600860 0 SECTION LOCAL DEFAULT 24
|
||||
25: 0000000000000000 0 SECTION LOCAL DEFAULT 25
|
||||
26: 00000000004003ec 0 FUNC LOCAL DEFAULT 12 call_gmon_start
|
||||
27: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
|
||||
28: 0000000000600670 0 OBJECT LOCAL DEFAULT 17 __CTOR_LIST__
|
||||
29: 0000000000600680 0 OBJECT LOCAL DEFAULT 18 __DTOR_LIST__
|
||||
30: 0000000000600690 0 OBJECT LOCAL DEFAULT 19 __JCR_LIST__
|
||||
31: 0000000000600860 8 OBJECT LOCAL DEFAULT 24 dtor_idx.6147
|
||||
32: 0000000000600868 1 OBJECT LOCAL DEFAULT 24 completed.6145
|
||||
33: 0000000000400410 0 FUNC LOCAL DEFAULT 12 __do_global_dtors_aux
|
||||
34: 0000000000400470 0 FUNC LOCAL DEFAULT 12 frame_dummy
|
||||
35: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
|
||||
36: 0000000000600678 0 OBJECT LOCAL DEFAULT 17 __CTOR_END__
|
||||
37: 0000000000400668 0 OBJECT LOCAL DEFAULT 16 __FRAME_END__
|
||||
38: 0000000000600690 0 OBJECT LOCAL DEFAULT 19 __JCR_END__
|
||||
39: 0000000000400550 0 FUNC LOCAL DEFAULT 12 __do_global_ctors_aux
|
||||
40: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c
|
||||
41: 000000000060066c 0 NOTYPE LOCAL HIDDEN 17 __preinit_array_start
|
||||
42: 000000000060066c 0 NOTYPE LOCAL HIDDEN 17 __fini_array_end
|
||||
43: 0000000000600830 0 OBJECT LOCAL HIDDEN 22 _GLOBAL_OFFSET_TABLE_
|
||||
44: 000000000060066c 0 NOTYPE LOCAL HIDDEN 17 __preinit_array_end
|
||||
45: 000000000060066c 0 NOTYPE LOCAL HIDDEN 17 __fini_array_start
|
||||
46: 000000000060066c 0 NOTYPE LOCAL HIDDEN 17 __init_array_end
|
||||
47: 000000000060066c 0 NOTYPE LOCAL HIDDEN 17 __init_array_start
|
||||
48: 0000000000600698 0 OBJECT LOCAL HIDDEN 20 _DYNAMIC
|
||||
49: 0000000000600858 0 NOTYPE WEAK DEFAULT 23 data_start
|
||||
50: 00000000004004b0 2 FUNC GLOBAL DEFAULT 12 __libc_csu_fini
|
||||
51: 00000000004003c0 0 FUNC GLOBAL DEFAULT 12 _start
|
||||
52: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
|
||||
53: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
|
||||
54: 0000000000000000 396 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5
|
||||
55: 0000000000400588 0 FUNC GLOBAL DEFAULT 13 _fini
|
||||
56: 0000000000000000 421 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
|
||||
57: 0000000000400598 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used
|
||||
58: 0000000000600858 0 NOTYPE GLOBAL DEFAULT 23 __data_start
|
||||
59: 00000000004005a0 0 OBJECT GLOBAL HIDDEN 14 __dso_handle
|
||||
60: 0000000000600688 0 OBJECT GLOBAL HIDDEN 18 __DTOR_END__
|
||||
61: 00000000004004c0 139 FUNC GLOBAL DEFAULT 12 __libc_csu_init
|
||||
62: 000000000060085c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
63: 0000000000600870 0 NOTYPE GLOBAL DEFAULT ABS _end
|
||||
64: 000000000060085c 0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
65: 0000000000400498 21 FUNC GLOBAL DEFAULT 12 main
|
||||
66: 0000000000400370 0 FUNC GLOBAL DEFAULT 10 _init
|
||||
|
||||
Version symbols section '.gnu.version' contains 4 entries:
|
||||
Addr: 00000000004002fe Offset: 0x0002fe Link: 4 (.dynsym)
|
||||
000: 0 (*local*) 0 (*local*) 2 (GLIBC_2.2.5) 2 (GLIBC_2.2.5)
|
||||
|
||||
Version needs section '.gnu.version_r' contains 1 entries:
|
||||
Addr: 0x0000000000400308 Offset: 0x000308 Link to section: 5 (.dynstr)
|
||||
000000: Version: 1 File: libc.so.6 Cnt: 1
|
||||
0x0010: Name: GLIBC_2.2.5 Flags: none Version: 2
|
||||
|
||||
Notes at offset 0x0000021c with length 0x00000020:
|
||||
Owner Data size Description
|
||||
GNU 0x00000010 NT_VERSION (version)
|
||||
@@ -0,0 +1,85 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF64
|
||||
Data: 2's complement, little endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: REL (Relocatable file)
|
||||
Machine: Advanced Micro Devices X86-64
|
||||
Version: 0x1
|
||||
Entry point address: 0x0
|
||||
Start of program headers: 0 (bytes into file)
|
||||
Start of section headers: 296 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 64 (bytes)
|
||||
Size of program headers: 0 (bytes)
|
||||
Number of program headers: 0
|
||||
Size of section headers: 64 (bytes)
|
||||
Number of section headers: 13
|
||||
Section header string table index: 10
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Address Offset
|
||||
Size EntSize Flags Link Info Align
|
||||
[ 0] NULL 0000000000000000 00000000
|
||||
0000000000000000 0000000000000000 0 0 0
|
||||
[ 1] .text PROGBITS 0000000000000000 00000040
|
||||
0000000000000015 0000000000000000 AX 0 0 4
|
||||
[ 2] .rela.text RELA 0000000000000000 00000588
|
||||
0000000000000030 0000000000000018 11 1 8
|
||||
[ 3] .data PROGBITS 0000000000000000 00000058
|
||||
0000000000000000 0000000000000000 WA 0 0 4
|
||||
[ 4] .bss NOBITS 0000000000000000 00000058
|
||||
0000000000000000 0000000000000000 WA 0 0 4
|
||||
[ 5] .rodata PROGBITS 0000000000000000 00000058
|
||||
0000000000000006 0000000000000000 A 0 0 1
|
||||
[ 6] .eh_frame PROGBITS 0000000000000000 00000060
|
||||
0000000000000038 0000000000000000 A 0 0 8
|
||||
[ 7] .rela.eh_frame RELA 0000000000000000 000005b8
|
||||
0000000000000018 0000000000000018 11 6 8
|
||||
[ 8] .comment PROGBITS 0000000000000000 00000098
|
||||
000000000000002e 0000000000000000 0 0 1
|
||||
[ 9] .note.GNU-stack PROGBITS 0000000000000000 000000c6
|
||||
0000000000000000 0000000000000000 0 0 1
|
||||
[10] .shstrtab STRTAB 0000000000000000 000000c6
|
||||
0000000000000061 0000000000000000 0 0 1
|
||||
[11] .symtab SYMTAB 0000000000000000 00000468
|
||||
0000000000000108 0000000000000018 12 9 8
|
||||
[12] .strtab STRTAB 0000000000000000 00000570
|
||||
0000000000000013 0000000000000000 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
There are no program headers in this file.
|
||||
|
||||
Relocation section '.rela.text' at offset 0x588 contains 2 entries:
|
||||
Offset Info Type Sym. Value Sym. Name + Addend
|
||||
000000000005 00050000000a R_X86_64_32 0000000000000000 .rodata + 0
|
||||
00000000000a 000a00000002 R_X86_64_PC32 0000000000000000 puts + fffffffffffffffc
|
||||
|
||||
Relocation section '.rela.eh_frame' at offset 0x5b8 contains 1 entries:
|
||||
Offset Info Type Sym. Value Sym. Name + Addend
|
||||
000000000020 00020000000a R_X86_64_32 0000000000000000 .text + 0
|
||||
|
||||
There are no unwind sections in this file.
|
||||
|
||||
Symbol table '.symtab' contains 11 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c
|
||||
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
|
||||
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
|
||||
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
|
||||
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
|
||||
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
|
||||
7: 0000000000000000 0 SECTION LOCAL DEFAULT 9
|
||||
8: 0000000000000000 0 SECTION LOCAL DEFAULT 8
|
||||
9: 0000000000000000 21 FUNC GLOBAL DEFAULT 1 main
|
||||
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND puts
|
||||
|
||||
No version information found in this file.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Hello" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,263 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF32
|
||||
Data: 2's complement, big endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: EXEC (Executable file)
|
||||
Machine: PowerPC
|
||||
Version: 0x1
|
||||
Entry point address: 0x10000550
|
||||
Start of program headers: 52 (bytes into file)
|
||||
Start of section headers: 3484 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 52 (bytes)
|
||||
Size of program headers: 32 (bytes)
|
||||
Number of program headers: 8
|
||||
Size of section headers: 40 (bytes)
|
||||
Number of section headers: 31
|
||||
Section header string table index: 28
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
|
||||
[ 0] NULL 00000000 000000 000000 00 0 0 0
|
||||
[ 1] .interp PROGBITS 10000134 000134 00000d 00 A 0 0 1
|
||||
[ 2] .note.ABI-tag NOTE 10000144 000144 000020 00 A 0 0 4
|
||||
[ 3] .hash HASH 10000164 000164 000048 04 A 4 0 4
|
||||
[ 4] .dynsym DYNSYM 100001ac 0001ac 0000d0 10 A 5 1 4
|
||||
[ 5] .dynstr STRTAB 1000027c 00027c 000183 00 A 0 0 1
|
||||
[ 6] .gnu.version VERSYM 10000400 000400 00001a 02 A 4 0 2
|
||||
[ 7] .gnu.version_r VERNEED 1000041c 00041c 000060 00 A 5 2 4
|
||||
[ 8] .rela.dyn RELA 1000047c 00047c 000018 0c A 4 0 4
|
||||
[ 9] .rela.plt RELA 10000494 000494 00006c 0c A 4 22 4
|
||||
[10] .init PROGBITS 10000500 000500 00004c 00 AX 0 0 4
|
||||
[11] .text PROGBITS 10000550 000550 000480 00 AX 0 0 16
|
||||
[12] .fini PROGBITS 100009d0 0009d0 000038 00 AX 0 0 4
|
||||
[13] .rodata PROGBITS 10000a08 000a08 00001a 00 A 0 0 4
|
||||
[14] .eh_frame_hdr PROGBITS 10000a24 000a24 000024 00 A 0 0 4
|
||||
[15] .eh_frame PROGBITS 10000a48 000a48 000084 00 A 0 0 4
|
||||
[16] .ctors PROGBITS 10010acc 000acc 00000c 00 WA 0 0 4
|
||||
[17] .dtors PROGBITS 10010ad8 000ad8 000008 00 WA 0 0 4
|
||||
[18] .jcr PROGBITS 10010ae0 000ae0 000004 00 WA 0 0 4
|
||||
[19] .got2 PROGBITS 10010ae4 000ae4 000008 00 WA 0 0 1
|
||||
[20] .dynamic DYNAMIC 10010aec 000aec 0000e8 08 WA 5 0 4
|
||||
[21] .got PROGBITS 10010bd4 000bd4 000010 04 WA 0 0 4
|
||||
[22] .plt PROGBITS 10010be4 000be4 000024 00 WA 0 0 4
|
||||
[23] .data PROGBITS 10010c08 000c08 000004 00 WA 0 0 4
|
||||
[24] .bss NOBITS 10010c0c 000c0c 000098 00 WA 0 0 4
|
||||
[25] .comment PROGBITS 00000000 000c0c 000027 00 0 0 1
|
||||
[26] .debug_frame PROGBITS 00000000 000c34 000050 00 0 0 4
|
||||
[27] .gnu.attributes LOOS+ffffff5 00000000 000c84 000014 00 0 0 1
|
||||
[28] .shstrtab STRTAB 00000000 000c98 000101 00 0 0 1
|
||||
[29] .symtab SYMTAB 00000000 001274 000500 10 30 54 4
|
||||
[30] .strtab STRTAB 00000000 001774 0003cc 00 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
Program Headers:
|
||||
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
PHDR 0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4
|
||||
INTERP 0x000134 0x10000134 0x10000134 0x0000d 0x0000d R 0x1
|
||||
[Requesting program interpreter: /lib/ld.so.1]
|
||||
LOAD 0x000000 0x10000000 0x10000000 0x00acc 0x00acc R E 0x10000
|
||||
LOAD 0x000acc 0x10010acc 0x10010acc 0x00140 0x001d8 RW 0x10000
|
||||
DYNAMIC 0x000aec 0x10010aec 0x10010aec 0x000e8 0x000e8 RW 0x4
|
||||
NOTE 0x000144 0x10000144 0x10000144 0x00020 0x00020 R 0x4
|
||||
GNU_EH_FRAME 0x000a24 0x10000a24 0x10000a24 0x00024 0x00024 R 0x4
|
||||
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00
|
||||
01 .interp
|
||||
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .text .fini .rodata .eh_frame_hdr .eh_frame
|
||||
03 .ctors .dtors .jcr .got2 .dynamic .got .plt .data .bss
|
||||
04 .dynamic
|
||||
05 .note.ABI-tag
|
||||
06 .eh_frame_hdr
|
||||
07
|
||||
|
||||
Dynamic section at offset 0xaec contains 24 entries:
|
||||
Tag Type Name/Value
|
||||
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
|
||||
0x00000001 (NEEDED) Shared library: [libm.so.6]
|
||||
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
|
||||
0x00000001 (NEEDED) Shared library: [libc.so.6]
|
||||
0x0000000c (INIT) 0x10000500
|
||||
0x0000000d (FINI) 0x100009d0
|
||||
0x00000004 (HASH) 0x10000164
|
||||
0x00000005 (STRTAB) 0x1000027c
|
||||
0x00000006 (SYMTAB) 0x100001ac
|
||||
0x0000000a (STRSZ) 387 (bytes)
|
||||
0x0000000b (SYMENT) 16 (bytes)
|
||||
0x00000015 (DEBUG) 0x0
|
||||
0x00000003 (PLTGOT) 0x10010be4
|
||||
0x00000002 (PLTRELSZ) 108 (bytes)
|
||||
0x00000014 (PLTREL) RELA
|
||||
0x00000017 (JMPREL) 0x10000494
|
||||
0x70000000 (PPC_GOT) 0x10010bd8
|
||||
0x00000007 (RELA) 0x1000047c
|
||||
0x00000008 (RELASZ) 132 (bytes)
|
||||
0x00000009 (RELAENT) 12 (bytes)
|
||||
0x6ffffffe (VERNEED) 0x1000041c
|
||||
0x6fffffff (VERNEEDNUM) 2
|
||||
0x6ffffff0 (VERSYM) 0x10000400
|
||||
0x00000000 (NULL) 0x0
|
||||
|
||||
Relocation section '.rela.dyn' at offset 0x47c contains 2 entries:
|
||||
Offset Info Type Sym.Value Sym. Name + Addend
|
||||
10010bd4 00000214 R_PPC_GLOB_DAT 00000000 __gmon_start__ + 0
|
||||
10010c0c 00000913 R_PPC_COPY 10010c0c _ZSt4cout + 0
|
||||
|
||||
Relocation section '.rela.plt' at offset 0x494 contains 9 entries:
|
||||
Offset Info Type Sym.Value Sym. Name + Addend
|
||||
10010be4 00000115 R_PPC_JMP_SLOT 100008e0 __cxa_atexit + 0
|
||||
10010be8 00000215 R_PPC_JMP_SLOT 00000000 __gmon_start__ + 0
|
||||
10010bec 00000415 R_PPC_JMP_SLOT 10000900 _ZNSt8ios_base4InitC1E + 0
|
||||
10010bf0 00000515 R_PPC_JMP_SLOT 10000910 __libc_start_main + 0
|
||||
10010bf4 00000615 R_PPC_JMP_SLOT 10000920 _ZNSt8ios_base4InitD1E + 0
|
||||
10010bf8 00000715 R_PPC_JMP_SLOT 10000930 _ZStlsISt11char_traits + 0
|
||||
10010bfc 00000a15 R_PPC_JMP_SLOT 10000940 _ZNSolsEPFRSoS_E + 0
|
||||
10010c00 00000b15 R_PPC_JMP_SLOT 10000950 _ZSt4endlIcSt11char_tr + 0
|
||||
10010c04 00000c15 R_PPC_JMP_SLOT 10000960 __gxx_personality_v0 + 0
|
||||
|
||||
There are no unwind sections in this file.
|
||||
|
||||
Symbol table '.dynsym' contains 13 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 100008e0 144 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.1.3 (2)
|
||||
2: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
|
||||
3: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
|
||||
4: 10000900 1452 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4 (3)
|
||||
5: 10000910 232 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (4)
|
||||
6: 10000920 204 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4 (3)
|
||||
7: 10000930 164 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE@GLIBCXX_3.4 (3)
|
||||
8: 10000a18 4 OBJECT GLOBAL DEFAULT 13 _IO_stdin_used
|
||||
9: 10010c0c 140 OBJECT GLOBAL DEFAULT 24 _ZSt4cout@GLIBCXX_3.4 (3)
|
||||
10: 10000940 36 FUNC GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E@GLIBCXX_3.4 (3)
|
||||
11: 10000950 336 FUNC GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait@GLIBCXX_3.4 (3)
|
||||
12: 10000960 1420 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@CXXABI_1.3 (5)
|
||||
|
||||
Symbol table '.symtab' contains 80 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 10000134 0 SECTION LOCAL DEFAULT 1
|
||||
2: 10000144 0 SECTION LOCAL DEFAULT 2
|
||||
3: 10000164 0 SECTION LOCAL DEFAULT 3
|
||||
4: 100001ac 0 SECTION LOCAL DEFAULT 4
|
||||
5: 1000027c 0 SECTION LOCAL DEFAULT 5
|
||||
6: 10000400 0 SECTION LOCAL DEFAULT 6
|
||||
7: 1000041c 0 SECTION LOCAL DEFAULT 7
|
||||
8: 1000047c 0 SECTION LOCAL DEFAULT 8
|
||||
9: 10000494 0 SECTION LOCAL DEFAULT 9
|
||||
10: 10000500 0 SECTION LOCAL DEFAULT 10
|
||||
11: 10000550 0 SECTION LOCAL DEFAULT 11
|
||||
12: 100009d0 0 SECTION LOCAL DEFAULT 12
|
||||
13: 10000a08 0 SECTION LOCAL DEFAULT 13
|
||||
14: 10000a24 0 SECTION LOCAL DEFAULT 14
|
||||
15: 10000a48 0 SECTION LOCAL DEFAULT 15
|
||||
16: 10010acc 0 SECTION LOCAL DEFAULT 16
|
||||
17: 10010ad8 0 SECTION LOCAL DEFAULT 17
|
||||
18: 10010ae0 0 SECTION LOCAL DEFAULT 18
|
||||
19: 10010ae4 0 SECTION LOCAL DEFAULT 19
|
||||
20: 10010aec 0 SECTION LOCAL DEFAULT 20
|
||||
21: 10010bd4 0 SECTION LOCAL DEFAULT 21
|
||||
22: 10010be4 0 SECTION LOCAL DEFAULT 22
|
||||
23: 10010c08 0 SECTION LOCAL DEFAULT 23
|
||||
24: 10010c0c 0 SECTION LOCAL DEFAULT 24
|
||||
25: 00000000 0 SECTION LOCAL DEFAULT 25
|
||||
26: 00000000 0 SECTION LOCAL DEFAULT 26
|
||||
27: 00000000 0 SECTION LOCAL DEFAULT 27
|
||||
28: 00000000 0 FILE LOCAL DEFAULT ABS init.c
|
||||
29: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
|
||||
30: 10010acc 0 OBJECT LOCAL DEFAULT 16 __CTOR_LIST__
|
||||
31: 10010ad8 0 OBJECT LOCAL DEFAULT 17 __DTOR_LIST__
|
||||
32: 10010ae0 0 OBJECT LOCAL DEFAULT 18 __JCR_LIST__
|
||||
33: 10000574 0 FUNC LOCAL DEFAULT 11 __do_global_dtors_aux
|
||||
34: 10010c98 1 OBJECT LOCAL DEFAULT 24 completed.6348
|
||||
35: 10010c9c 4 OBJECT LOCAL DEFAULT 24 dtor_idx.6350
|
||||
36: 1000061c 0 FUNC LOCAL DEFAULT 11 call___do_global_dtors_au
|
||||
37: 10000638 0 FUNC LOCAL DEFAULT 11 frame_dummy
|
||||
38: 10000680 0 FUNC LOCAL DEFAULT 11 call_frame_dummy
|
||||
39: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
|
||||
40: 10010ad4 0 OBJECT LOCAL DEFAULT 16 __CTOR_END__
|
||||
41: 10000ac8 0 OBJECT LOCAL DEFAULT 15 __FRAME_END__
|
||||
42: 10010ae0 0 OBJECT LOCAL DEFAULT 18 __JCR_END__
|
||||
43: 1000086c 0 FUNC LOCAL DEFAULT 11 __do_global_ctors_aux
|
||||
44: 100008bc 0 FUNC LOCAL DEFAULT 11 call___do_global_ctors_au
|
||||
45: 00000000 0 FILE LOCAL DEFAULT ABS test_ppc.cpp
|
||||
46: 100006f8 128 FUNC LOCAL DEFAULT 11 _Z41__static_initializati
|
||||
47: 10010ca0 1 OBJECT LOCAL DEFAULT 24 _ZStL8__ioinit
|
||||
48: 10000778 60 FUNC LOCAL DEFAULT 11 _GLOBAL__I_main
|
||||
49: 00000000 0 FILE LOCAL DEFAULT ABS elf-init.c
|
||||
50: 10010bd8 0 OBJECT LOCAL HIDDEN 21 _GLOBAL_OFFSET_TABLE_
|
||||
51: 10010acc 0 NOTYPE LOCAL HIDDEN 16 __init_array_end
|
||||
52: 10010acc 0 NOTYPE LOCAL HIDDEN 16 __init_array_start
|
||||
53: 10010aec 0 OBJECT LOCAL HIDDEN 20 _DYNAMIC
|
||||
54: 10010c08 0 NOTYPE WEAK DEFAULT 23 data_start
|
||||
55: 100008e0 144 FUNC GLOBAL DEFAULT UND __cxa_atexit@@GLIBC_2.1.3
|
||||
56: 100007b4 4 FUNC GLOBAL DEFAULT 11 __libc_csu_fini
|
||||
57: 10000550 36 FUNC GLOBAL DEFAULT 11 _start
|
||||
58: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
|
||||
59: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
|
||||
60: 100009d0 0 FUNC GLOBAL DEFAULT 12 _fini
|
||||
61: 10000900 1452 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev@@
|
||||
62: 10018c0c 0 NOTYPE GLOBAL DEFAULT 24 _SDA_BASE_
|
||||
63: 10000910 232 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
|
||||
64: 10000920 204 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@@
|
||||
65: 10000930 164 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE
|
||||
66: 10000a18 4 OBJECT GLOBAL DEFAULT 13 _IO_stdin_used
|
||||
67: 10010c08 0 NOTYPE GLOBAL DEFAULT 23 __data_start
|
||||
68: 10010c0c 140 OBJECT GLOBAL DEFAULT 24 _ZSt4cout@@GLIBCXX_3.4
|
||||
69: 10010c08 0 OBJECT GLOBAL HIDDEN 23 __dso_handle
|
||||
70: 10010adc 0 OBJECT GLOBAL HIDDEN 17 __DTOR_END__
|
||||
71: 100007b8 180 FUNC GLOBAL DEFAULT 11 __libc_csu_init
|
||||
72: 10010c0c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
73: 10010ca4 0 NOTYPE GLOBAL DEFAULT ABS _end
|
||||
74: 10000940 36 FUNC GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E@@GLIBCXX
|
||||
75: 10000950 336 FUNC GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait
|
||||
76: 10010c0c 0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
77: 10000960 1420 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@@CXX
|
||||
78: 1000069c 92 FUNC GLOBAL DEFAULT 11 main
|
||||
79: 10000500 0 FUNC GLOBAL DEFAULT 10 _init
|
||||
|
||||
Histogram for bucket list length (total of 3 buckets):
|
||||
Length Number % of total Coverage
|
||||
0 0 ( 0.0%)
|
||||
1 0 ( 0.0%) 0.0%
|
||||
2 1 ( 33.3%) 16.7%
|
||||
3 0 ( 0.0%) 16.7%
|
||||
4 1 ( 33.3%) 50.0%
|
||||
5 0 ( 0.0%) 50.0%
|
||||
6 1 ( 33.3%) 100.0%
|
||||
|
||||
Version symbols section '.gnu.version' contains 13 entries:
|
||||
Addr: 0000000010000400 Offset: 0x000400 Link: 4 (.dynsym)
|
||||
000: 0 (*local*) 2 (GLIBC_2.1.3) 0 (*local*) 0 (*local*)
|
||||
004: 3 (GLIBCXX_3.4) 4 (GLIBC_2.0) 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4)
|
||||
008: 1 (*global*) 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4) 3 (GLIBCXX_3.4)
|
||||
00c: 5 (CXXABI_1.3)
|
||||
|
||||
Version needs section '.gnu.version_r' contains 2 entries:
|
||||
Addr: 0x000000001000041c Offset: 0x00041c Link: 5 (.dynstr)
|
||||
000000: Version: 1 File: libstdc++.so.6 Cnt: 2
|
||||
0x0010: Name: CXXABI_1.3 Flags: none Version: 5
|
||||
0x0020: Name: GLIBCXX_3.4 Flags: none Version: 3
|
||||
0x0030: Version: 1 File: libc.so.6 Cnt: 2
|
||||
0x0040: Name: GLIBC_2.0 Flags: none Version: 4
|
||||
0x0050: Name: GLIBC_2.1.3 Flags: none Version: 2
|
||||
|
||||
Notes at offset 0x00000144 with length 0x00000020:
|
||||
Owner Data size Description
|
||||
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
|
||||
Attribute Section: gnu
|
||||
File Attributes
|
||||
Tag_GNU_Power_ABI_FP: Hard float
|
||||
Tag_GNU_Power_ABI_Vector: Generic
|
||||
Tag_GNU_Power_ABI_Struct_Return: Memory
|
||||
@@ -0,0 +1,114 @@
|
||||
ELF Header:
|
||||
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
|
||||
Class: ELF32
|
||||
Data: 2's complement, big endian
|
||||
Version: 1 (current)
|
||||
OS/ABI: UNIX - System V
|
||||
ABI Version: 0
|
||||
Type: REL (Relocatable file)
|
||||
Machine: PowerPC
|
||||
Version: 0x1
|
||||
Entry point address: 0x0
|
||||
Start of program headers: 0 (bytes into file)
|
||||
Start of section headers: 616 (bytes into file)
|
||||
Flags: 0x0
|
||||
Size of this header: 52 (bytes)
|
||||
Size of program headers: 0 (bytes)
|
||||
Number of program headers: 0
|
||||
Size of section headers: 40 (bytes)
|
||||
Number of section headers: 16
|
||||
Section header string table index: 13
|
||||
|
||||
Section Headers:
|
||||
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
|
||||
[ 0] NULL 00000000 000000 000000 00 0 0 0
|
||||
[ 1] .text PROGBITS 00000000 000034 000118 00 AX 0 0 4
|
||||
[ 2] .rela.text RELA 00000000 0007b8 0000d8 0c 14 1 4
|
||||
[ 3] .data PROGBITS 00000000 00014c 000000 00 WA 0 0 1
|
||||
[ 4] .bss NOBITS 00000000 00014c 000001 00 WA 0 0 1
|
||||
[ 5] .rodata PROGBITS 00000000 00014c 000006 00 A 0 0 4
|
||||
[ 6] .ctors PROGBITS 00000000 000154 000004 00 WA 0 0 4
|
||||
[ 7] .rela.ctors RELA 00000000 000890 00000c 0c 14 6 4
|
||||
[ 8] .eh_frame PROGBITS 00000000 000158 000058 00 A 0 0 4
|
||||
[ 9] .rela.eh_frame RELA 00000000 00089c 000024 0c 14 8 4
|
||||
[10] .comment PROGBITS 00000000 0001b0 000027 00 0 0 1
|
||||
[11] .note.GNU-stack PROGBITS 00000000 0001d7 000000 00 0 0 1
|
||||
[12] .gnu.attributes LOOS+ffffff5 00000000 0001d7 000014 00 0 0 1
|
||||
[13] .shstrtab STRTAB 00000000 0001eb 00007d 00 0 0 1
|
||||
[14] .symtab SYMTAB 00000000 0004e8 000180 10 15 14 4
|
||||
[15] .strtab STRTAB 00000000 000668 00014f 00 0 0 1
|
||||
Key to Flags:
|
||||
W (write), A (alloc), X (execute), M (merge), S (strings)
|
||||
I (info), L (link order), G (group), x (unknown)
|
||||
O (extra OS processing required) o (OS specific), p (processor specific)
|
||||
|
||||
There are no section groups in this file.
|
||||
|
||||
There are no program headers in this file.
|
||||
|
||||
Relocation section '.rela.text' at offset 0x7b8 contains 18 entries:
|
||||
Offset Info Type Sym.Value Sym. Name + Addend
|
||||
00000016 00000f06 R_PPC_ADDR16_HA 00000000 _ZSt4cout + 0
|
||||
0000001a 00000f04 R_PPC_ADDR16_LO 00000000 _ZSt4cout + 0
|
||||
0000001e 00000506 R_PPC_ADDR16_HA 00000000 .rodata + 0
|
||||
00000022 00000504 R_PPC_ADDR16_LO 00000000 .rodata + 0
|
||||
00000024 0000100a R_PPC_REL24 00000000 _ZStlsISt11char_traits + 0
|
||||
00000032 00001106 R_PPC_ADDR16_HA 00000000 _ZSt4endlIcSt11char_tr + 0
|
||||
00000036 00001104 R_PPC_ADDR16_LO 00000000 _ZSt4endlIcSt11char_tr + 0
|
||||
00000038 0000120a R_PPC_REL24 00000000 _ZNSolsEPFRSoS_E + 0
|
||||
0000009a 00000406 R_PPC_ADDR16_HA 00000000 .bss + 0
|
||||
0000009e 00000404 R_PPC_ADDR16_LO 00000000 .bss + 0
|
||||
000000a0 0000130a R_PPC_REL24 00000000 _ZNSt8ios_base4InitC1E + 0
|
||||
000000a6 00001406 R_PPC_ADDR16_HA 00000000 _ZNSt8ios_base4InitD1E + 0
|
||||
000000aa 00001404 R_PPC_ADDR16_LO 00000000 _ZNSt8ios_base4InitD1E + 0
|
||||
000000b2 00000406 R_PPC_ADDR16_HA 00000000 .bss + 0
|
||||
000000b6 00000404 R_PPC_ADDR16_LO 00000000 .bss + 0
|
||||
000000ba 00001506 R_PPC_ADDR16_HA 00000000 __dso_handle + 0
|
||||
000000be 00001504 R_PPC_ADDR16_LO 00000000 __dso_handle + 0
|
||||
000000c0 0000160a R_PPC_REL24 00000000 __cxa_atexit + 0
|
||||
|
||||
Relocation section '.rela.ctors' at offset 0x890 contains 1 entries:
|
||||
Offset Info Type Sym.Value Sym. Name + Addend
|
||||
00000000 00000201 R_PPC_ADDR32 00000000 .text + dc
|
||||
|
||||
Relocation section '.rela.eh_frame' at offset 0x89c contains 3 entries:
|
||||
Offset Info Type Sym.Value Sym. Name + Addend
|
||||
00000011 00001701 R_PPC_ADDR32 00000000 __gxx_personality_v0 + 0
|
||||
00000020 00000201 R_PPC_ADDR32 00000000 .text + 0
|
||||
00000040 00000201 R_PPC_ADDR32 00000000 .text + 5c
|
||||
|
||||
There are no unwind sections in this file.
|
||||
|
||||
Symbol table '.symtab' contains 24 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 00000000 0 FILE LOCAL DEFAULT ABS test_ppc.cpp
|
||||
2: 00000000 0 SECTION LOCAL DEFAULT 1
|
||||
3: 00000000 0 SECTION LOCAL DEFAULT 3
|
||||
4: 00000000 0 SECTION LOCAL DEFAULT 4
|
||||
5: 00000000 0 SECTION LOCAL DEFAULT 5
|
||||
6: 0000005c 128 FUNC LOCAL DEFAULT 1 _Z41__static_initializati
|
||||
7: 00000000 1 OBJECT LOCAL DEFAULT 4 _ZStL8__ioinit
|
||||
8: 000000dc 60 FUNC LOCAL DEFAULT 1 _GLOBAL__I_main
|
||||
9: 00000000 0 SECTION LOCAL DEFAULT 6
|
||||
10: 00000000 0 SECTION LOCAL DEFAULT 8
|
||||
11: 00000000 0 SECTION LOCAL DEFAULT 11
|
||||
12: 00000000 0 SECTION LOCAL DEFAULT 10
|
||||
13: 00000000 0 SECTION LOCAL DEFAULT 12
|
||||
14: 00000000 92 FUNC GLOBAL DEFAULT 1 main
|
||||
15: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ZSt4cout
|
||||
16: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE
|
||||
17: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait
|
||||
18: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E
|
||||
19: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev
|
||||
20: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev
|
||||
21: 00000000 0 NOTYPE GLOBAL DEFAULT UND __dso_handle
|
||||
22: 00000000 0 NOTYPE GLOBAL DEFAULT UND __cxa_atexit
|
||||
23: 00000000 0 NOTYPE GLOBAL DEFAULT UND __gxx_personality_v0
|
||||
|
||||
No version information found in this file.
|
||||
Attribute Section: gnu
|
||||
File Attributes
|
||||
Tag_GNU_Power_ABI_FP: Hard float
|
||||
Tag_GNU_Power_ABI_Vector: Generic
|
||||
Tag_GNU_Power_ABI_Struct_Return: Memory
|
||||
@@ -0,0 +1,5 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void print_hello_world_v1() { printf( "hello v1" ); }
|
||||
|
||||
void print_hello_world_v2() { printf( "hello v2" ); }
|
||||
@@ -0,0 +1,9 @@
|
||||
HELLO_1.0 {
|
||||
global:
|
||||
_Z20print_hello_world_v1v;
|
||||
};
|
||||
|
||||
HELLO_2.0 {
|
||||
global:
|
||||
_Z20print_hello_world_v2v;
|
||||
};
|
||||
Binary file not shown.
@@ -0,0 +1,71 @@
|
||||
|
||||
write_exe_i386_32_work: file format elf32-i386
|
||||
write_exe_i386_32_work
|
||||
architecture: i386, flags 0x00000102:
|
||||
EXEC_P, D_PAGED
|
||||
start address 0x08048080
|
||||
|
||||
Program Header:
|
||||
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
|
||||
filesz 0x0000009d memsz 0x0000009d flags r-x
|
||||
LOAD off 0x000000a0 vaddr 0x080490a0 paddr 0x080490a0 align 2**12
|
||||
filesz 0x0000000e memsz 0x0000000e flags rw-
|
||||
|
||||
Sections:
|
||||
Idx Name Size VMA LMA File off Algn
|
||||
0 .text 0000001d 08048080 08048080 00000080 2**4
|
||||
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
||||
1 .data 0000000e 080490a0 080490a0 000000a0 2**2
|
||||
CONTENTS, ALLOC, LOAD, DATA
|
||||
2 .note 00000020 00000000 00000000 000000ae 2**0
|
||||
CONTENTS, READONLY
|
||||
SYMBOL TABLE:
|
||||
no symbols
|
||||
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
08048080 <.text>:
|
||||
8048080: b8 04 00 00 00 mov $0x4,%eax
|
||||
8048085: bb 01 00 00 00 mov $0x1,%ebx
|
||||
804808a: b9 a0 90 04 08 mov $0x80490a0,%ecx
|
||||
804808f: ba 0e 00 00 00 mov $0xe,%edx
|
||||
8048094: cd 80 int $0x80
|
||||
8048096: b8 01 00 00 00 mov $0x1,%eax
|
||||
804809b: cd 80 int $0x80
|
||||
|
||||
Disassembly of section .data:
|
||||
|
||||
080490a0 <.data>:
|
||||
80490a0: 48 dec %eax
|
||||
80490a1: 65 gs
|
||||
80490a2: 6c insb (%dx),%es:(%edi)
|
||||
80490a3: 6c insb (%dx),%es:(%edi)
|
||||
80490a4: 6f outsl %ds:(%esi),(%dx)
|
||||
80490a5: 2c 20 sub $0x20,%al
|
||||
80490a7: 57 push %edi
|
||||
80490a8: 6f outsl %ds:(%esi),(%dx)
|
||||
80490a9: 72 6c jb 0x8049117
|
||||
80490ab: 64 21 0a and %ecx,%fs:(%edx)
|
||||
|
||||
Disassembly of section .note:
|
||||
|
||||
00000000 <.note>:
|
||||
0: 11 00 adc %eax,(%eax)
|
||||
2: 00 00 add %al,(%eax)
|
||||
4: 00 00 add %al,(%eax)
|
||||
6: 00 00 add %al,(%eax)
|
||||
8: 77 00 ja 0xa
|
||||
a: 00 00 add %al,(%eax)
|
||||
c: 43 inc %ebx
|
||||
d: 72 65 jb 0x74
|
||||
f: 61 popa
|
||||
10: 74 65 je 0x77
|
||||
12: 64 20 62 79 and %ah,%fs:0x79(%edx)
|
||||
16: 20 45 4c and %al,0x4c(%ebp)
|
||||
19: 46 inc %esi
|
||||
1a: 49 dec %ecx
|
||||
1b: 4f dec %edi
|
||||
1c: 00 00 add %al,(%eax)
|
||||
...
|
||||
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <elfio/elfio.hpp>
|
||||
#include <elfio/elfio_dump.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput( const std::uint8_t* Data, size_t Size )
|
||||
{
|
||||
std::string str( (const char*)Data, Size );
|
||||
std::istringstream ss( str );
|
||||
std::ostringstream oss;
|
||||
|
||||
elfio elf;
|
||||
|
||||
if ( !elf.load( ss ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dump::header( oss, elf );
|
||||
dump::section_headers( oss, elf );
|
||||
dump::segment_headers( oss, elf );
|
||||
dump::symbol_tables( oss, elf );
|
||||
dump::notes( oss, elf );
|
||||
dump::modinfo( oss, elf );
|
||||
dump::dynamic_tags( oss, elf );
|
||||
dump::section_datas( oss, elf );
|
||||
dump::segment_datas( oss, elf );
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ELFIOTest requires to have the current working directory here,
|
||||
# otherwise it would not find its test files
|
||||
cd `dirname $0`
|
||||
./ELFIOTest
|
||||
Reference in New Issue
Block a user