public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
From: Matthias Maennich <maennich@google.com>
To: libabigail@sourceware.org
Cc: dodji@seketeli.org, gprocida@google.com, kernel-team@android.com,
	 maennich@google.com
Subject: [PATCH 13/20] symtab_reader: add support for ppc64 ELFv1 binaries
Date: Wed, 27 Jan 2021 12:58:46 +0000	[thread overview]
Message-ID: <20210127125853.886677-14-maennich@google.com> (raw)
In-Reply-To: <20210127125853.886677-1-maennich@google.com>

When loading the symtab from an ppc64 binary, also keep track of the
function entry addresses as a key for the symbol lookup. That
accommodates the differences in DWARF pointing to the function entry
address while the symbol table points to the function pointer.

The implementation is mostly copied and adopted from abg-dwarf-reader's
read_context to add this functionality also to the new symtab reader.

	* src/abg-symtab-reader.cc (symtab::lookup_symbol): fall back to
	  lookup the address in entry_addr_symbol_map_.
	  (symtab::load): update the function entry address map for
	  ppc64 targets.
	  (symtab::update_function_entry_address_symbol_map): New
	  function implementation.
	* src/abg-symtab-reader.h
	  (symtab::entry_addr_symbol_map_): New data member.
	  (symtab::update_function_entry_address_symbol_map): New
	  function declaration.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
---
 src/abg-symtab-reader.cc | 93 ++++++++++++++++++++++++++++++++++++++--
 src/abg-symtab-reader.h  |  8 ++++
 2 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc
index 4576be2a0b42..7318fdfce52e 100644
--- a/src/abg-symtab-reader.cc
+++ b/src/abg-symtab-reader.cc
@@ -100,9 +100,15 @@ const elf_symbol_sptr&
 symtab::lookup_symbol(GElf_Addr symbol_addr) const
 {
   static const elf_symbol_sptr empty_result;
-  const auto it = addr_symbol_map_.find(symbol_addr);
-  if (it != addr_symbol_map_.end())
-      return it->second;
+  const auto addr_it = addr_symbol_map_.find(symbol_addr);
+  if (addr_it != addr_symbol_map_.end())
+    return addr_it->second;
+  else
+    {
+      const auto entry_it = entry_addr_symbol_map_.find(symbol_addr);
+      if (entry_it != entry_addr_symbol_map_.end())
+	return entry_it->second;
+    }
   return empty_result;
 }
 
@@ -197,6 +203,8 @@ symtab::load_(Elf*	       elf_handle,
   const bool is_kernel = elf_helpers::is_linux_kernel(elf_handle);
   std::unordered_set<std::string> exported_kernel_symbols;
 
+  const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle);
+
   for (size_t i = 0; i < number_syms; ++i)
     {
       GElf_Sym *sym, sym_mem;
@@ -304,6 +312,10 @@ symtab::load_(Elf*	       elf_handle,
 	      elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle,
 								    sym);
 
+	  if (is_ppc64 && symbol_sptr->is_function())
+	    update_function_entry_address_symbol_map(elf_handle, sym,
+						     symbol_sptr);
+
 	  const auto result =
 	    addr_symbol_map_.emplace(symbol_value, symbol_sptr);
 	  if (!result.second)
@@ -364,5 +376,80 @@ symtab::load_(string_elf_symbols_map_sptr function_symbol_map,
   return true;
 }
 
+void
+symtab::update_function_entry_address_symbol_map(
+    Elf*		   elf_handle,
+    GElf_Sym*		   native_symbol,
+    const elf_symbol_sptr& symbol_sptr)
+{
+
+  // For ppc64 ELFv1 binaries, we need to build a function entry point address
+  // -> function symbol map. This is in addition to the function pointer ->
+  // symbol map.  This is because on ppc64 ELFv1, a function pointer is
+  // different from a function entry point address.
+  //
+  // On ppc64 ELFv1, the DWARF DIE of a function references the address of the
+  // entry point of the function symbol; whereas the value of the function
+  // symbol is the function pointer. As these addresses are different, if I we
+  // want to get to the symbol of a function from its entry point address (as
+  // referenced by DWARF function DIEs) we must have the two maps I mentionned
+  // right above.
+  //
+  // In other words, we need a map that associates a function entry point
+  // address with the symbol of that function, to be able to get the function
+  // symbol that corresponds to a given function DIE, on ppc64.
+  //
+  // The value of the function pointer (the value of the symbol) usually refers
+  // to the offset of a table in the .opd section.  But sometimes, for a symbol
+  // named "foo", the corresponding symbol named ".foo" (note the dot before
+  // foo) which value is the entry point address of the function; that entry
+  // point address refers to a region in the .text section.
+  //
+  // So we are only interested in values of the symbol that are in the .opd
+  // section.
+  const GElf_Addr fn_desc_addr = native_symbol->st_value;
+  const GElf_Addr fn_entry_point_addr =
+    elf_helpers::lookup_ppc64_elf_fn_entry_point_address(elf_handle,
+							 fn_desc_addr);
+
+  const std::pair<addr_symbol_map_type::const_iterator, bool>& result =
+    entry_addr_symbol_map_.emplace(fn_entry_point_addr, symbol_sptr);
+
+  const addr_symbol_map_type::const_iterator it = result.first;
+  const bool was_inserted = result.second;
+  if (!was_inserted
+      && elf_helpers::address_is_in_opd_section(elf_handle, fn_desc_addr))
+    {
+      // Either
+      //
+      // 'symbol' must have been registered as an alias for
+      // it->second->get_main_symbol()
+      //
+      // Or
+      //
+      // if the name of 'symbol' is foo, then the name of it2->second is
+      // ".foo". That is, foo is the name of the symbol when it refers to the
+      // function descriptor in the .opd section and ".foo" is an internal name
+      // for the address of the entry point of foo.
+      //
+      // In the latter case, we just want to keep a reference to "foo" as .foo
+      // is an internal name.
+
+      const bool two_symbols_alias =
+	it->second->get_main_symbol()->does_alias(*symbol_sptr);
+      const bool symbol_is_foo_and_prev_symbol_is_dot_foo =
+	(it->second->get_name() == std::string(".") + symbol_sptr->get_name());
+
+      ABG_ASSERT(two_symbols_alias
+		 || symbol_is_foo_and_prev_symbol_is_dot_foo);
+
+      if (symbol_is_foo_and_prev_symbol_is_dot_foo)
+	// Let's just keep a reference of the symbol that the user sees in the
+	// source code (the one named foo). The symbol which name is prefixed
+	// with a "dot" is an artificial one.
+	entry_addr_symbol_map_[fn_entry_point_addr] = symbol_sptr;
+    }
+}
+
 } // end namespace symtab_reader
 } // end namespace abigail
diff --git a/src/abg-symtab-reader.h b/src/abg-symtab-reader.h
index 4c5e3b85c22d..2906bab818b0 100644
--- a/src/abg-symtab-reader.h
+++ b/src/abg-symtab-reader.h
@@ -251,12 +251,20 @@ private:
   typedef std::unordered_map<GElf_Addr, elf_symbol_sptr> addr_symbol_map_type;
   addr_symbol_map_type addr_symbol_map_;
 
+  /// Lookup map function entry address -> symbol
+  addr_symbol_map_type entry_addr_symbol_map_;
+
   bool
   load_(Elf* elf_handle, ir::environment* env, symbol_predicate is_suppressed);
 
   bool
   load_(string_elf_symbols_map_sptr function_symbol_map,
        string_elf_symbols_map_sptr variables_symbol_map);
+
+  void
+  update_function_entry_address_symbol_map(Elf*	     elf_handle,
+					   GElf_Sym* native_symbol,
+					   const elf_symbol_sptr& symbol_sptr);
 };
 
 /// Helper class to allow range-for loops on symtabs for C++11 and later code.
-- 
2.30.0.280.ga3ce27912f-goog


  parent reply	other threads:[~2021-01-27 12:59 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-19 21:42 [PATCH v1 00/16] Refactor (k)symtab reader Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 01/16] abg-cxx-compat: add simplified version of std::optional Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 02/16] abg-cxx-compat: more <functional> support: std::bind and friends Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 03/16] abg-ir: elf_symbol: add is_in_ksymtab field Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 04/16] abg-ir: elf_symbol: add is_suppressed field Matthias Maennich
2020-06-22  9:46   ` Giuliano Procida
2020-06-19 21:42 ` [PATCH v1 05/16] dwarf-reader split: create abg-symtab-reader.{h, cc} and test case Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 06/16] Refactor ELF symbol table reading by adding a new symtab reader Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 07/16] Integrate new symtab reader into corpus and read_context Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 08/16] corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab Matthias Maennich
2020-06-22  9:53   ` Giuliano Procida
2020-06-19 21:42 ` [PATCH v1 09/16] corpus: make get_unreferenced_(function|variable)_symbols " Matthias Maennich
2020-06-19 21:42 ` [PATCH v1 10/16] abg-reader: avoid using the (var|function)_symbol_map Matthias Maennich
2020-06-19 21:43 ` [PATCH v1 11/16] dwarf-reader: read_context: use new symtab in *_symbols_is_exported Matthias Maennich
2020-06-19 21:43 ` [PATCH v1 12/16] Switch kernel stuff over to new symtab and drop unused code Matthias Maennich
2020-06-19 21:43 ` [PATCH v1 13/16] abg-elf-helpers: migrate ppc64 specific helpers Matthias Maennich
2020-06-19 21:43 ` [PATCH v1 14/16] symtab_reader: add support for ppc64 ELFv1 binaries Matthias Maennich
2020-06-19 21:43 ` [PATCH v1 15/16] abg-corpus: remove symbol maps and their setters Matthias Maennich
2020-06-19 21:43 ` [PATCH v1 16/16] dwarf reader: drop (now) unused code related symbol table reading Matthias Maennich
2020-06-22  9:56   ` Giuliano Procida
2020-07-03 16:46 ` [PATCH v2 00/21] Refactor (k)symtab reader Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 01/21] abg-cxx-compat: add simplified version of std::optional Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 02/21] abg-cxx-compat: more <functional> support: std::bind and friends Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 03/21] abg-ir: elf_symbol: add is_in_ksymtab field Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 04/21] abg-ir: elf_symbol: add is_suppressed field Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 05/21] dwarf-reader split: create abg-symtab-reader.{h, cc} and test case Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 06/21] Refactor ELF symbol table reading by adding a new symtab reader Matthias Maennich
2020-07-20 15:39     ` Dodji Seketeli
2020-07-03 16:46   ` [PATCH v2 07/21] Integrate new symtab reader into corpus and read_context Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 08/21] corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 09/21] corpus: make get_unreferenced_(function|variable)_symbols " Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 10/21] abg-reader: avoid using the (var|function)_symbol_map Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 11/21] dwarf-reader: read_context: use new symtab in *_symbols_is_exported Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 12/21] Switch kernel stuff over to new symtab and drop unused code Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 13/21] abg-elf-helpers: migrate ppc64 specific helpers Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 14/21] symtab_reader: add support for ppc64 ELFv1 binaries Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 15/21] abg-corpus: remove symbol maps and their setters Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 16/21] dwarf reader: drop now-unused code related to symbol table reading Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 17/21] test-symtab: add tests for whitelisted functions Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 18/21] symtab/dwarf-reader: allow hinting of main symbols for aliases Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 19/21] dwarf-reader/writer: consider aliases when dealing with suppressions Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 20/21] symtab: Add support for MODVERSIONS (CRC checksums) Matthias Maennich
2020-07-03 16:46   ` [PATCH v2 21/21] reader/symtab: Improve handling for suppressed aliases Matthias Maennich
2020-07-20 14:27   ` [PATCH v2 00/21] Refactor (k)symtab reader Dodji Seketeli
2021-01-27 12:58 ` [PATCH 00/20] " Matthias Maennich
2021-01-27 12:58   ` [PATCH 01/20] abg-cxx-compat: add simplified version of std::optional Matthias Maennich
2021-03-09  9:43     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 02/20] abg-ir: elf_symbol: add is_in_ksymtab field Matthias Maennich
2021-03-09 14:05     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 03/20] abg-ir: elf_symbol: add is_suppressed field Matthias Maennich
2021-03-09 18:03     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 04/20] dwarf-reader split: create abg-symtab-reader.{h, cc} and test case Matthias Maennich
2021-03-10 18:00     ` [PATCH 04/20] dwarf-reader split: create abg-symtab-reader.{h,cc} " Dodji Seketeli
2021-01-27 12:58   ` [PATCH 05/20] Refactor ELF symbol table reading by adding a new symtab reader Matthias Maennich
2021-03-12 11:18     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 06/20] Integrate new symtab reader into corpus and read_context Matthias Maennich
2021-03-12 15:04     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 07/20] corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab Matthias Maennich
2021-03-15 10:05     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 08/20] corpus: make get_unreferenced_(function|variable)_symbols " Matthias Maennich
2021-03-15 12:06     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 09/20] abg-reader: avoid using the (var|function)_symbol_map Matthias Maennich
2021-03-15 14:23     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 10/20] dwarf-reader: read_context: use new symtab in *_symbols_is_exported Matthias Maennich
2021-03-15 18:13     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 11/20] Switch kernel stuff over to new symtab and drop unused code Matthias Maennich
2021-03-16 10:38     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 12/20] abg-elf-helpers: migrate ppc64 specific helpers Matthias Maennich
2021-03-16 10:59     ` Dodji Seketeli
2021-01-27 12:58   ` Matthias Maennich [this message]
2021-03-16 11:39     ` [PATCH 13/20] symtab_reader: add support for ppc64 ELFv1 binaries Dodji Seketeli
2021-01-27 12:58   ` [PATCH 14/20] abg-corpus: remove symbol maps and their setters Matthias Maennich
2021-03-16 18:08     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 15/20] dwarf reader: drop (now) unused code related to symbol table reading Matthias Maennich
2021-03-16 18:42     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 16/20] test-symtab: add tests for whitelisted functions Matthias Maennich
2021-03-17 11:07     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 17/20] symtab/dwarf-reader: allow hinting of main symbols for aliases Matthias Maennich
2021-03-17 13:40     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 18/20] dwarf-reader/writer: consider aliases when dealing with suppressions Matthias Maennich
2021-03-17 15:44     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 19/20] abg-writer.cc: fix write_elf_symbol_reference loop Matthias Maennich
2021-03-17 16:11     ` Dodji Seketeli
2021-01-27 12:58   ` [PATCH 20/20] symtab: Add support for MODVERSIONS (CRC checksums) Matthias Maennich
2021-03-17 17:13     ` Dodji Seketeli
2021-03-17 23:29       ` Giuliano Procida
2021-03-18 22:10         ` Matthias Maennich
2021-03-19 16:55           ` Dodji Seketeli
2021-03-19 18:15     ` Dodji Seketeli
2021-03-29 13:19   ` [GIT PULL] Refactor (k)symtab reader Matthias Maennich
2021-04-02 14:28     ` Dodji Seketeli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210127125853.886677-14-maennich@google.com \
    --to=maennich@google.com \
    --cc=dodji@seketeli.org \
    --cc=gprocida@google.com \
    --cc=kernel-team@android.com \
    --cc=libabigail@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).