diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 5bc8a157..10ca1232 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -1850,20 +1850,27 @@ get_elf_class_size_in_bytes(Elf* elf_handle) } /// Get a given word of a bloom filter, referred to by the index of -/// the word. The word size depends on the current elf class and this -/// function abstracts that nicely. +/// the word. +/// +/// The bloom word size depends on the current elf class (32 bits for +/// an ELFCLASS32 or 64 bits for an ELFCLASS64 one) and this function +/// abstracts that nicely. /// /// @param elf_handle the elf handle to use. /// /// @param bloom_filter the bloom filter to consider. /// /// @param index the index of the bloom filter to return. -static GElf_Word +/// +/// @return a 64 bits work containing the bloom word found at index @p +/// index. Note that if we are looking at an ELFCLASS32 binary, the 4 +/// most significant bytes of the result are going to be zero. +static Elf64_Xword bloom_word_at(Elf* elf_handle, Elf32_Word* bloom_filter, size_t index) { - GElf_Word result = 0; + Elf64_Xword result = 0; GElf_Ehdr h; ABG_ASSERT(gelf_getehdr(elf_handle, &h)); int c; @@ -1876,7 +1883,7 @@ bloom_word_at(Elf* elf_handle, break ; case ELFCLASS64: { - GElf_Word* f= reinterpret_cast(bloom_filter); + Elf64_Xword* f= reinterpret_cast(bloom_filter); result = f[index]; } break; @@ -2025,7 +2032,12 @@ 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; - GElf_Word bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c)); + // The bitmask of the bloom filter has a size of either 32-bits on + // ELFCLASS32 binaries or 64-bits on ELFCLASS64 binaries. So we + // need a 64-bits type to hold the bitmap, hence the Elf64_Xword + // type used here. When dealing with 32bits binaries, the upper + // bits of the bitmask will be zero anyway. + Elf64_Xword 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) diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index e9fdad1e..cf7792f1 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -1324,6 +1324,8 @@ test-lookup-syms/test02-report.txt \ test-lookup-syms/test1.c \ test-lookup-syms/test1.version-script \ test-lookup-syms/test1.so \ +test-lookup-syms/test1-32bits.so \ +test-lookup-syms/test1.c.compiling.txt \ test-lookup-syms/test1-1-report.txt \ test-lookup-syms/test1-2-report.txt \ test-lookup-syms/test1-3-report.txt \ diff --git a/tests/data/test-lookup-syms/test1-32bits.so b/tests/data/test-lookup-syms/test1-32bits.so new file mode 100755 index 00000000..119cee41 Binary files /dev/null and b/tests/data/test-lookup-syms/test1-32bits.so differ diff --git a/tests/data/test-lookup-syms/test1.c.compiling.txt b/tests/data/test-lookup-syms/test1.c.compiling.txt new file mode 100644 index 00000000..6753d63d --- /dev/null +++ b/tests/data/test-lookup-syms/test1.c.compiling.txt @@ -0,0 +1,9 @@ +To re-compile test1.so (on a 64-bits machine), please do: + +gcc -g -shared -Wl,--version-script=test1.version-script -o test1.so test1.c + + +To re-compile test1-32.so, please do: + +gcc -g -m32 -shared -Wl,--version-script=test1.version-script -o test1.so test1.c + diff --git a/tests/test-lookup-syms.cc b/tests/test-lookup-syms.cc index 2f4d8f77..077f33b9 100644 --- a/tests/test-lookup-syms.cc +++ b/tests/test-lookup-syms.cc @@ -73,6 +73,13 @@ InOutSpec in_out_specs[] = "data/test-lookup-syms/test1-1-report.txt", "output/test-lookup-syms/test1-1-report.txt" }, + { + "data/test-lookup-syms/test1-32bits.so", + "foo", + "", + "data/test-lookup-syms/test1-1-report.txt", + "output/test-lookup-syms/test1-1-report.txt" + }, { "data/test-lookup-syms/test1.so", "_foo1",