[2/4] Factorize elf-reader::{variable,function}_symbol_is_exported into symtab

Message ID 87le6k3g23.fsf@redhat.com
State New
Headers
Series Support undefined interfaces to fix abicompt's weak mode |

Commit Message

Dodji Seketeli March 14, 2024, 4:59 p.m. UTC
  Hello,

Move the code of elf-reader::{variable,function}_symbol_is_exported into
symtab::{variable,function}_symbol_is_exported (where it belongs) and
make the former use the later.

	* src/abg-elf-reader.cc (reader::function_symbol_is_exported): Use
	the new symtab::function_symbol_is_exported.
	(reader::variable_symbol_is_exported): Use the new
	symtab::variable_symbol_is_exported.
	* src/abg-symtab-reader.cc
	(symtab::{function,variable}_symbol_is_exported): Factorize
	elf::reader::{function,variable}_symbol_is_exported into this.
	* src/abg-symtab-reader.h
	(symtab::{function,variable}_symbol_is_exported): Declare new
	member functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 src/abg-elf-reader.cc    | 59 ++++++++++++---------------
 src/abg-symtab-reader.cc | 87 ++++++++++++++++++++++++++++++++++++++++
 src/abg-symtab-reader.h  | 12 ++++++
 3 files changed, 124 insertions(+), 34 deletions(-)
  

Patch

diff --git a/src/abg-elf-reader.cc b/src/abg-elf-reader.cc
index afb038ff..14f8ce6a 100644
--- a/src/abg-elf-reader.cc
+++ b/src/abg-elf-reader.cc
@@ -788,13 +788,12 @@  reader::symtab() const
 elf_symbol_sptr
 reader::function_symbol_is_exported(GElf_Addr symbol_address) const
 {
-  elf_symbol_sptr symbol = symtab()->lookup_symbol(symbol_address);
+
+  elf_symbol_sptr symbol =
+    symtab()->function_symbol_is_exported(symbol_address);
   if (!symbol)
     return symbol;
 
-  if (!symbol->is_function() || !symbol->is_public())
-    return elf_symbol_sptr();
-
   address_set_sptr set;
   bool looking_at_linux_kernel_binary =
     load_in_linux_kernel_mode() && elf_helpers::is_linux_kernel(elf_handle());
@@ -820,13 +819,11 @@  reader::function_symbol_is_exported(GElf_Addr symbol_address) const
 elf_symbol_sptr
 reader::variable_symbol_is_exported(GElf_Addr symbol_address) const
 {
-  elf_symbol_sptr symbol = symtab()->lookup_symbol(symbol_address);
+  elf_symbol_sptr symbol =
+    symtab()->variable_symbol_is_exported(symbol_address);
   if (!symbol)
     return symbol;
 
-  if (!symbol->is_variable() || !symbol->is_public())
-    return elf_symbol_sptr();
-
   address_set_sptr set;
   bool looking_at_linux_kernel_binary =
     load_in_linux_kernel_mode() && elf_helpers::is_linux_kernel(elf_handle());
@@ -849,23 +846,20 @@  reader::variable_symbol_is_exported(GElf_Addr symbol_address) const
 elf_symbol_sptr
 reader::function_symbol_is_exported(const string& name) const
 {
-  const elf_symbols& syms = symtab()->lookup_symbol(name);
-  for (auto s : syms)
+  const elf_symbol_sptr s = symtab()->function_symbol_is_exported(name);
+  if (s && s->is_function() && s->is_public())
     {
-      if (s->is_function() && s->is_public())
-	{
-	  bool looking_at_linux_kernel_binary =
-	    (load_in_linux_kernel_mode()
-	     && elf_helpers::is_linux_kernel(elf_handle()));
+      bool looking_at_linux_kernel_binary =
+	(load_in_linux_kernel_mode()
+	 && elf_helpers::is_linux_kernel(elf_handle()));
 
-	  if (looking_at_linux_kernel_binary)
-	    {
-	      if (s->is_in_ksymtab())
-		return s;
-	    }
-	  else
+      if (looking_at_linux_kernel_binary)
+	{
+	  if (s->is_in_ksymtab())
 	    return s;
 	}
+      else
+	return s;
     }
   return elf_symbol_sptr();
 }
@@ -879,23 +873,20 @@  reader::function_symbol_is_exported(const string& name) const
 elf_symbol_sptr
 reader::variable_symbol_is_exported(const string& name) const
 {
-  const elf_symbols& syms = symtab()->lookup_symbol(name);
-  for (auto s : syms)
+  const elf_symbol_sptr s  = symtab()->variable_symbol_is_exported(name);
+  if (s->is_variable() && s->is_public())
     {
-      if (s->is_variable() && s->is_public())
-	{
-	  bool looking_at_linux_kernel_binary =
-	    (load_in_linux_kernel_mode()
-	     && elf_helpers::is_linux_kernel(elf_handle()));
+      bool looking_at_linux_kernel_binary =
+	(load_in_linux_kernel_mode()
+	 && elf_helpers::is_linux_kernel(elf_handle()));
 
-	  if (looking_at_linux_kernel_binary)
-	    {
-	      if (s->is_in_ksymtab())
-		return s;
-	    }
-	  else
+      if (looking_at_linux_kernel_binary)
+	{
+	  if (s->is_in_ksymtab())
 	    return s;
 	}
+      else
+	return s;
     }
   return elf_symbol_sptr();
 }
diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc
index 2eebc282..51177369 100644
--- a/src/abg-symtab-reader.cc
+++ b/src/abg-symtab-reader.cc
@@ -166,6 +166,93 @@  symtab::lookup_undefined_variable_symbol(const std::string& sym_name)
   return result;
 }
 
+/// Test if a given function symbol has been exported.
+///
+/// Note that this doesn't test if the symbol is defined or not, but
+/// assumes the symbol is defined.
+///
+/// @param name the name of the symbol we are looking for.
+///
+/// @return the elf symbol if found, or nil otherwise.
+elf_symbol_sptr
+symtab::function_symbol_is_exported(const string& name)
+{
+  const elf_symbols& syms = lookup_symbol(name);
+  for (auto s : syms)
+    if (s->is_function() && s->is_public())
+      return s;
+
+  return elf_symbol_sptr();
+}
+
+/// Test if a given function symbol has been exported.
+///
+/// Note that this doesn't test if the symbol is defined or not, but
+/// assumes the symbol is defined.
+///
+/// @param symbol_address the address of the symbol we are looking
+/// for.  Note that this address must be a relative offset from the
+/// beginning of the .text section, just like the kind of addresses
+/// that are present in the .symtab section.
+///
+/// @return the elf symbol if found, or nil otherwise.
+elf_symbol_sptr
+symtab::function_symbol_is_exported(const GElf_Addr symbol_address)
+{
+  elf_symbol_sptr symbol = lookup_symbol(symbol_address);
+  if (!symbol)
+    return symbol;
+
+  if (!symbol->is_function() || !symbol->is_public())
+    return elf_symbol_sptr();
+
+  return symbol;
+}
+
+/// Test if a given variable symbol has been exported.
+///
+/// Note that this assumes the symbol is exported but doesn't test for
+/// it.
+///
+/// @param name the name of the symbol we are looking
+/// for.
+///
+/// @return the elf symbol if found, or nil otherwise.
+elf_symbol_sptr
+symtab::variable_symbol_is_exported(const string& name)
+{
+  const elf_symbols& syms = lookup_symbol(name);
+  for (auto s : syms)
+    if (s->is_variable() && s->is_public())
+      return s;
+
+  return elf_symbol_sptr();
+}
+
+/// Test if a given variable symbol has been exported.
+///
+/// Note that this assumes the symbol is exported but doesn't test for
+/// it.
+///
+/// @param symbol_address the address of the symbol we are looking
+/// for.  Note that this address must be a relative offset from the
+/// beginning of the .text section, just like the kind of addresses
+/// that are present in the .symtab section.
+///
+/// @return the elf symbol if found, or nil otherwise.
+elf_symbol_sptr
+symtab::variable_symbol_is_exported(const GElf_Addr symbol_address)
+{
+  elf_symbol_sptr symbol = lookup_symbol(symbol_address);
+  if (!symbol)
+    return symbol;
+
+  if (!symbol->is_variable() || !symbol->is_public())
+    return elf_symbol_sptr();
+
+  return symbol;
+}
+
 /// Test if a name is a the name of an undefined function symbol.
 ///
 /// @param sym_name the symbol name to consider.
diff --git a/src/abg-symtab-reader.h b/src/abg-symtab-reader.h
index cc284453..43b40b79 100644
--- a/src/abg-symtab-reader.h
+++ b/src/abg-symtab-reader.h
@@ -248,6 +248,18 @@  public:
   const elf_symbol_sptr
   lookup_undefined_variable_symbol(const std::string& name);
 
+  elf_symbol_sptr
+  function_symbol_is_exported(const string&);
+
+  elf_symbol_sptr
+  function_symbol_is_exported(const GElf_Addr symbol_address);
+
+  elf_symbol_sptr
+  variable_symbol_is_exported(const string&);
+
+  elf_symbol_sptr
+  variable_symbol_is_exported(const GElf_Addr symbol_address);
+
   bool
   function_symbol_is_undefined(const string&);