Squashed 'external/ELFIO/' content from commit 94f7706

git-subtree-dir: external/ELFIO
git-subtree-split: 94f7706b5325b2ad9872e4481278278592cf86c9
This commit is contained in:
2026-05-11 11:41:03 +02:00
commit a67f311330
261 changed files with 21266 additions and 0 deletions
+848
View File
@@ -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 );
}
+108
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+895
View File
@@ -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 );
}
+580
View File
@@ -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 );
}
+1
View File
@@ -0,0 +1 @@
!<arch>
+20
View File
@@ -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.
+30
View File
@@ -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
+20
View File
@@ -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.
+23
View File
@@ -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.
+51
View File
@@ -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.
+22
View 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.
+23
View File
@@ -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.
+8
View File
@@ -0,0 +1,8 @@
#include <stdio.h>
int main()
{
printf( "Hello\n" );
return 0;
}
Binary file not shown.
Binary file not shown.
+211
View File
@@ -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)
+64
View File
@@ -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.
+244
View File
@@ -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)
+85
View File
@@ -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.
BIN
View 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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+8
View File
@@ -0,0 +1,8 @@
#include <iostream>
int main()
{
std::cout << "Hello" << std::endl;
return 0;
}
Binary file not shown.
+263
View File
@@ -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
+114
View File
@@ -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
+5
View File
@@ -0,0 +1,5 @@
#include <stdio.h>
void print_hello_world_v1() { printf( "hello v1" ); }
void print_hello_world_v2() { printf( "hello v2" ); }
+9
View File
@@ -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.
BIN
View File
Binary file not shown.
Binary file not shown.
+32
View File
@@ -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;
}
+6
View File
@@ -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