LibELF: Implement GNU hash section lookups for x86_64

This commit is contained in:
Gunnar Beutner 2021-06-29 00:41:30 +02:00 committed by Andreas Kling
parent d138424549
commit c81d959afb
Notes: sideshowbarker 2024-07-18 11:20:35 +09:00

View file

@ -276,8 +276,7 @@ auto DynamicObject::HashSection::lookup_sysv_symbol(const StringView& name, u32
auto DynamicObject::HashSection::lookup_gnu_symbol(const StringView& name, u32 hash_value) const -> Optional<Symbol> auto DynamicObject::HashSection::lookup_gnu_symbol(const StringView& name, u32 hash_value) const -> Optional<Symbol>
{ {
// Algorithm reference: https://ent-voy.blogspot.com/2011/02/ // Algorithm reference: https://ent-voy.blogspot.com/2011/02/
// TODO: Handle 64bit bloomwords for ELF_CLASS64 using BloomWord = FlatPtr;
using BloomWord = u32;
constexpr size_t bloom_word_size = sizeof(BloomWord) * 8; constexpr size_t bloom_word_size = sizeof(BloomWord) * 8;
const u32* hash_table_begin = (u32*)address().as_ptr(); const u32* hash_table_begin = (u32*)address().as_ptr();
@ -289,13 +288,13 @@ auto DynamicObject::HashSection::lookup_gnu_symbol(const StringView& name, u32 h
const u32 num_maskwords_bitmask = num_maskwords - 1; const u32 num_maskwords_bitmask = num_maskwords - 1;
const u32 shift2 = hash_table_begin[3]; const u32 shift2 = hash_table_begin[3];
const BloomWord* bloom_words = &hash_table_begin[4]; const BloomWord* bloom_words = (BloomWord const*)&hash_table_begin[4];
const u32* const buckets = &bloom_words[num_maskwords]; const u32* const buckets = (u32 const*)&bloom_words[num_maskwords];
const u32* const chains = &buckets[num_buckets]; const u32* const chains = &buckets[num_buckets];
BloomWord hash1 = hash_value; BloomWord hash1 = hash_value;
BloomWord hash2 = hash1 >> shift2; BloomWord hash2 = hash1 >> shift2;
const BloomWord bitmask = (1 << (hash1 % bloom_word_size)) | (1 << (hash2 % bloom_word_size)); const BloomWord bitmask = ((BloomWord)1 << (hash1 % bloom_word_size)) | ((BloomWord)1 << (hash2 % bloom_word_size));
if ((bloom_words[(hash1 / bloom_word_size) & num_maskwords_bitmask] & bitmask) != bitmask) if ((bloom_words[(hash1 / bloom_word_size) & num_maskwords_bitmask] & bitmask) != bitmask)
return {}; return {};