diff options
author | Giuliano Procida <gprocida@google.com> | 2022-04-07 17:29:25 +0100 |
---|---|---|
committer | Dodji Seketeli <dodji@redhat.com> | 2022-05-04 11:34:46 +0200 |
commit | 5106149c77f297db1613d76235e5f58afc043fa5 (patch) | |
tree | 03c272e5a05f9027af55f8f87ee393d2fc50b681 | |
parent | ctf-reader: Fix multiple var-decl in anonymous struct/uninons (diff) | |
download | libabigail-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.cc | 81 | ||||
-rw-r--r-- | src/abg-symtab-reader.h | 5 |
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 | ||
478 | GElf_Addr | ||
479 | symtab::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( | |||
582 | void | 601 | void |
583 | symtab::add_alternative_address_lookups(Elf* elf_handle) | 602 | symtab::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, |