dwarf-reader: Use all bits of Bloom filter words.
authorGiuliano Procida <gprocida@google.com>
Wed, 18 Mar 2020 12:12:41 +0000 (12:12 +0000)
committerDodji Seketeli <dodji@redhat.com>
Thu, 19 Mar 2020 10:01:36 +0000 (11:01 +0100)
Most of the bit values used for GNU hash ELF section Bloom filtering
were being ignored due to integer narrowing, reducing missing symbol
filtering efficiency considerably.

This patch fixes this.

Note on testing.

The .gnu.hash section seems to be present in all the .so but none of
the .o test files. abisym doesn't appear to find dynamic symbols (nm
-D), only normal ones, so it was a little tricky to test this.

I found a Debian .so (libpthread) with both the .gnu.hash section and
normal symbols. abisym behaves identically with my change, looking up
lots of present and non-present (as far as it's concerned) symbols. I
just extracted a full list with nm/sed and looked up each one.

389 symbols looked up, 241 present, 148 absent
8-bit filter: 336 maybe, 53 no (53/148 filtering efficiency)
64-bit filter: 255 maybe, 134 no (134/148 filtering efficiency)

* src/abg-dwarf-reader.cc (lookup_symbol_from_gnu_hash_tab):
Don't narrow calculated Bloom word to 8 bits before using it
to mask the fetched Bloom word.

Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-dwarf-reader.cc

index ff532cfd244ea48b4ce52c5135823e29c256c4b6..5bc8a157693a176c4d3ba9b5e52f40f3f336e185 100644 (file)
@@ -2025,7 +2025,7 @@ lookup_symbol_from_gnu_hash_tab(const environment*                env,
   // filter, in bits.
   int c = get_elf_class_size_in_bytes(elf_handle) * 8;
   int n =  (h1 / c) % ht.bf_nwords;
-  unsigned char bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
+  GElf_Word bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
 
   // Test if the symbol is *NOT* present in this ELF file.
   if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)