mirror of
https://github.com/serge1/ELFIO.git
synced 2025-03-18 16:21:11 +00:00
Permit substitution of relocation entry by using set_entry() function call
This commit is contained in:
parent
6037df883c
commit
6d3d5467a2
@ -200,6 +200,38 @@ class relocation_section_accessor_template
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
set_entry(Elf_Xword index,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
Elf_Word type,
|
||||
Elf_Sxword addend)
|
||||
{
|
||||
if (index >= get_entries_num()) { // Is index valid
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elf_file.get_class() == ELFCLASS32) {
|
||||
if (SHT_REL == relocation_section->get_type()) {
|
||||
generic_set_entry_rel<Elf32_Rel>(index, offset, symbol, type, addend);
|
||||
}
|
||||
else if (SHT_RELA == relocation_section->get_type()) {
|
||||
generic_set_entry_rela<Elf32_Rela>(index, offset, symbol, type, addend);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (SHT_REL == relocation_section->get_type()) {
|
||||
generic_set_entry_rel<Elf64_Rel>(index, offset, symbol, type, addend);
|
||||
}
|
||||
else if (SHT_RELA == relocation_section->get_type()) {
|
||||
generic_set_entry_rela<Elf64_Rela>(index, offset, symbol, type, addend);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
add_entry( Elf64_Addr offset, Elf_Xword info )
|
||||
@ -325,6 +357,58 @@ class relocation_section_accessor_template
|
||||
addend = convertor( pEntry->r_addend );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
void
|
||||
generic_set_entry_rel(Elf_Xword index,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
Elf_Word type,
|
||||
Elf_Sxword addend)
|
||||
{
|
||||
const endianess_convertor &convertor = elf_file.get_convertor();
|
||||
|
||||
T *pEntry = const_cast<T *>(reinterpret_cast<const T *>(relocation_section->get_data() +
|
||||
index * relocation_section->get_entry_size()));
|
||||
|
||||
if (elf_file.get_class() == ELFCLASS32) {
|
||||
pEntry->r_info = ELF32_R_INFO((Elf_Xword)symbol, type);
|
||||
}
|
||||
else {
|
||||
pEntry->r_info = ELF64_R_INFO((Elf_Xword)symbol, type);
|
||||
}
|
||||
pEntry->r_offset = offset;
|
||||
pEntry->r_offset = convertor(pEntry->r_offset);
|
||||
pEntry->r_info = convertor(pEntry->r_info);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
void
|
||||
generic_set_entry_rela(Elf_Xword index,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
Elf_Word type,
|
||||
Elf_Sxword addend)
|
||||
{
|
||||
const endianess_convertor &convertor = elf_file.get_convertor();
|
||||
|
||||
T *pEntry = const_cast<T *>(reinterpret_cast<const T *>(relocation_section->get_data() +
|
||||
index * relocation_section->get_entry_size()));
|
||||
|
||||
if (elf_file.get_class() == ELFCLASS32) {
|
||||
pEntry->r_info = ELF32_R_INFO((Elf_Xword)symbol, type);
|
||||
}
|
||||
else {
|
||||
pEntry->r_info = ELF64_R_INFO((Elf_Xword)symbol, type);
|
||||
}
|
||||
pEntry->r_offset = offset;
|
||||
pEntry->r_addend = addend;
|
||||
pEntry->r_offset = convertor(pEntry->r_offset);
|
||||
pEntry->r_info = convertor(pEntry->r_info);
|
||||
pEntry->r_addend = convertor(pEntry->r_addend);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template< class T >
|
||||
void
|
||||
|
@ -650,7 +650,7 @@ BOOST_AUTO_TEST_CASE(rearrange_local_symbols)
|
||||
value = 8;
|
||||
symbols.add_symbol(str_writer, name.c_str(), value, size, bind, type, other, section_index);
|
||||
|
||||
symbols.arrange_local_symbols([symbols](Elf_Xword first, Elf_Xword second) -> void {
|
||||
symbols.arrange_local_symbols([&](Elf_Xword first, Elf_Xword second) -> void {
|
||||
static int counter = 0;
|
||||
BOOST_CHECK_EQUAL(first, ++counter);
|
||||
// std::string name = "";
|
||||
@ -702,3 +702,161 @@ BOOST_AUTO_TEST_CASE(rearrange_local_symbols)
|
||||
}
|
||||
BOOST_CHECK_EQUAL(name, "Str8");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE(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);
|
||||
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);
|
||||
|
||||
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, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(8, sym8, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(6, sym6, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(2, sym2, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(3, sym3, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(8, sym8, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(7, sym7, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(2, sym2, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(11, sym1, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(18, sym8, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(16, sym6, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(12, sym2, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(13, sym3, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(17, sym7, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(14, sym4, (unsigned char)R_386_RELATIVE);
|
||||
rela.add_entry(15, sym5, (unsigned char)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;
|
||||
Elf_Word 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.push_back(name);
|
||||
}
|
||||
|
||||
symbols.arrange_local_symbols([&](Elf_Xword first, Elf_Xword second) -> void {
|
||||
Elf64_Addr offset;
|
||||
Elf_Word symbol;
|
||||
Elf_Word rtype;
|
||||
Elf_Sxword addend;
|
||||
for (Elf_Word i = 0; i < rela.get_entries_num(); i++) {
|
||||
rela.get_entry(i, offset, symbol, rtype, addend);
|
||||
if (symbol == first) {
|
||||
rela.set_entry(i, offset, second, rtype, addend);
|
||||
}
|
||||
if (symbol == second) {
|
||||
rela.set_entry(i, offset, first, rtype, addend);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
BOOST_REQUIRE_EQUAL(writer.save(file_name), true);
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
elfio reader;
|
||||
BOOST_REQUIRE_EQUAL(reader.load(file_name), true);
|
||||
|
||||
auto prelsec = reader.sections[".rel.text"];
|
||||
auto psyms = reader.sections[".symtab"];
|
||||
|
||||
BOOST_REQUIRE_NE(prelsec, nullptr);
|
||||
BOOST_REQUIRE_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;
|
||||
Elf_Word 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.push_back(name);
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(before.begin(), before.end(), after.begin(), after.end());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user