Skip to content

Commit

Permalink
LibELF: Correctly determine symbol amount for DT_GNU_HASH table
Browse files Browse the repository at this point in the history
  • Loading branch information
Ollrogge committed Jan 7, 2024
1 parent 8538d6e commit bd3965a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
37 changes: 33 additions & 4 deletions Userland/Libraries/LibELF/DynamicObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,39 @@ void DynamicObject::parse()
m_size_of_relocation_table -= m_size_of_plt_relocation_entry_list;
}

auto hash_section_address = hash_section().address().as_ptr();
// TODO: consider base address - it might not be zero
auto num_hash_chains = ((u32*)hash_section_address)[1];
m_symbol_count = num_hash_chains;
u32 const* hash_table_begin = reinterpret_cast<u32 const*>(hash_section().address().as_ptr());

if (m_hash_type == HashType::SYSV) {
u32 n_chain = hash_table_begin[1];
m_symbol_count = n_chain;
return;
}

// Determine amount of symbols by finding the chain with the highest
// starting index and walking this chain until the end to find the
// maximum index = amount of symbols.
using BloomWord = FlatPtr;
size_t const num_buckets = hash_table_begin[0];
size_t const num_omitted_symbols = hash_table_begin[1];
u32 const num_maskwords = hash_table_begin[2];
BloomWord const* bloom_words = reinterpret_cast<BloomWord const*>(&hash_table_begin[4]);
u32 const* const buckets = reinterpret_cast<u32 const*>(&bloom_words[num_maskwords]);
u32 const* const chains = &buckets[num_buckets];

size_t highest_chain_idx = 0;
for (size_t i = 0; i < num_buckets; i++) {
if (buckets[i] > highest_chain_idx) {
highest_chain_idx = buckets[i];
}
}

size_t amount_symbols = highest_chain_idx;
u32 const* last_chain = &chains[highest_chain_idx - num_omitted_symbols];
while ((*(last_chain++) & 1) == 0) {
amount_symbols++;
}

m_symbol_count = amount_symbols + 1;
}

DynamicObject::Relocation DynamicObject::RelocationSection::relocation(unsigned index) const
Expand Down
1 change: 0 additions & 1 deletion Userland/Utilities/readelf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
});

if (object->symbol_count()) {
// FIXME: Add support for init/fini/start/main sections
outln(" Num: Value{} Size{} Type Bind Name", addr_padding, addr_padding);
object->for_each_symbol([](const ELF::DynamicObject::Symbol& sym) {
out(" {:>4}: ", sym.index());
Expand Down

0 comments on commit bd3965a

Please sign in to comment.