public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] CTF as a fallback when no DWARF debug info is present
@ 2022-10-01  0:15 Guillermo E. Martinez
  2022-10-04  9:04 ` Dodji Seketeli
  2022-11-15 20:13 ` [PATCHv2] ELF based front-end readers fallback feature Guillermo E. Martinez
  0 siblings, 2 replies; 17+ messages in thread
From: Guillermo E. Martinez @ 2022-10-01  0:15 UTC (permalink / raw)
  To: libabigail; +Cc: Guillermo E. Martinez

Hello,

This patch implements the CTF fallback behaviour in libabigail tools
when DWARF debug info is not present.

Please let me know your thoughts, they will be really appreciated.

Thanks in advanced,
guillermo
--

By default, `abidw', `abidiff', `abipkgdiff' and `kmidiff' tools use
debug information in `DWARF` format, if present, otherwise now
automatically the tools try to extract and build the binaries IR using
debug information in `CTF` format without use of `--ctf' option, if
present, finally, if neither is found, they use only `ELF` symbols to
extract, build, compare and report which of them were added or removed.

In case of neither DWARF nor CTF debug information is present
(`STATUS_DEBUG_INFO_NOT_FOUND') and `--ctf' option was not passed in
the command line, those tools use the symbol object build by DWARF
reader (default) to completed  theirs task.

Tools don't allow comparing corpora built with between different debug
information i.e DWARF vs CTF, the first corpus built dictate the
expected debug information in the second one.

This work for libraries and Linux kernel.  The `--ctf' option is
preserved to explicitly indicate to those tools that we want to use
CTF support.

	* doc/manuals/abidiff.rst: Adjust usage tool information
	to indicates fallback for CTF debug info when DWARF info
	is not present.
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* doc/manuals/kmidiff.rst: Likewise.
	* src/abg-ctf-reader.cc (slurp_elf_info): Report status
	when debug information is not present.
	(read_corpus): Add code to locate `vmlinux.ctfa' just when
	`main corpus' is being processed.
	* src/abg-tools-utils.cc (maybe_load_vmlinux_dwarf_corpus):
	Replace by a reference `origin' argument to notify whether
	CTF reader needs to be executed.
	* tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt: Adjust
	test case.
	* tests/test-diff-pkg.cc (in_out_specs): Add `--ctf' option
	in test case.
	* tools/abidiff.cc (main): Add `origin' depending of command
	line argument by default it is `corpus::DWARF_ORIGIN'. Add
	`dwarf_corpus' to be used as default corpus (containing ELF
	symbols), when DWARF nor CTF debug information was found.
	* tools/abidw.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
---
 doc/manuals/abidiff.rst                       |  15 +--
 doc/manuals/abidw.rst                         |  15 ++-
 doc/manuals/abipkgdiff.rst                    |  13 +-
 doc/manuals/kmidiff.rst                       |   9 +-
 src/abg-ctf-reader.cc                         |  33 +++--
 src/abg-tools-utils.cc                        |  22 +++-
 .../test-diff-pkg-ctf/dirpkg-3-report-2.txt   |  16 +++
 tests/test-diff-pkg.cc                        |   2 +-
 tools/abidiff.cc                              |  82 ++++++++-----
 tools/abidw.cc                                |  54 +++++---
 tools/abipkgdiff.cc                           | 116 +++++++++++-------
 11 files changed, 257 insertions(+), 120 deletions(-)

diff --git a/doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst
index 0c711d9e..caeceded 100644
--- a/doc/manuals/abidiff.rst
+++ b/doc/manuals/abidiff.rst
@@ -12,11 +12,12 @@ This tool can also compare the textual representations of the ABI of
 two ELF binaries (as emitted by ``abidw``) or an ELF binary against a
 textual representation of another ELF binary.
 
-For a comprehensive ABI change report that includes changes about
-function and variable sub-types, the two input shared libraries must
-be accompanied with their debug information in `DWARF`_ format.
-Otherwise, only `ELF`_ symbols that were added or removed are
-reported.
+For a comprehensive ABI change report between two input shared
+libraries that includes changes about function and variable sub-types,
+``abidiff`` uses by default, debug information in `DWARF`_ format, if
+present, otherwise it compares interfaces using debug information in
+`CTF`_ format, if present, finally, if neither is found, it uses only
+`ELF`_ symbols to report which of them were added or removed.
 
 .. include:: tools-use-libabigail.txt
 
@@ -558,7 +559,7 @@ Options
 
   * ``--ctf``
 
-    When comparing binaries, extract ABI information from CTF debug
+    When comparing binaries, extract ABI information from `CTF`_ debug
     information, if present.
 
   * ``--stats``
@@ -785,4 +786,4 @@ Usage examples
 
 .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
 .. _DWARF: http://www.dwarfstd.org
-
+.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst
index a3055c7e..20948805 100644
--- a/doc/manuals/abidw.rst
+++ b/doc/manuals/abidw.rst
@@ -8,8 +8,7 @@ representation of its ABI to standard output.  The emitted
 representation format, named ``ABIXML``, includes all the globally
 defined functions and variables, along with a complete representation
 of their types.  It also includes a representation of the globally
-defined ELF symbols of the file.  The input shared library must
-contain associated debug information in `DWARF`_ format.
+defined ELF symbols of the file.
 
 When given the ``--linux-tree`` option, this program can also handle a
 `Linux kernel`_ tree.  That is, a directory tree that contains both
@@ -19,8 +18,13 @@ interface between the kernel and its module, to standard output.  In
 this case, we don't call it an ABI, but a KMI (Kernel Module
 Interface).  The emitted KMI includes all the globally defined
 functions and variables, along with a complete representation of their
-types.  The input binaries must contain associated debug information
-in `DWARF`_ format.
+types.
+
+To generate either ABI or KMI representation, by default ``abidw``
+uses debug information in `DWARF`_ format, if present, otherwise it
+looks for debug information in `CTF`_ format, if present, finally, if
+neither is found, it uses only `ELF`_ symbols to report which of them
+were added or removed.
 
 .. include:: tools-use-libabigail.txt
 
@@ -326,7 +330,7 @@ Options
 
   * ``--ctf``
 
-    Extract ABI information from CTF debug information, if present in
+    Extract ABI information from `CTF`_ debug information, if present in
     the given object.
 
   *  ``--annotate``
@@ -365,3 +369,4 @@ standard `here
 .. _DWARF: http://www.dwarfstd.org
 .. _GNU: http://www.gnu.org
 .. _Linux Kernel: https://kernel.org/
+.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
diff --git a/doc/manuals/abipkgdiff.rst b/doc/manuals/abipkgdiff.rst
index 9114775a..771bb034 100644
--- a/doc/manuals/abipkgdiff.rst
+++ b/doc/manuals/abipkgdiff.rst
@@ -13,12 +13,18 @@ binaries.
 For a comprehensive ABI change report that includes changes about
 function and variable sub-types, the two input packages must be
 accompanied with their debug information packages that contain debug
-information either in `DWARF`_ or in `CTF` formats.  Please note
+information either in `DWARF`_ or in `CTF`_ formats.  Please note
 however that some packages contain binaries that embed the debug
 information directly in a section of said binaries.  In those cases,
 obviously, no separate debug information package is needed as the tool
 will find the debug information inside the binaries.
 
+By default, ``abipkgdiff`` uses debug information in `DWARF`_ format,
+if present, otherwise it compares binaries interfaces using debug
+information in `CTF`_ format, if present, finally, if neither is
+found, it uses only `ELF`_ symbols to report which of them were added
+or removed.
+
 .. include:: tools-use-libabigail.txt
 
 .. _abipkgdiff_invocation_label:
@@ -525,8 +531,8 @@ Options
 
   * ``--ctf``
 
-     This is used to compare packages with CTF debug information, if
-     present.
+     This is used to compare packages with `CTF`_ debug information,
+     if present.
 
 .. _abipkgdiff_return_value_label:
 
@@ -546,4 +552,5 @@ In the later case, the value of the exit code is the same as for the
 .. _Deb: https://en.wikipedia.org/wiki/Deb_%28file_format%29
 .. _tar: https://en.wikipedia.org/wiki/Tar_%28computing%29
 .. _DWARF: http://www.dwarfstd.org
+.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
 .. _Development Package: https://fedoraproject.org/wiki/Packaging:Guidelines?rd=Packaging/Guidelines#Devel_Packages
diff --git a/doc/manuals/kmidiff.rst b/doc/manuals/kmidiff.rst
index 53010189..a27d2456 100644
--- a/doc/manuals/kmidiff.rst
+++ b/doc/manuals/kmidiff.rst
@@ -74,6 +74,11 @@ functions and variables) between the Kernel and its modules.  In
 practice, though, some users might want to compare a subset of the
 those interfaces.
 
+By default, ``kmidiff`` uses debug information in `DWARF`_ format,
+if present, otherwise it compares interfaces using debug information
+in `CTF`_ format, if present, finally, if neither is found, it uses
+only `ELF`_ symbols to report which were added or removed.
+
 Users can then define a "white list" of the interfaces to compare.
 Such a white list is a just a file in the "INI" format that looks
 like: ::
@@ -174,7 +179,7 @@ Options
 
   * ``--ctf``
 
-    Extract ABI information from CTF debug information, if present in
+    Extract ABI information from `CTF`_ debug information, if present in
     the Kernel and Modules.
 
   * ``--impacted-interfaces | -i``
@@ -242,3 +247,5 @@ Options
 .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
 .. _ksymtab: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
 .. _Linux Kernel: https://kernel.org
+.. _DWARF: http://www.dwarfstd.org
+.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index 9148a646..b3cde365 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -45,6 +45,7 @@ namespace ctf_reader
 using std::dynamic_pointer_cast;
 using abigail::tools_utils::dir_name;
 using abigail::tools_utils::file_exists;
+using abigail::tools_utils::base_name;
 
 class read_context
 {
@@ -1545,7 +1546,12 @@ slurp_elf_info(read_context *ctxt,
   corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine));
 
   find_alt_debuginfo(ctxt, &ctf_dbg_scn);
-  ABG_ASSERT(ctxt->symtab);
+  if (!ctxt->symtab)
+    {
+      status |= elf_reader::STATUS_NO_SYMBOLS_FOUND;
+      return;
+    }
+
   corp->set_symtab(ctxt->symtab);
 
   if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
@@ -1564,7 +1570,8 @@ slurp_elf_info(read_context *ctxt,
         ctf_scn = ctf_dbg_scn;
       else
         {
-          status |= elf_reader::STATUS_DEBUG_INFO_NOT_FOUND;
+          status |= (elf_reader::STATUS_OK |
+                     elf_reader::STATUS_DEBUG_INFO_NOT_FOUND);
           return;
         }
     }
@@ -1676,15 +1683,15 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
     origin |= corpus::LINUX_KERNEL_BINARY_ORIGIN;
   corp->set_origin(origin);
 
-  if (ctxt->cur_corpus_group_)
-    ctxt->cur_corpus_group_->add_corpus(ctxt->cur_corpus_);
-
   slurp_elf_info(ctxt, corp, status);
-  if (!is_linux_kernel
-      && ((status & elf_reader::STATUS_DEBUG_INFO_NOT_FOUND) |
-          (status & elf_reader::STATUS_NO_SYMBOLS_FOUND)))
+  if ((status & elf_reader::STATUS_NO_SYMBOLS_FOUND) ||
+      (!is_linux_kernel &&
+       (status & elf_reader::STATUS_DEBUG_INFO_NOT_FOUND)))
       return corp;
 
+  if (ctxt->cur_corpus_group_)
+    ctxt->cur_corpus_group_->add_corpus(ctxt->cur_corpus_);
+
   // Set the set of exported declaration that are defined.
   ctxt->exported_decls_builder
    (ctxt->cur_corpus_->get_exported_decls_builder().get());
@@ -1695,9 +1702,13 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
     {
       if (ctxt->ctfa == NULL)
         {
-          std::string ctfa_filename;
-          if (find_ctfa_file(ctxt, ctfa_filename))
-            ctxt->ctfa = ctf_arc_open(ctfa_filename.c_str(), &errp);
+          std::string filename;
+          base_name(ctxt->filename, filename);
+
+          // locate vmlinux.ctfa only when reader is processing
+          // vmlinux file, i.e the main corpus in the group.
+          if (filename == "vmlinux" && find_ctfa_file(ctxt, filename))
+            ctxt->ctfa = ctf_arc_open(filename.c_str(), &errp);
         }
     }
   else
diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc
index fe9ebc72..7d00f726 100644
--- a/src/abg-tools-utils.cc
+++ b/src/abg-tools-utils.cc
@@ -2493,6 +2493,11 @@ get_binary_paths_from_kernel_dist(const string&	dist_root,
 /// made of vmlinux kernel file and the linux kernel modules found
 /// under @p root directory and under its sub-directories, recursively.
 ///
+/// If the vmlinux file doens't have DWARF info, it looks for
+/// vmlinux.ctfa, if it's present, it assumes that kernel was build
+/// with CTF support, then it updates @ref origin, given chance to
+/// CTF reader to build the IR for kernel build directory.
+///
 /// @param origin the debug type information in vmlinux kernel and
 /// the linux kernel modules to be used to build the corpora @p group.
 ///
@@ -2526,7 +2531,7 @@ get_binary_paths_from_kernel_dist(const string&	dist_root,
 ///
 /// @param env the environment to create the corpus_group in.
 static void
-maybe_load_vmlinux_dwarf_corpus(corpus::origin      origin,
+maybe_load_vmlinux_dwarf_corpus(corpus::origin      &origin,
                                 corpus_group_sptr&  group,
                                 const string&       vmlinux,
                                 vector<string>&     modules,
@@ -2578,6 +2583,21 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin      origin,
      << " reading DONE:"
      << t << "\n";
 
+  if (status & elf_reader::STATUS_DEBUG_INFO_NOT_FOUND)
+    {
+      // vmlinux doesn't have DWARF debug info, so it might contain
+      // CTF debug info, this means vmlinux.ctfa is under kernel
+      // build directory.
+      string ctfa_file = root + "/vmlinux.ctfa";
+      if (file_exists(ctfa_file))
+        {
+          // OK. Likely CTF could build a better IR, then let's
+          // notify the caller to try with CTF reader.
+          origin = corpus::CTF_ORIGIN;
+          return;
+        }
+    }
+
   if (group->is_empty())
     return;
 
diff --git a/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt b/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt
index e69de29b..4938d221 100644
--- a/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt
+++ b/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt
@@ -0,0 +1,16 @@
+================ changes of 'libobj-v0.so'===============
+  Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions
+  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+  1 function with some indirect sub-type change:
+
+    [C] 'function void foo(S1*)' has some indirect sub-type changes:
+      parameter 1 of type 'S1*' has sub-type changes:
+        in pointed to type 'struct S1':
+          type size changed from 0 to 32 (in bits)
+          type alignment changed from 0 to 32
+          1 data member insertion:
+            'int mem2', at offset 0 (in bits)
+
+================ end of changes of 'libobj-v0.so'===============
+
diff --git a/tests/test-diff-pkg.cc b/tests/test-diff-pkg.cc
index e128ff63..8e510ca2 100644
--- a/tests/test-diff-pkg.cc
+++ b/tests/test-diff-pkg.cc
@@ -855,7 +855,7 @@ static InOutSpec in_out_specs[] =
   { // Just like the previous tests, but loc info is emitted.
     "data/test-diff-pkg-ctf/dirpkg-3-dir1",
     "data/test-diff-pkg-ctf/dirpkg-3-dir2",
-    "--no-default-suppression --no-abignore",
+    "--ctf --no-default-suppression --no-abignore",
     "data/test-diff-pkg-ctf/dirpkg-3.suppr",
     "",
     "",
diff --git a/tools/abidiff.cc b/tools/abidiff.cc
index e0bb35ac..815c68df 100644
--- a/tools/abidiff.cc
+++ b/tools/abidiff.cc
@@ -1118,6 +1118,13 @@ main(int argc, char* argv[])
       return 0;
     }
 
+  corpus::origin first_input_origin;
+  corpus::origin origin =
+#ifdef WITH_CTF
+    opts.use_ctf ? corpus::CTF_ORIGIN :
+#endif
+    corpus::DWARF_ORIGIN;
+
   prepare_di_root_paths(opts);
 
   if (!maybe_check_suppression_files(opts))
@@ -1150,7 +1157,7 @@ main(int argc, char* argv[])
       abigail::elf_reader::status c1_status =
 	abigail::elf_reader::STATUS_OK,
 	c2_status = abigail::elf_reader::STATUS_OK;
-      corpus_sptr c1, c2;
+      corpus_sptr c1, c2, dwarf_corpus;
       corpus_group_sptr g1, g2;
       bool files_suppressed = false;
 
@@ -1180,20 +1187,9 @@ main(int argc, char* argv[])
 	case abigail::tools_utils::FILE_TYPE_ELF: // fall through
 	case abigail::tools_utils::FILE_TYPE_AR:
 	  {
-#ifdef WITH_CTF
-            if (opts.use_ctf)
-              {
-                abigail::ctf_reader::read_context_sptr ctxt
-                  = abigail::ctf_reader::create_read_context(opts.file1,
-                                                             opts.prepared_di_root_paths1,
-                                                             env.get());
-                ABG_ASSERT(ctxt);
-                c1 = abigail::ctf_reader::read_corpus(ctxt.get(),
-                                                      c1_status);
-              }
-            else
-#endif
+            if (origin & corpus::DWARF_ORIGIN)
               {
+                first_input_origin = corpus::DWARF_ORIGIN;
                 abigail::dwarf_reader::read_context_sptr ctxt =
                   abigail::dwarf_reader::create_read_context
                   (opts.file1, opts.prepared_di_root_paths1,
@@ -1205,6 +1201,7 @@ main(int argc, char* argv[])
                 set_suppressions(*ctxt, opts);
                 abigail::dwarf_reader::set_do_log(*ctxt, opts.do_log);
                 c1 = abigail::dwarf_reader::read_corpus_from_elf(*ctxt, c1_status);
+                dwarf_corpus = c1;
                 if (!c1
                     || (opts.fail_no_debug_info
                         && (c1_status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
@@ -1212,7 +1209,31 @@ main(int argc, char* argv[])
                   return handle_error(c1_status, ctxt.get(),
                                       argv[0], opts);
               }
-	  }
+#ifdef WITH_CTF
+            if (((c1_status & STATUS_OK) &&
+                 (c1_status & STATUS_DEBUG_INFO_NOT_FOUND)) ||
+                (origin & corpus::CTF_ORIGIN))
+              {
+                first_input_origin = corpus::CTF_ORIGIN;
+                abigail::ctf_reader::read_context_sptr ctxt
+                  = abigail::ctf_reader::create_read_context(opts.file1,
+                                                             opts.prepared_di_root_paths1,
+                                                             env.get());
+                ABG_ASSERT(ctxt);
+                c1 = abigail::ctf_reader::read_corpus(ctxt.get(),
+                                                      c1_status);
+                // If CTF was not explicitly selected in the command line and
+                // there is no CTF information, then compare DWARF corpora
+                // by default only with symbols information.
+                if ((origin & corpus::DWARF_ORIGIN) &&
+                    (c1_status & abigail::elf_reader::STATUS_DEBUG_INFO_NOT_FOUND))
+                  {
+                    first_input_origin = corpus::DWARF_ORIGIN;
+                    c1 = dwarf_corpus;
+                  }
+              }
+#endif
+          }
 	  break;
 	case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
 	  {
@@ -1264,19 +1285,7 @@ main(int argc, char* argv[])
 	case abigail::tools_utils::FILE_TYPE_ELF: // Fall through
 	case abigail::tools_utils::FILE_TYPE_AR:
 	  {
-#ifdef WITH_CTF
-            if (opts.use_ctf)
-              {
-                abigail::ctf_reader::read_context_sptr ctxt
-                  = abigail::ctf_reader::create_read_context(opts.file2,
-                                                             opts.prepared_di_root_paths2,
-                                                             env.get());
-                ABG_ASSERT(ctxt);
-                c2 = abigail::ctf_reader::read_corpus(ctxt.get(),
-                                                      c2_status);
-              }
-            else
-#endif
+            if (first_input_origin & corpus::DWARF_ORIGIN)
               {
                 abigail::dwarf_reader::read_context_sptr ctxt =
                   abigail::dwarf_reader::create_read_context
@@ -1295,7 +1304,19 @@ main(int argc, char* argv[])
                         && (c2_status & STATUS_DEBUG_INFO_NOT_FOUND)))
                   return handle_error(c2_status, ctxt.get(), argv[0], opts);
               }
-	  }
+#ifdef WITH_CTF
+            else
+              {
+                abigail::ctf_reader::read_context_sptr ctxt
+                  = abigail::ctf_reader::create_read_context(opts.file2,
+                                                             opts.prepared_di_root_paths2,
+                                                             env.get());
+                ABG_ASSERT(ctxt);
+                c2 = abigail::ctf_reader::read_corpus(ctxt.get(),
+                                                      c2_status);
+              }
+#endif
+          }
 	  break;
 	case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
 	  {
@@ -1334,7 +1355,8 @@ main(int argc, char* argv[])
 
       if (!!c1 != !!c2
 	  || !!t1 != !!t2
-	  || !!g1 != !!g2)
+	  || !!g1 != !!g2
+          || c1_status != c2_status)
 	{
 	  emit_prefix(argv[0], cerr)
 	    << "the two input should be of the same kind\n";
diff --git a/tools/abidw.cc b/tools/abidw.cc
index f38d6048..9b03069b 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -551,25 +551,15 @@ load_corpus_and_write_abixml(char* argv[],
 
   // First of all, read a libabigail IR corpus from the file specified
   // in OPTS.
-  corpus_sptr corp;
+  corpus_sptr corp, dwarf_corpus;
   elf_reader::status s = elf_reader::STATUS_UNKNOWN;
+  corpus::origin origin =
 #ifdef WITH_CTF
-  if (opts.use_ctf)
-    {
-      abigail::ctf_reader::read_context_sptr ctxt
-        = abigail::ctf_reader::create_read_context(opts.in_file_path,
-                                                   opts.prepared_di_root_paths,
-                                                   env.get());
-      assert (ctxt);
-      t.start();
-      corp = abigail::ctf_reader::read_corpus (ctxt, s);
-      t.stop();
-      if (opts.do_log)
-        emit_prefix(argv[0], cerr)
-          << "read corpus from elf file in: " << t << "\n";
-    }
-  else
+    opts.use_ctf ? corpus::CTF_ORIGIN :
 #endif
+    corpus::DWARF_ORIGIN;
+
+  if (origin & corpus::DWARF_ORIGIN)
     {
       dwarf_reader::read_context_sptr c
         = abigail::dwarf_reader::create_read_context(opts.in_file_path,
@@ -616,7 +606,7 @@ load_corpus_and_write_abixml(char* argv[],
         }
 
       if (opts.exported_interfaces_only.has_value())
-	env->analyze_exported_interfaces_only(*opts.exported_interfaces_only);
+        env->analyze_exported_interfaces_only(*opts.exported_interfaces_only);
 
       t.start();
       corp = dwarf_reader::read_corpus_from_elf(ctxt, s);
@@ -632,7 +622,35 @@ load_corpus_and_write_abixml(char* argv[],
       if (opts.do_log)
         emit_prefix(argv[0], cerr)
           << "reset read context in: " << t << "\n";
+
+      dwarf_corpus = corp;
     }
+#ifdef WITH_CTF
+  if (((s & abigail::elf_reader::STATUS_OK) &&
+       (s & elf_reader::STATUS_DEBUG_INFO_NOT_FOUND)) ||
+      (origin & corpus::CTF_ORIGIN))
+    {
+      abigail::ctf_reader::read_context_sptr ctxt
+        = abigail::ctf_reader::create_read_context(opts.in_file_path,
+                                                   opts.prepared_di_root_paths,
+                                                   env.get());
+      assert (ctxt);
+      t.start();
+      corp = abigail::ctf_reader::read_corpus (ctxt, s);
+      t.stop();
+
+      // If CTF was not explicitly selected in the command line and
+      // there is no CTF information, then compare DWARF corpora
+      // by default only with symbols information.
+      if ((origin & corpus::DWARF_ORIGIN) &&
+          (s & abigail::elf_reader::STATUS_DEBUG_INFO_NOT_FOUND))
+        corp = dwarf_corpus;
+
+      if (opts.do_log)
+        emit_prefix(argv[0], cerr)
+          << "read corpus from elf file in: " << t << "\n";
+    }
+#endif
 
   // If we couldn't create a corpus, emit some (hopefully) useful
   // diagnostics and return and error.
@@ -834,7 +852,7 @@ load_kernel_corpus_group_and_write_abixml(char* argv[],
 
   global_timer.start();
   t.start();
-corpus::origin origin =
+  corpus::origin origin =
 #ifdef WITH_CTF
     opts.use_ctf ? corpus::CTF_ORIGIN :
 #endif
diff --git a/tools/abipkgdiff.cc b/tools/abipkgdiff.cc
index 656d5882..7704ac72 100644
--- a/tools/abipkgdiff.cc
+++ b/tools/abipkgdiff.cc
@@ -136,6 +136,7 @@ using abigail::tools_utils::build_corpus_group_from_kernel_dist_under;
 using abigail::tools_utils::load_default_system_suppressions;
 using abigail::tools_utils::load_default_user_suppressions;
 using abigail::tools_utils::abidiff_status;
+using abigail::corpus;
 using abigail::ir::corpus_sptr;
 using abigail::ir::corpus_group_sptr;
 using abigail::comparison::diff_context;
@@ -1320,33 +1321,54 @@ compare(const elf_file& elf1,
       << elf1.path
       << " ...\n";
 
-  corpus_sptr corpus1;
+  corpus_sptr corpus1, dwarf_corpus;
+  corpus::origin first_input_origin;
+  corpus::origin origin =
+#ifdef WITH_CTF
+    opts.use_ctf ? corpus::CTF_ORIGIN :
+#endif
+    corpus::DWARF_ORIGIN;
+
 #ifdef WITH_CTF
   abigail::ctf_reader::read_context_sptr ctxt_ctf;
 #endif
   read_context_sptr ctxt_dwarf;
   {
+    if (origin & corpus::DWARF_ORIGIN)
+      {
+        first_input_origin = corpus::DWARF_ORIGIN;
+        ctxt_dwarf = create_read_context(elf1.path, di_dirs1, env.get(),
+                                         /*load_all_types=*/opts.show_all_types);
+        add_read_context_suppressions(*ctxt_dwarf, priv_types_supprs1);
+        if (!opts.kabi_suppressions.empty())
+          add_read_context_suppressions(*ctxt_dwarf, opts.kabi_suppressions);
+
+        corpus1 = read_corpus_from_elf(*ctxt_dwarf, c1_status);
+        dwarf_corpus = corpus1;
+      }
 #ifdef WITH_CTF
-    if (opts.use_ctf)
+    if (((c1_status & abigail::elf_reader::STATUS_OK) &&
+         (c1_status & abigail::elf_reader::STATUS_DEBUG_INFO_NOT_FOUND)) ||
+        (origin & corpus::CTF_ORIGIN))
       {
+        first_input_origin = corpus::CTF_ORIGIN;
         ctxt_ctf = abigail::ctf_reader::create_read_context(elf1.path,
 							    di_dirs1,
                                                             env.get());
         ABG_ASSERT(ctxt_ctf);
         corpus1 = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
                                                    c1_status);
+        // If CTF was not explicitly selected in the command line and
+        // there is no CTF information, then compare DWARF corpora
+        // by default only with symbols information.
+        if ((origin & corpus::DWARF_ORIGIN) &&
+            (c1_status & abigail::elf_reader::STATUS_DEBUG_INFO_NOT_FOUND))
+          {
+            first_input_origin = corpus::DWARF_ORIGIN;
+            corpus1 = dwarf_corpus;
+          }
       }
-    else
 #endif
-      {
-        ctxt_dwarf = create_read_context(elf1.path, di_dirs1, env.get(),
-                                         /*load_all_types=*/opts.show_all_types);
-        add_read_context_suppressions(*ctxt_dwarf, priv_types_supprs1);
-        if (!opts.kabi_suppressions.empty())
-          add_read_context_suppressions(*ctxt_dwarf, opts.kabi_suppressions);
-
-        corpus1 = read_corpus_from_elf(*ctxt_dwarf, c1_status);
-      }
 
     bool bail_out = false;
     if (!(c1_status & abigail::elf_reader::STATUS_OK))
@@ -1392,11 +1414,7 @@ compare(const elf_file& elf1,
 	    emit_prefix("abipkgdiff", cerr)
 	      << "Could not find alternate debug info file";
 	    string alt_di_path;
-#ifdef WITH_CTF
-            if (opts.use_ctf)
-              ;
-            else
-#endif
+            if (first_input_origin & corpus::DWARF_ORIGIN)
               abigail::dwarf_reader::refers_to_alt_debug_info(*ctxt_dwarf,
                                                               alt_di_path);
 	    if (!alt_di_path.empty())
@@ -1431,17 +1449,7 @@ compare(const elf_file& elf1,
 
   corpus_sptr corpus2;
   {
-#ifdef WITH_CTF
-    if (opts.use_ctf)
-      {
-        ctxt_ctf = abigail::ctf_reader::create_read_context(elf2.path,
-							    di_dirs2,
-							    env.get());
-        corpus2 = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
-                                                   c2_status);
-      }
-    else
-#endif
+    if (first_input_origin & corpus::DWARF_ORIGIN)
       {
         ctxt_dwarf = create_read_context(elf2.path, di_dirs2, env.get(),
                                          /*load_all_types=*/opts.show_all_types);
@@ -1452,6 +1460,16 @@ compare(const elf_file& elf1,
 
         corpus2 = read_corpus_from_elf(*ctxt_dwarf, c2_status);
       }
+#ifdef WITH_CTF
+    else
+      {
+        ctxt_ctf = abigail::ctf_reader::create_read_context(elf2.path,
+							    di_dirs2,
+							    env.get());
+        corpus2 = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
+                                                   c2_status);
+      }
+#endif
 
     bool bail_out = false;
     if (!(c2_status & abigail::elf_reader::STATUS_OK))
@@ -1497,11 +1515,8 @@ compare(const elf_file& elf1,
 	    emit_prefix("abipkgdiff", cerr)
 	      << "Could not find alternate debug info file";
 	    string alt_di_path;
-#ifdef WITH_CTF
-            if (opts.use_ctf)
-              ;
-            else
-#endif
+
+            if (first_input_origin & corpus::DWARF_ORIGIN)
               abigail::dwarf_reader::refers_to_alt_debug_info(*ctxt_dwarf,
                                                               alt_di_path);
 	    if (!alt_di_path.empty())
@@ -1599,14 +1614,31 @@ compare_to_self(const elf_file& elf,
       << elf.path
       << " ...\n";
 
-  corpus_sptr corp;
+  corpus_sptr corp, dwarf_corpus;
+  corpus::origin origin =
+#ifdef WITH_CTF
+    opts.use_ctf ? corpus::CTF_ORIGIN :
+#endif
+    corpus::DWARF_ORIGIN;
 #ifdef WITH_CTF
   abigail::ctf_reader::read_context_sptr ctxt_ctf;
 #endif
+
   read_context_sptr ctxt_dwarf;
   {
+    if (origin & corpus::DWARF_ORIGIN)
+      {
+        ctxt_dwarf =
+         create_read_context(elf.path, di_dirs, env.get(),
+                             /*read_all_types=*/opts.show_all_types);
+
+        corp = read_corpus_from_elf(*ctxt_dwarf, c_status);
+        dwarf_corpus = corp;
+      }
 #ifdef WITH_CTF
-    if (opts.use_ctf)
+    if (((c_status & abigail::elf_reader::STATUS_OK) &&
+         (c_status & abigail::elf_reader::STATUS_DEBUG_INFO_NOT_FOUND)) ||
+        (origin & corpus::CTF_ORIGIN))
       {
         ctxt_ctf = abigail::ctf_reader::create_read_context(elf.path,
 							    di_dirs,
@@ -1614,16 +1646,14 @@ compare_to_self(const elf_file& elf,
         ABG_ASSERT(ctxt_ctf);
         corp = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
                                                    c_status);
+        // If CTF was not explicitly selected in the command line and
+        // there is no CTF information, then use DWARF corpus
+        // by default just with symbols information.
+        if ((origin & corpus::DWARF_ORIGIN) &&
+            (c_status & abigail::elf_reader::STATUS_DEBUG_INFO_NOT_FOUND))
+          corp = dwarf_corpus;
       }
-    else
 #endif
-      {
-        ctxt_dwarf =
-         create_read_context(elf.path, di_dirs, env.get(),
-                             /*read_all_types=*/opts.show_all_types);
-
-        corp = read_corpus_from_elf(*ctxt_dwarf, c_status);
-      }
 
     if (!(c_status & abigail::elf_reader::STATUS_OK))
       {
-- 
2.35.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2022-11-28 21:59 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-01  0:15 [PATCH] CTF as a fallback when no DWARF debug info is present Guillermo E. Martinez
2022-10-04  9:04 ` Dodji Seketeli
2022-10-04 23:13   ` Guillermo E. Martinez
2022-10-06  7:42     ` Dodji Seketeli
2022-10-06 14:12       ` Dodji Seketeli
2022-10-07 14:13         ` Guillermo E. Martinez
2022-10-06 19:53       ` Guillermo Martinez
2022-10-06 19:50         ` Guillermo E. Martinez
2022-10-07 13:38         ` Dodji Seketeli
2022-10-07 16:04           ` Ben Woodard
2022-11-15 20:13 ` [PATCHv2] ELF based front-end readers fallback feature Guillermo E. Martinez
2022-11-21 18:51   ` [PATCHv3] " Guillermo E. Martinez
2022-11-22 14:19     ` Dodji Seketeli
2022-11-22 16:02       ` Guillermo E. Martinez
2022-11-22 16:00     ` [PATCH v4] " Guillermo E. Martinez
2022-11-28 15:56       ` Dodji Seketeli
2022-11-28 21:59         ` 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).