public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] ctf-reader: CTF debug info for some symbols is not found
@ 2022-05-07  1:50 Guillermo E. Martinez
  0 siblings, 0 replies; only message in thread
From: Guillermo E. Martinez @ 2022-05-07  1:50 UTC (permalink / raw)
  To: libabigail

Hello libabigail team,

This patch fix missing symbols in the CTF reader backend. It depends of:

   * https://sourceware.org/pipermail/libabigail/2022q2/004340.html
   * https://sourceware.org/pipermail/libabigail/2022q2/004343.html


Please let me know your comments, I'll really appreciate them.

Kind regards,
Guillermo


Running `abidw --ctf' tool for some executable ELF files, seems that ctf
reader is unable to get debug information for some symbols so, they will
not be neither the corpus nor in abixml file. This is happening because
internally the reader uses `ctf_arc_bufopen' expecting as argument the
sections: symbol table (.dynsym) and string table (.dynstr) for ELF
types: ET_{EXEC,DYN}, currently those sections are read by `elf_helpers'
but it uses .symtab  when it is present and `symtab_shdr->sh_link' to
get .strtab, instead.

	* src/abg-ctf-reader.cc (read_context::is_elf_exec): Remove
	data member.
	(ctf_reader::process_ctf_qualified_type): Add condition to avoid
	use qualifier in functions.
	(ctf_reader::process_ctf_archive): Use `ctf_lookup_by_symbol_name'
	to find debug information when `ctf_lookup_variable' was not
	lucky iff `corpus::CTF_ORIGIN'.
	(ctf_reader::slurp_elf_info): Use `elf_helpers::find_section_by_name'
	to read .dynsym and .dynstr when {EXEC,DYN}.
	* src/abg-elf-helpers.h (elf_helpers::find_section_by_name): Add new
	declaration.
	* src/abg-elf-helpers.cc (elf_helpers::find_section_by_name): Add new
	definition.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
---
 src/abg-ctf-reader.cc  | 53 ++++++++++++++++++++++++++++--------------
 src/abg-elf-helpers.cc | 29 +++++++++++++++++++++++
 src/abg-elf-helpers.h  |  3 +++
 3 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index 5cb6fe19..3f8c3d03 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -70,8 +70,6 @@ public:
   Elf *elf_handler;
   int elf_fd;
 
-  /// set when ELF is ET_EXEC
-  bool is_elf_exec;
 
   /// The symtab read from the ELF file.
   symtab_reader::symtab_sptr symtab;
@@ -240,9 +238,13 @@ public:
 
   /// Constructor.
   ///
-  /// ctfa data member can be used per courpus group.
-  ///
   /// @param elf_path the path to the ELF file.
+  ///
+  /// @param environment the environment used by the current context.
+  /// This environment contains resources needed by the reader and by
+  /// the types and declarations that are to be created later.  Note
+  /// that ABI artifacts that are to be compared all need to be
+  /// created within the same environment.
   read_context(const string& elf_path, ir::environment *env) :
     ctfa(NULL)
   {
@@ -271,7 +273,6 @@ public:
     ir_env = env;
     elf_handler = NULL;
     elf_fd = -1;
-    is_elf_exec = false;
     symtab.reset();
     cur_corpus_group_.reset();
     exported_decls_builder_ = 0;
@@ -895,8 +896,11 @@ process_ctf_qualified_type(read_context *ctxt,
   else
     ABG_ASSERT_NOT_REACHED;
 
-  result.reset(new qualified_type_def(utype, qualifiers, location()));
+  // qualifiers are not be use in functions
+  if (is_function_type(utype))
+    return result;
 
+  result.reset(new qualified_type_def(utype, qualifiers, location()));
   if (result)
     {
       decl_base_sptr qualified_type_decl = get_type_declaration(result);
@@ -1213,16 +1217,16 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
       std::string sym_name = symbol->get_name();
       ctf_id_t ctf_sym_type;
 
-      if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
-          || ctxt->is_elf_exec)
-        ctf_sym_type= ctf_lookup_variable (ctf_dict, sym_name.c_str());
-      else
+      ctf_sym_type = ctf_lookup_variable(ctf_dict, sym_name.c_str());
+      if (ctf_sym_type == (ctf_id_t) -1
+          && !(corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN))
+        // lookup in function objects
         ctf_sym_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str());
 
       if (ctf_sym_type == (ctf_id_t) -1)
         continue;
 
-      if (ctf_type_kind (ctf_dict, ctf_sym_type) != CTF_K_FUNCTION)
+      if (ctf_type_kind(ctf_dict, ctf_sym_type) != CTF_K_FUNCTION)
         {
           const char *var_name = sym_name.c_str();
           type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit,
@@ -1262,7 +1266,7 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
           func_declaration->set_symbol(symbol);
           add_decl_to_scope(func_declaration,
                             ir_translation_unit->get_global_scope());
-	  func_declaration->set_is_in_public_symbol_table(true);
+          func_declaration->set_is_in_public_symbol_table(true);
           ctxt->maybe_add_fn_to_exported_decls(func_declaration.get());
         }
     }
@@ -1353,10 +1357,13 @@ fill_ctf_section(Elf_Scn *elf_section, ctf_sect_t *ctf_section)
 static int
 slurp_elf_info(read_context *ctxt, corpus_sptr corp)
 {
-  /* Set the ELF architecture.  */
+  Elf_Scn *symtab_scn;
+  Elf_Scn *ctf_scn;
+  Elf_Scn *strtab_scn;
   GElf_Ehdr eh_mem;
   GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem);
-  ctxt->is_elf_exec = (ehdr->e_type == ET_EXEC);
+
+  /* Set the ELF architecture.  */
   corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine));
 
   /* Read the symtab from the ELF file and set it in the corpus.  */
@@ -1369,10 +1376,20 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp)
     return 1;
 
   /* Get the raw ELF section contents for libctf.  */
-  Elf_Scn *ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS);
-  Elf_Scn *symtab_scn = elf_helpers::find_symbol_table_section(ctxt->elf_handler);
-  Elf_Scn *strtab_scn = elf_helpers::find_strtab_for_symtab_section(ctxt->elf_handler,
-                                                                    symtab_scn);
+  ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS);
+
+  // ET_{EXEC,DYN} needs .dyn{sym,str} in ctf_arc_bufopen
+  const char *symtab_name = ".dynsym";
+  const char *strtab_name = ".dynstr";
+
+  if (ehdr->e_type == ET_REL)
+    {
+      symtab_name = ".symtab";
+      strtab_name = ".strtab";
+    }
+
+  symtab_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, symtab_name);
+  strtab_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, strtab_name);
 
   if (ctf_scn == NULL || symtab_scn == NULL || strtab_scn == NULL)
     return 0;
diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc
index 787a05ff..a1fd4e6c 100644
--- a/src/abg-elf-helpers.cc
+++ b/src/abg-elf-helpers.cc
@@ -296,6 +296,35 @@ e_machine_to_string(GElf_Half e_machine)
     }
 }
 
+/// Find and return a section by its name.
+///
+/// @param elf_handle the elf handle to use.
+///
+/// @return the section found, nor nil if none was found.
+Elf_Scn*
+find_section_by_name(Elf* elf_handle, const std::string& name)
+{
+  size_t section_header_string_index = 0;
+  if (elf_getshdrstrndx (elf_handle, &section_header_string_index) < 0)
+    return 0;
+
+  Elf_Scn* section = 0;
+  GElf_Shdr header_mem, *header;
+  while ((section = elf_nextscn(elf_handle, section)) != 0)
+    {
+      header = gelf_getshdr(section, &header_mem);
+      if (header == NULL)
+        continue;
+
+      const char* section_name =
+	elf_strptr(elf_handle, section_header_string_index, header->sh_name);
+      if (section_name && name == section_name)
+	return section;
+    }
+
+  return 0;
+}
+
 /// Find and return a section by its name and its type.
 ///
 /// @param elf_handle the elf handle to use.
diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h
index afaff24a..ee406863 100644
--- a/src/abg-elf-helpers.h
+++ b/src/abg-elf-helpers.h
@@ -49,6 +49,9 @@ find_section(Elf*		elf_handle,
 	     const std::string& name,
 	     Elf64_Word		section_type);
 
+Elf_Scn*
+find_section_by_name(Elf* elf_handle, const std::string& name);
+
 Elf_Scn*
 find_section(Elf* elf_handle, Elf64_Word section_type);
 

base-commit: c96463e1ad974b7c4561886d7a3aa8a3c9a35607
prerequisite-patch-id: 781b026536589341e1e4378d9529fe258633bb53
prerequisite-patch-id: e6191c510bc90e225bd0858d333e2e01b6e52a62
-- 
2.35.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-07  1:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-07  1:50 [PATCH] ctf-reader: CTF debug info for some symbols is not found Guillermo E. Martinez

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).