summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuliano Procida <gprocida@google.com>2022-04-07 17:29:25 +0100
committerDodji Seketeli <dodji@redhat.com>2022-05-04 11:34:46 +0200
commit5106149c77f297db1613d76235e5f58afc043fa5 (patch)
tree03c272e5a05f9027af55f8f87ee393d2fc50b681
parentctf-reader: Fix multiple var-decl in anonymous struct/uninons (diff)
downloadlibabigail-5106149c77f297db1613d76235e5f58afc043fa5.tar.gz
libabigail-5106149c77f297db1613d76235e5f58afc043fa5.tar.bz2
libabigail-5106149c77f297db1613d76235e5f58afc043fa5.tar.xz
symtab: refactor ELF symbol value tweaks
A previous changes duplicated some logic for tweaking ELF symbol values (and possibly updating some bookkeeping information). This change refactors the code so the logic is in one place, in symtab::get_symbol_value. * src/abg-symtab-reader.cc (symtab::load_): Replace address tweaking logic with a call to get_symbol_value. (symtab::add_alternative_address_lookups): Likewise. (symtab::get_symbol_value): New function containing address tweaking logic for PPC and ARM. Signed-off-by: Giuliano Procida <gprocida@google.com>
-rw-r--r--src/abg-symtab-reader.cc81
-rw-r--r--src/abg-symtab-reader.h5
2 files changed, 46 insertions, 40 deletions
diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc
index b42ce87d..026988ee 100644
--- a/src/abg-symtab-reader.cc
+++ b/src/abg-symtab-reader.cc
@@ -236,9 +236,6 @@ symtab::load_(Elf* elf_handle,
236 std::unordered_set<std::string> exported_kernel_symbols; 236 std::unordered_set<std::string> exported_kernel_symbols;
237 std::unordered_map<std::string, uint64_t> crc_values; 237 std::unordered_map<std::string, uint64_t> crc_values;
238 238
239 const bool is_arm32 = elf_helpers::architecture_is_arm32(elf_handle);
240 const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle);
241
242 for (size_t i = 0; i < number_syms; ++i) 239 for (size_t i = 0; i < number_syms; ++i)
243 { 240 {
244 GElf_Sym *sym, sym_mem; 241 GElf_Sym *sym, sym_mem;
@@ -347,23 +344,8 @@ symtab::load_(Elf* elf_handle,
347 } 344 }
348 else if (symbol_sptr->is_defined()) 345 else if (symbol_sptr->is_defined())
349 { 346 {
350 GElf_Addr symbol_value = 347 const GElf_Addr symbol_value =
351 elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle, 348 get_symbol_value(elf_handle, sym, symbol_sptr);
352 sym);
353
354 // See also symtab::add_alternative_address_lookups.
355 if (symbol_sptr->is_function())
356 {
357 if (is_arm32)
358 // Clear bit zero of ARM32 addresses as per "ELF for the Arm
359 // Architecture" section 5.5.3.
360 // https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
361 symbol_value &= ~1;
362 else if (is_ppc64)
363 update_function_entry_address_symbol_map(elf_handle, sym,
364 symbol_sptr);
365 }
366
367 const auto result = 349 const auto result =
368 addr_symbol_map_.emplace(symbol_value, symbol_sptr); 350 addr_symbol_map_.emplace(symbol_value, symbol_sptr);
369 if (!result.second) 351 if (!result.second)
@@ -483,6 +465,43 @@ symtab::update_main_symbol(GElf_Addr addr, const std::string& name)
483 addr_symbol_map_[addr] = new_main; 465 addr_symbol_map_[addr] = new_main;
484} 466}
485 467
468/// Various adjustments and bookkeeping may be needed to provide a correct
469/// interpretation (one that matches DWARF addresses) of raw symbol values.
470///
471/// @param elf_handle the ELF handle
472///
473/// @param elf_symbol the ELF symbol
474///
475/// @param symbol_sptr the libabigail symbol
476///
477/// @return a possibly-adjusted symbol value
478GElf_Addr
479symtab::get_symbol_value(Elf* elf_handle,
480 GElf_Sym* elf_symbol,
481 const elf_symbol_sptr& symbol_sptr)
482{
483 const bool is_arm32 = elf_helpers::architecture_is_arm32(elf_handle);
484 const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle);
485
486 GElf_Addr symbol_value =
487 elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle,
488 elf_symbol);
489
490 if (symbol_sptr->is_function())
491 {
492 if (is_arm32)
493 // Clear bit zero of ARM32 addresses as per "ELF for the Arm
494 // Architecture" section 5.5.3.
495 // https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
496 symbol_value &= ~1;
497 else if (is_ppc64)
498 update_function_entry_address_symbol_map(elf_handle, elf_symbol,
499 symbol_sptr);
500 }
501
502 return symbol_value;
503}
504
486/// Update the function entry symbol map to later allow lookups of this symbol 505/// Update the function entry symbol map to later allow lookups of this symbol
487/// by entry address as well. This is relevant for ppc64 ELFv1 binaries. 506/// by entry address as well. This is relevant for ppc64 ELFv1 binaries.
488/// 507///
@@ -582,9 +601,6 @@ symtab::update_function_entry_address_symbol_map(
582void 601void
583symtab::add_alternative_address_lookups(Elf* elf_handle) 602symtab::add_alternative_address_lookups(Elf* elf_handle)
584{ 603{
585 const bool is_arm32 = elf_helpers::architecture_is_arm32(elf_handle);
586 const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle);
587
588 Elf_Scn* symtab_section = elf_helpers::find_symtab_section(elf_handle); 604 Elf_Scn* symtab_section = elf_helpers::find_symtab_section(elf_handle);
589 if (!symtab_section) 605 if (!symtab_section)
590 return; 606 return;
@@ -634,23 +650,8 @@ symtab::add_alternative_address_lookups(Elf* elf_handle)
634 if (symbols.size() == 1) 650 if (symbols.size() == 1)
635 { 651 {
636 const auto& symbol_sptr = symbols[0]; 652 const auto& symbol_sptr = symbols[0];
637 GElf_Addr symbol_value = 653 const GElf_Addr symbol_value =
638 elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr( 654 get_symbol_value(elf_handle, sym, symbol_sptr);
639 elf_handle, sym);
640
641 // See also symtab::load_.
642 if (symbol_sptr->is_function())
643 {
644 if (is_arm32)
645 // Clear bit zero of ARM32 addresses as per "ELF for the Arm
646 // Architecture" section 5.5.3.
647 // https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
648 symbol_value &= ~1;
649 else if (is_ppc64)
650 update_function_entry_address_symbol_map(elf_handle, sym,
651 symbol_sptr);
652 }
653
654 addr_symbol_map_.emplace(symbol_value, symbol_sptr); 655 addr_symbol_map_.emplace(symbol_value, symbol_sptr);
655 } 656 }
656 } 657 }
diff --git a/src/abg-symtab-reader.h b/src/abg-symtab-reader.h
index 7ac15352..bddde2f6 100644
--- a/src/abg-symtab-reader.h
+++ b/src/abg-symtab-reader.h
@@ -289,6 +289,11 @@ private:
289 load_(string_elf_symbols_map_sptr function_symbol_map, 289 load_(string_elf_symbols_map_sptr function_symbol_map,
290 string_elf_symbols_map_sptr variables_symbol_map); 290 string_elf_symbols_map_sptr variables_symbol_map);
291 291
292 GElf_Addr
293 get_symbol_value(Elf* elf_handle,
294 GElf_Sym* elf_symbol,
295 const elf_symbol_sptr& symbol_sptr);
296
292 void 297 void
293 update_function_entry_address_symbol_map(Elf* elf_handle, 298 update_function_entry_address_symbol_map(Elf* elf_handle,
294 GElf_Sym* native_symbol, 299 GElf_Sym* native_symbol,