mirror of
https://github.com/QuasarApp/ELFIO.git
synced 2025-05-14 11:59:33 +00:00
arrange_local_symbols() added
ELF standard requires that all STB_LOCAL symbols will go prior others and sh_info entry will contain the number of the local symbols
This commit is contained in:
parent
d2c3fb6a14
commit
8e0b5754e4
1
.gitignore
vendored
1
.gitignore
vendored
@ -44,6 +44,7 @@ tests/elf_examples/write_exe_i386_32_section_added
|
|||||||
tests/elf_examples/ppc-32bit-testcopy*.elf
|
tests/elf_examples/ppc-32bit-testcopy*.elf
|
||||||
tests/elf_examples/null_section_inside_segment*
|
tests/elf_examples/null_section_inside_segment*
|
||||||
tests/elf_examples/segment_containing_no_section*
|
tests/elf_examples/segment_containing_no_section*
|
||||||
|
tests/elf_examples/test_symbols_order.elf
|
||||||
examples/writer/hello_x86_64
|
examples/writer/hello_x86_64
|
||||||
examples/write_obj/hello
|
examples/write_obj/hello
|
||||||
|
|
||||||
|
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@ -8,10 +8,13 @@
|
|||||||
"name": "Run ELFIO Tests",
|
"name": "Run ELFIO Tests",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/ELFIOTest/ELFIOTest",
|
"program": "${workspaceFolder}/tests/ELFIOTest",
|
||||||
"args": [],
|
"args": [
|
||||||
|
"-r",
|
||||||
|
"short"
|
||||||
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}/ELFIOTest",
|
"cwd": "${workspaceFolder}/tests",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
|
9
.vscode/tasks.json
vendored
9
.vscode/tasks.json
vendored
@ -9,12 +9,15 @@
|
|||||||
"CXXFLAGS='-g -O0'"
|
"CXXFLAGS='-g -O0'"
|
||||||
],
|
],
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceRoot}/ELFIOTest",
|
"cwd": "${workspaceRoot}/tests"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
}
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
@ -25,7 +28,7 @@
|
|||||||
"CXXFLAGS='-g -O0'"
|
"CXXFLAGS='-g -O0'"
|
||||||
],
|
],
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
|
@ -214,6 +214,22 @@ class symbol_section_accessor_template
|
|||||||
return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx );
|
return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
Elf_Xword
|
||||||
|
arrange_local_symbols()
|
||||||
|
{
|
||||||
|
int nRet = 0;
|
||||||
|
|
||||||
|
if (elf_file.get_class() == ELFCLASS32) {
|
||||||
|
nRet = generic_arrange_local_symbols<Elf32_Sym>();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nRet = generic_arrange_local_symbols<Elf64_Sym>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nRet;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
private :
|
private :
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -345,6 +361,61 @@ class symbol_section_accessor_template
|
|||||||
return nRet;
|
return nRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template <class T>
|
||||||
|
Elf_Xword
|
||||||
|
generic_arrange_local_symbols()
|
||||||
|
{
|
||||||
|
const endianess_convertor &convertor = elf_file.get_convertor();
|
||||||
|
const Elf_Xword size = symbol_section->get_entry_size();
|
||||||
|
|
||||||
|
Elf_Xword first_not_local = 1; // Skip the first entry
|
||||||
|
Elf_Xword current = 0;
|
||||||
|
Elf_Xword count = get_symbols_num();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
T *p1 = nullptr;
|
||||||
|
T *p2 = nullptr;
|
||||||
|
|
||||||
|
while (first_not_local < count)
|
||||||
|
{
|
||||||
|
p1 = const_cast<T *>(generic_get_symbol_ptr<T>(first_not_local));
|
||||||
|
if (ELF_ST_BIND(convertor(p1->st_info)) != STB_LOCAL)
|
||||||
|
break;
|
||||||
|
++first_not_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = first_not_local + 1;
|
||||||
|
while (current < count)
|
||||||
|
{
|
||||||
|
p2 = const_cast<T *>(generic_get_symbol_ptr<T>(current));
|
||||||
|
if (ELF_ST_BIND(convertor(p2->st_info)) == STB_LOCAL)
|
||||||
|
break;
|
||||||
|
++current;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_not_local < count && current < count)
|
||||||
|
{
|
||||||
|
// Swap the symbols
|
||||||
|
T tmp;
|
||||||
|
memcpy(&tmp, p1, size);
|
||||||
|
memcpy(p1, p2, size);
|
||||||
|
memcpy(p2, &tmp, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Update 'info' field of the section
|
||||||
|
symbol_section->set_info(first_not_local);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elf_Word nRet = symbol_section->get_size() / sizeof(entry) - 1;
|
||||||
|
|
||||||
|
return first_not_local;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
private:
|
private:
|
||||||
const elfio& elf_file;
|
const elfio& elf_file;
|
||||||
|
@ -11,7 +11,12 @@ using boost::test_tools::output_test_stream;
|
|||||||
|
|
||||||
using namespace ELFIO;
|
using namespace ELFIO;
|
||||||
|
|
||||||
|
enum Tests
|
||||||
|
{
|
||||||
|
SEG_ALIGN = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool write_obj_i386(bool is64bit)
|
bool write_obj_i386(bool is64bit)
|
||||||
{
|
{
|
||||||
elfio writer;
|
elfio writer;
|
||||||
@ -28,7 +33,8 @@ bool write_obj_i386( bool is64bit )
|
|||||||
text_sec->set_addr_align(0x10);
|
text_sec->set_addr_align(0x10);
|
||||||
|
|
||||||
// Add data into it
|
// Add data into it
|
||||||
char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
char text[] = {
|
||||||
|
'\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
||||||
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
||||||
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
|
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
|
||||||
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
||||||
@ -46,8 +52,7 @@ bool write_obj_i386( bool is64bit )
|
|||||||
|
|
||||||
char data[] = {'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
char data[] = {'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
||||||
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
||||||
'\x6C', '\x64', '\x21', '\x0A'
|
'\x6C', '\x64', '\x21', '\x0A'};
|
||||||
};
|
|
||||||
data_sec->set_data(data, sizeof(data));
|
data_sec->set_data(data, sizeof(data));
|
||||||
|
|
||||||
section *str_sec = writer.sections.add(".strtab");
|
section *str_sec = writer.sections.add(".strtab");
|
||||||
@ -103,36 +108,12 @@ bool write_obj_i386( bool is64bit )
|
|||||||
|
|
||||||
// Create ELF file
|
// Create ELF file
|
||||||
writer.save(
|
writer.save(
|
||||||
is64bit ?
|
is64bit ? "elf_examples/write_obj_i386_64.o" : "elf_examples/write_obj_i386_32.o");
|
||||||
"elf_examples/write_obj_i386_64.o" :
|
|
||||||
"elf_examples/write_obj_i386_32.o"
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
BOOST_AUTO_TEST_CASE( write_obj_i386_32 )
|
|
||||||
{
|
|
||||||
BOOST_CHECK_EQUAL( 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() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
BOOST_AUTO_TEST_CASE( write_obj_i386_64 )
|
|
||||||
{
|
|
||||||
BOOST_CHECK_EQUAL( 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() );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool write_exe_i386(const std::string &filename, bool is64bit, bool set_addr = false, Elf64_Addr addr = 0)
|
bool write_exe_i386(const std::string &filename, bool is64bit, bool set_addr = false, Elf64_Addr addr = 0)
|
||||||
{
|
{
|
||||||
elfio writer;
|
elfio writer;
|
||||||
@ -147,12 +128,14 @@ bool write_exe_i386( const std::string& filename, bool is64bit, bool set_addr =
|
|||||||
text_sec->set_type(SHT_PROGBITS);
|
text_sec->set_type(SHT_PROGBITS);
|
||||||
text_sec->set_flags(SHF_ALLOC | SHF_EXECINSTR);
|
text_sec->set_flags(SHF_ALLOC | SHF_EXECINSTR);
|
||||||
text_sec->set_addr_align(0x10);
|
text_sec->set_addr_align(0x10);
|
||||||
if ( set_addr ) {
|
if (set_addr)
|
||||||
|
{
|
||||||
text_sec->set_address(addr);
|
text_sec->set_address(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add data into it
|
// Add data into it
|
||||||
char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
char text[] = {
|
||||||
|
'\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
||||||
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
||||||
'\xB9', '\x20', '\x80', '\x04', '\x08', // mov ecx, msg
|
'\xB9', '\x20', '\x80', '\x04', '\x08', // mov ecx, msg
|
||||||
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
||||||
@ -178,8 +161,7 @@ bool write_exe_i386( const std::string& filename, bool is64bit, bool set_addr =
|
|||||||
|
|
||||||
char data[] = {'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
char data[] = {'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
||||||
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
||||||
'\x6C', '\x64', '\x21', '\x0A'
|
'\x6C', '\x64', '\x21', '\x0A'};
|
||||||
};
|
|
||||||
data_sec->set_data(data, sizeof(data));
|
data_sec->set_data(data, sizeof(data));
|
||||||
|
|
||||||
segment *data_seg = writer.segments.add();
|
segment *data_seg = writer.segments.add();
|
||||||
@ -206,21 +188,7 @@ bool write_exe_i386( const std::string& filename, bool is64bit, bool set_addr =
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
BOOST_AUTO_TEST_CASE( 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" );
|
|
||||||
BOOST_CHECK_EQUAL( 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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Tests { SEG_ALIGN = 1 };
|
|
||||||
|
|
||||||
void checkObjestsAreEqual(std::string file_name1, std::string file_name2)
|
void checkObjestsAreEqual(std::string file_name1, std::string file_name2)
|
||||||
{
|
{
|
||||||
elfio file1;
|
elfio file1;
|
||||||
@ -230,7 +198,8 @@ void checkObjestsAreEqual( std::string file_name1, std::string file_name2 )
|
|||||||
BOOST_REQUIRE_EQUAL(file1.load(file_name1), true);
|
BOOST_REQUIRE_EQUAL(file1.load(file_name1), true);
|
||||||
BOOST_REQUIRE_EQUAL(file2.load(file_name2), true);
|
BOOST_REQUIRE_EQUAL(file2.load(file_name2), true);
|
||||||
|
|
||||||
for (int i = 0; i < file1.sections.size(); ++i ) {
|
for (int i = 0; i < file1.sections.size(); ++i)
|
||||||
|
{
|
||||||
BOOST_CHECK_EQUAL(file1.sections[i]->get_address(),
|
BOOST_CHECK_EQUAL(file1.sections[i]->get_address(),
|
||||||
file2.sections[i]->get_address());
|
file2.sections[i]->get_address());
|
||||||
BOOST_CHECK_EQUAL(file1.sections[i]->get_addr_align(),
|
BOOST_CHECK_EQUAL(file1.sections[i]->get_addr_align(),
|
||||||
@ -254,9 +223,9 @@ void checkObjestsAreEqual( std::string file_name1, std::string file_name2 )
|
|||||||
BOOST_CHECK_EQUAL(file1.sections[i]->get_type(),
|
BOOST_CHECK_EQUAL(file1.sections[i]->get_type(),
|
||||||
file2.sections[i]->get_type());
|
file2.sections[i]->get_type());
|
||||||
|
|
||||||
|
|
||||||
if (file1.sections[i]->get_type() == SHT_NULL ||
|
if (file1.sections[i]->get_type() == SHT_NULL ||
|
||||||
file1.sections[i]->get_type() == SHT_NOBITS ) {
|
file1.sections[i]->get_type() == SHT_NOBITS)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BOOST_REQUIRE_NE(file1.sections[i]->get_data(), (const char *)0);
|
BOOST_REQUIRE_NE(file1.sections[i]->get_data(), (const char *)0);
|
||||||
@ -271,14 +240,15 @@ void checkObjestsAreEqual( std::string file_name1, std::string file_name2 )
|
|||||||
BOOST_CHECK_EQUAL(file1.sections[i]->get_size(),
|
BOOST_CHECK_EQUAL(file1.sections[i]->get_size(),
|
||||||
file2.sections[i]->get_size());
|
file2.sections[i]->get_size());
|
||||||
if ((file2.sections[i]->get_type() != SHT_NULL) &&
|
if ((file2.sections[i]->get_type() != SHT_NULL) &&
|
||||||
( file2.sections[i]->get_type() != SHT_NOBITS ) ) {
|
(file2.sections[i]->get_type() != SHT_NOBITS))
|
||||||
|
{
|
||||||
BOOST_CHECK_EQUAL_COLLECTIONS(pdata1.begin(), pdata1.end(),
|
BOOST_CHECK_EQUAL_COLLECTIONS(pdata1.begin(), pdata1.end(),
|
||||||
pdata2.begin(), pdata2.end());
|
pdata2.begin(), pdata2.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void checkExeAreEqual(std::string file_name1, std::string file_name2, int skipTests = 0)
|
void checkExeAreEqual(std::string file_name1, std::string file_name2, int skipTests = 0)
|
||||||
{
|
{
|
||||||
checkObjestsAreEqual(file_name1, file_name2);
|
checkObjestsAreEqual(file_name1, file_name2);
|
||||||
@ -289,7 +259,8 @@ void checkExeAreEqual( std::string file_name1, std::string file_name2, int skipT
|
|||||||
BOOST_REQUIRE_EQUAL(file1.load(file_name1), true);
|
BOOST_REQUIRE_EQUAL(file1.load(file_name1), true);
|
||||||
BOOST_REQUIRE_EQUAL(file2.load(file_name2), true);
|
BOOST_REQUIRE_EQUAL(file2.load(file_name2), true);
|
||||||
|
|
||||||
for (int i = 0; i < file1.segments.size(); ++i ) {
|
for (int i = 0; i < file1.segments.size(); ++i)
|
||||||
|
{
|
||||||
if (!(skipTests & SEG_ALIGN))
|
if (!(skipTests & SEG_ALIGN))
|
||||||
BOOST_CHECK_EQUAL(file1.segments[i]->get_align(),
|
BOOST_CHECK_EQUAL(file1.segments[i]->get_align(),
|
||||||
file2.segments[i]->get_align());
|
file2.segments[i]->get_align());
|
||||||
@ -318,7 +289,8 @@ void checkExeAreEqual( std::string file_name1, std::string file_name2, int skipT
|
|||||||
// part of the segment
|
// part of the segment
|
||||||
Elf64_Off afterPHDR = file1.get_segments_offset() +
|
Elf64_Off afterPHDR = file1.get_segments_offset() +
|
||||||
file1.get_segment_entry_size() * (Elf64_Off)file1.segments.size();
|
file1.get_segment_entry_size() * (Elf64_Off)file1.segments.size();
|
||||||
if( file1.segments[i]->get_offset() < afterPHDR ) {
|
if (file1.segments[i]->get_offset() < afterPHDR)
|
||||||
|
{
|
||||||
pdata1 = pdata1.substr((unsigned int)afterPHDR);
|
pdata1 = pdata1.substr((unsigned int)afterPHDR);
|
||||||
pdata2 = pdata2.substr((unsigned int)afterPHDR);
|
pdata2 = pdata2.substr((unsigned int)afterPHDR);
|
||||||
}
|
}
|
||||||
@ -328,6 +300,37 @@ void checkExeAreEqual( std::string file_name1, std::string file_name2, int skipT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
BOOST_AUTO_TEST_CASE(write_obj_i386_32)
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(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());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
BOOST_AUTO_TEST_CASE(write_obj_i386_64)
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(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());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
BOOST_AUTO_TEST_CASE(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");
|
||||||
|
BOOST_CHECK_EQUAL(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);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
BOOST_AUTO_TEST_CASE(elf_object_copy_32)
|
BOOST_AUTO_TEST_CASE(elf_object_copy_32)
|
||||||
@ -344,7 +347,6 @@ BOOST_AUTO_TEST_CASE( elf_object_copy_32 )
|
|||||||
"elf_examples/write_obj_i386_64_copy.o");
|
"elf_examples/write_obj_i386_64_copy.o");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
BOOST_AUTO_TEST_CASE(section_header_address_update)
|
BOOST_AUTO_TEST_CASE(section_header_address_update)
|
||||||
{
|
{
|
||||||
@ -357,7 +359,6 @@ BOOST_AUTO_TEST_CASE( section_header_address_update )
|
|||||||
BOOST_REQUIRE_NE(sec, (section *)0);
|
BOOST_REQUIRE_NE(sec, (section *)0);
|
||||||
BOOST_CHECK_EQUAL(sec->get_address(), 0x08048100);
|
BOOST_CHECK_EQUAL(sec->get_address(), 0x08048100);
|
||||||
|
|
||||||
|
|
||||||
const std::string file_wo_addr("elf_examples/write_exe_i386_32_wo_addr");
|
const std::string file_wo_addr("elf_examples/write_exe_i386_32_wo_addr");
|
||||||
write_exe_i386(file_wo_addr, false, false, 0);
|
write_exe_i386(file_wo_addr, false, false, 0);
|
||||||
reader.load(file_wo_addr);
|
reader.load(file_wo_addr);
|
||||||
@ -366,7 +367,6 @@ BOOST_AUTO_TEST_CASE( section_header_address_update )
|
|||||||
BOOST_CHECK_EQUAL(sec->get_address(), 0x08048000);
|
BOOST_CHECK_EQUAL(sec->get_address(), 0x08048000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
BOOST_AUTO_TEST_CASE(elfio_copy)
|
BOOST_AUTO_TEST_CASE(elfio_copy)
|
||||||
{
|
{
|
||||||
@ -585,3 +585,102 @@ BOOST_AUTO_TEST_CASE(invalid_file)
|
|||||||
symbols.get_symbol(0x00400498, name, size, bind,
|
symbols.get_symbol(0x00400498, name, size, bind,
|
||||||
type, section_index, other));
|
type, section_index, other));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
BOOST_AUTO_TEST_CASE(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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
symbols.arrange_local_symbols();
|
||||||
|
|
||||||
|
BOOST_REQUIRE_EQUAL(writer.save(file_name), true);
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
elfio reader;
|
||||||
|
BOOST_REQUIRE_EQUAL(reader.load(file_name), true);
|
||||||
|
|
||||||
|
auto psymsec = reader.sections[".symtab"];
|
||||||
|
BOOST_REQUIRE_NE(psymsec, nullptr);
|
||||||
|
|
||||||
|
const_symbol_section_accessor rsymbols(reader, psymsec);
|
||||||
|
|
||||||
|
auto bound = psymsec->get_info();
|
||||||
|
auto num = rsymbols.get_symbols_num();
|
||||||
|
|
||||||
|
BOOST_CHECK_LE(bound, num);
|
||||||
|
|
||||||
|
// Check that all symbols are LOCAL until the bound value
|
||||||
|
for (auto i = 0; i < bound; i++)
|
||||||
|
{
|
||||||
|
rsymbols.get_symbol(i, name, value, size, bind, type, section_index, other);
|
||||||
|
BOOST_CHECK_EQUAL(bind, STB_LOCAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all symbols are not LOCAL after the bound value
|
||||||
|
for (auto i = bound; i < num; i++)
|
||||||
|
{
|
||||||
|
rsymbols.get_symbol(i, name, value, size, bind, type, section_index, other);
|
||||||
|
|
||||||
|
BOOST_CHECK_NE(bind, STB_LOCAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user