summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuliano Procida <gprocida@google.com>2022-04-07 17:29:26 +0100
committerDodji Seketeli <dodji@redhat.com>2022-05-04 11:44:04 +0200
commitc96463e1ad974b7c4561886d7a3aa8a3c9a35607 (patch)
treeac57864a8d4d9497f343623ac96a9a30d5b738da
parentsymtab: refactor ELF symbol value tweaks (diff)
downloadlibabigail-c96463e1ad974b7c4561886d7a3aa8a3c9a35607.tar.gz
libabigail-c96463e1ad974b7c4561886d7a3aa8a3c9a35607.tar.bz2
libabigail-c96463e1ad974b7c4561886d7a3aa8a3c9a35607.tar.xz
symtab: fix up 64-bit ARM address which may contain tags
64-bit ARM addresses normally have bits 47 to 63 as either all 0 or all 1. If tagging is used, bits 56 to 63 can vary, but the interpretation of such values is as if the bits were all the same as bit 55. Such tagging is used for HWASAN and this affects the ELF symbol values seen in shared libraries. This commit changes the interpretation of 64-bit ARM symbol values by unconditionally extending bit 55 into bits 56 to 63. This fixes missing types for symbols in HWASAN-compiled libraries. * src/abg-elf-helpers.cc: (architecture_is_arm64): Add helper. * src/abg-elf-helpers.h: Likewise. * src/abg-symtab-reader.cc: (get_symbol_value): Adjust 64-bit ARM symbol values by extending bit 55 into bits 56 to 63. Signed-off-by: Giuliano Procida <gprocida@google.com>
-rw-r--r--src/abg-elf-helpers.cc17
-rw-r--r--src/abg-elf-helpers.h3
-rw-r--r--src/abg-symtab-reader.cc6
3 files changed, 26 insertions, 0 deletions
diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc
index ee631831..787a05ff 100644
--- a/src/abg-elf-helpers.cc
+++ b/src/abg-elf-helpers.cc
@@ -900,6 +900,23 @@ architecture_is_arm32(Elf* elf_handle)
900 return (elf_header && elf_header->e_machine == EM_ARM); 900 return (elf_header && elf_header->e_machine == EM_ARM);
901} 901}
902 902
903/// Test if the architecture of the current binary is arm64.
904///
905/// @param elf_handle the ELF handle to consider.
906///
907/// @return true iff the architecture of the current binary is arm64.
908bool
909architecture_is_arm64(Elf* elf_handle)
910{
911#ifdef HAVE_EM_AARCH64_MACRO
912 GElf_Ehdr eh_mem;
913 GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
914 return (elf_header && elf_header->e_machine == EM_AARCH64);
915#else
916 return false;
917#endif
918}
919
903/// Test if the endianness of the current binary is Big Endian. 920/// Test if the endianness of the current binary is Big Endian.
904/// 921///
905/// https://en.wikipedia.org/wiki/Endianness. 922/// https://en.wikipedia.org/wiki/Endianness.
diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h
index 718ce9c1..afaff24a 100644
--- a/src/abg-elf-helpers.h
+++ b/src/abg-elf-helpers.h
@@ -148,6 +148,9 @@ bool
148architecture_is_arm32(Elf* elf_handle); 148architecture_is_arm32(Elf* elf_handle);
149 149
150bool 150bool
151architecture_is_arm64(Elf* elf_handle);
152
153bool
151architecture_is_big_endian(Elf* elf_handle); 154architecture_is_big_endian(Elf* elf_handle);
152 155
153GElf_Addr 156GElf_Addr
diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc
index 026988ee..3740cb7a 100644
--- a/src/abg-symtab-reader.cc
+++ b/src/abg-symtab-reader.cc
@@ -481,6 +481,7 @@ symtab::get_symbol_value(Elf* elf_handle,
481 const elf_symbol_sptr& symbol_sptr) 481 const elf_symbol_sptr& symbol_sptr)
482{ 482{
483 const bool is_arm32 = elf_helpers::architecture_is_arm32(elf_handle); 483 const bool is_arm32 = elf_helpers::architecture_is_arm32(elf_handle);
484 const bool is_arm64 = elf_helpers::architecture_is_arm64(elf_handle);
484 const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle); 485 const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle);
485 486
486 GElf_Addr symbol_value = 487 GElf_Addr symbol_value =
@@ -498,6 +499,11 @@ symtab::get_symbol_value(Elf* elf_handle,
498 update_function_entry_address_symbol_map(elf_handle, elf_symbol, 499 update_function_entry_address_symbol_map(elf_handle, elf_symbol,
499 symbol_sptr); 500 symbol_sptr);
500 } 501 }
502 if (is_arm64)
503 // Copy bit 55 over bits 56 to 63 which may be tag information.
504 symbol_value = symbol_value & (1ULL<<55)
505 ? symbol_value | (0xffULL<<56)
506 : symbol_value &~ (0xffULL<<56);
501 507
502 return symbol_value; 508 return symbol_value;
503} 509}