Skip to content

Commit

Permalink
Resolve: #1089
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Aug 24, 2024
1 parent 47d707f commit ecbedb4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
2 changes: 2 additions & 0 deletions doc/sphinx/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Changelog
:ELF:

* Add support for RISC-V architecture
* Fix bug when trying to remove a dynamic symbol that is associated with
multiple relocations (:issue:`1089`)

:Extended:

Expand Down
38 changes: 26 additions & 12 deletions src/ELF/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,27 +633,41 @@ void Binary::remove_dynamic_symbol(Symbol* symbol) {
R.symbol(nullptr);
}

it_relocation = std::find_if(std::begin(relocations_), std::end(relocations_),
[symbol] (const std::unique_ptr<Relocation>& relocation) {
return relocation->purpose() == Relocation::PURPOSE::DYNAMIC &&
relocation->has_symbol() && relocation->symbol() == symbol;
});
const size_t nb_relocs = relocations_.size();
size_t rel_sizeof = 0;

if (it_relocation != std::end(relocations_)) {
const size_t rel_sizeof = get_relocation_sizeof(*this, **it_relocation);
relocations_.erase(
std::remove_if(relocations_.begin(), relocations_.end(),
[symbol, this, &rel_sizeof] (const std::unique_ptr<Relocation>& reloc) {
if (reloc->purpose() != Relocation::PURPOSE::DYNAMIC) {
return false;
}

if (const Symbol* sym = reloc->symbol(); sym == symbol) {
rel_sizeof = get_relocation_sizeof(*this, *reloc);
return true;
}

return false;
}
), relocations_.end());

const size_t nb_deleted_relocs = nb_relocs - relocations_.size();

if (nb_deleted_relocs > 0) {
const size_t relocs_size = nb_deleted_relocs * rel_sizeof;
if (auto* DT = get(DynamicEntry::TAG::RELASZ)) {
const uint64_t sizes = DT->value();
if (sizes >= rel_sizeof) {
DT->value(sizes - rel_sizeof);
if (sizes >= relocs_size) {
DT->value(sizes - relocs_size);
}
}
else if (auto* DT = get(DynamicEntry::TAG::RELSZ)) {
const uint64_t sizes = DT->value();
if (sizes >= rel_sizeof) {
DT->value(sizes - rel_sizeof);
if (sizes >= relocs_size) {
DT->value(sizes - relocs_size);
}
}
relocations_.erase(it_relocation);
}

// Update symbol versions
Expand Down
15 changes: 15 additions & 0 deletions tests/elf/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,18 @@ def test_issue_1082():
assert imp_symbols[0] == "printf"
assert imp_symbols[2] == "__libc_start_main@GLIBC_2.34"
assert imp_symbols[3] == "printf@GLIBC_2.27"

def test_issue_1089(tmp_path: Path):
elf = lief.ELF.parse(get_sample("ELF/libip4tc.so.2.0.0"))

original_nb_relocations = len(elf.dynamic_relocations)

elf.remove_dynamic_symbol("iptc_read_counter")

out = tmp_path / "libip4tc.so.2.0.0"
elf.write(out.as_posix())

new = lief.ELF.parse(out)

assert new.get_symbol("iptc_read_counter") is None
assert len(new.dynamic_relocations) == original_nb_relocations - 2

0 comments on commit ecbedb4

Please sign in to comment.