mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:07:36 +00:00
LibELF: Correctly determine symbol amount for DT_GNU_HASH table
This commit is contained in:
parent
eada4f2ee8
commit
90ff6cca8a
2 changed files with 33 additions and 5 deletions
|
@ -216,10 +216,39 @@ void DynamicObject::parse()
|
||||||
m_size_of_relocation_table -= m_size_of_plt_relocation_entry_list;
|
m_size_of_relocation_table -= m_size_of_plt_relocation_entry_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto hash_section_address = hash_section().address().as_ptr();
|
u32 const* hash_table_begin = reinterpret_cast<u32 const*>(hash_section().address().as_ptr());
|
||||||
// TODO: consider base address - it might not be zero
|
|
||||||
auto num_hash_chains = ((u32*)hash_section_address)[1];
|
if (m_hash_type == HashType::SYSV) {
|
||||||
m_symbol_count = num_hash_chains;
|
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
|
DynamicObject::Relocation DynamicObject::RelocationSection::relocation(unsigned index) const
|
||||||
|
|
|
@ -565,7 +565,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (object->symbol_count()) {
|
if (object->symbol_count()) {
|
||||||
// FIXME: Add support for init/fini/start/main sections
|
|
||||||
outln(" Num: Value{} Size{} Type Bind Name", addr_padding, addr_padding);
|
outln(" Num: Value{} Size{} Type Bind Name", addr_padding, addr_padding);
|
||||||
object->for_each_symbol([](const ELF::DynamicObject::Symbol& sym) {
|
object->for_each_symbol([](const ELF::DynamicObject::Symbol& sym) {
|
||||||
out(" {:>4}: ", sym.index());
|
out(" {:>4}: ", sym.index());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue