]> sourceware.org Git - libabigail.git/commitdiff
ctf-reader: CTF debug info for some symbols is not found
authorGuillermo E. Martinez <guillermo.e.martinez@oracle.com>
Sat, 7 May 2022 01:50:25 +0000 (20:50 -0500)
committerDodji Seketeli <dodji@redhat.com>
Fri, 13 May 2022 12:34:47 +0000 (14:34 +0200)
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>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-ctf-reader.cc
src/abg-elf-helpers.cc
src/abg-elf-helpers.h

index a6a0b74e0a2af78ced34ced579205c6f78e38387..89dea276fcc29750835b6da5fb27c65f45b1485f 100644 (file)
@@ -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;
@@ -253,9 +251,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)
   {
@@ -284,7 +286,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;
@@ -908,8 +909,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);
@@ -1226,16 +1230,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,
@@ -1275,7 +1279,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());
         }
     }
@@ -1366,10 +1370,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.  */
@@ -1382,10 +1389,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;
index 787a05ffea5e8dc322d2f332368d01d475432f36..a1fd4e6c3269f4ac4d099af4a67d2b4b83a2b193 100644 (file)
@@ -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.
index afaff24a86c271720eb7be2936f20d8590d5d75a..ee4068638056d21820d568fec58fffea9ce605ac 100644 (file)
@@ -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);
 
This page took 0.039132 seconds and 5 git commands to generate.