abixml-reader: Support SONAME related properties on file suppression

Message ID 861rqnzzpw.fsf@seketeli.org
State Committed
Headers
Series abixml-reader: Support SONAME related properties on file suppression |

Commit Message

Dodji Seketeli Jan. 1, 2020, midnight UTC
  When comparing binary files (using abidiff for instance) libabigail
can interpret the [suppress_file] section of a suppression
specification.  If the suppression specification matches either of the
compared files, no comparison is performed.

At the moment, that doesn't work when comparing abixml files.

Thus, this patch implements that feature for abixml files.

With this patch, one can now write a suppression specification like
this:

  [suppress_file]
    soname_regexp = <some-regexp>

or

  [suppress_file]
    file_name_regexp = <some-regexp>

If either abixml file has a soname matched by such a regexp, then no
comparison is performed.

	* doc/manuals/libabigail-concepts.rst: Update the documentation to
	mention soname_regexp and soname_not_regexp is supported in the
	[suppress_file] section.
	* include/abg-suppression.h (suppression_matches_soname)
	(suppression_matches_soname_or_filename): Declare new functions.
	Make them be friends of class suppression_base.
	* src/abg-reader.cc
	(read_context::corpus_is_suppressed_by_soname_or_filename): Define
	new member function.
	(read_corpus_from_input): Apply file suppression.
	* src/abg-suppression.cc (read_file_suppression): Support
	"soname_regexp" and "soname_not_regexp" in the [suppress_file]
	section.
	(suppression_matches_soname)
	(suppression_matches_soname_or_filename): Define new functions.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-report-{1,2}.txt:
	New test reference output files.
	Likewise.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-suppr.txt:
	New test suppression file.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-{2,3,4}.txt::
	Likewise.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-v{0,1}.so: New
	test binary input files.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-v{0,1}.so.abi:
	New abixml for the binary input files above.
	* tests/data/test-diff-suppr/test48-soname-abixml-v{0,1}.c: Source
	code of the binary input files above.
	* tests/data/Makefile.am: Add the above test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the test input
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 doc/manuals/libabigail-concepts.rst                |  30 ++++++++--
 include/abg-suppression.h                          |  18 ++++++
 src/abg-reader.cc                                  |  54 ++++++++++++++++-
 src/abg-suppression.cc                             |  65 ++++++++++++++++++++-
 tests/data/Makefile.am                             |  12 ++++
 .../libtest48-soname-abixml-report-1.txt           |  16 +++++
 .../libtest48-soname-abixml-report-2.txt           |   0
 .../libtest48-soname-abixml-suppr-2.txt            |   2 +
 .../libtest48-soname-abixml-suppr-3.txt            |   2 +
 .../libtest48-soname-abixml-suppr-4.txt            |   2 +
 .../libtest48-soname-abixml-suppr.txt              |   2 +
 .../test-diff-suppr/libtest48-soname-abixml-v0.so  | Bin 0 -> 8632 bytes
 .../libtest48-soname-abixml-v0.so.abi              |  24 ++++++++
 .../test-diff-suppr/libtest48-soname-abixml-v1.so  | Bin 0 -> 8664 bytes
 .../libtest48-soname-abixml-v1.so.abi              |  28 +++++++++
 .../data/test-diff-suppr/test48-soname-abixml-v0.c |   8 +++
 .../data/test-diff-suppr/test48-soname-abixml-v1.c |   9 +++
 tests/test-diff-suppr.cc                           |  50 ++++++++++++++++
 18 files changed, 314 insertions(+), 8 deletions(-)
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-report-1.txt
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-report-2.txt
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-2.txt
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-3.txt
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-4.txt
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-suppr.txt
 create mode 100755 tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so.abi
 create mode 100755 tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so
 create mode 100644 tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi
 create mode 100644 tests/data/test-diff-suppr/test48-soname-abixml-v0.c
 create mode 100644 tests/data/test-diff-suppr/test48-soname-abixml-v1.c
  

Patch

diff --git a/doc/manuals/libabigail-concepts.rst b/doc/manuals/libabigail-concepts.rst
index 6565d30..607edee 100644
--- a/doc/manuals/libabigail-concepts.rst
+++ b/doc/manuals/libabigail-concepts.rst
@@ -197,10 +197,10 @@  suppress ABI change reports for a particular kind of ABI artifact.
 $$$$$$$$$$$$$$$$$$$
 
 This directive prevents a given tool from loading a file (binary or
-not) if its file name matches certain properties.  Thus, if the tool
-is meant to compare the ABIs of two files, and if the directive
-prevents it from loading either one of the files, then no comparison
-is performed.
+abixml file) if its file name or other properties match certain
+properties.  Thus, if the tool is meant to compare the ABIs of two
+files, and if the directive prevents it from loading either one of the
+files, then no comparison is performed.
 
 Note that for the ``[suppress_file]`` directive to work, at least one
 of the following properties must be provided:
@@ -228,6 +228,28 @@  The potential properties of this sections are listed below:
   the regular expression specified as value of this property.
 
 
+* ``soname_regexp``
+
+  Usage:
+
+    ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
+
+  Prevents the system from loading the file which contains a SONAME
+  property that matches the regular expression of this property.  Note
+  that this property also works on an abixml file if it contains a
+  SONAME property.
+
+* ``soname_not_regexp``
+
+  Usage:
+
+    ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
+
+  Prevents the system from loading the file which contains a SONAME
+  property that does *NOT* match the regular expression of this
+  property.  Note that this property also works on an abixml file if
+  it contains a SONAME property.
+
 * ``label``
 
  Usage:
diff --git a/include/abg-suppression.h b/include/abg-suppression.h
index 05709d6..1ccb776 100644
--- a/include/abg-suppression.h
+++ b/include/abg-suppression.h
@@ -119,6 +119,15 @@  public:
   suppresses_diff(const diff*) const = 0;
 
   virtual ~suppression_base();
+
+  friend bool
+  suppression_matches_soname(const string& soname,
+			     const suppression_base& suppr);
+
+  friend bool
+  suppression_matches_soname_or_filename(const string& soname,
+					 const string& filename,
+					 const suppression_base& suppr);
 }; // end class suppression_base
 
 void
@@ -826,6 +835,15 @@  file_suppression_sptr
 file_is_suppressed(const string& file_path,
 		   const suppressions_type& suppressions);
 
+bool
+suppression_matches_soname(const string& soname,
+			   const suppression_base& suppr);
+
+bool
+suppression_matches_soname_or_filename(const string& soname,
+				       const string& filename,
+				       const suppression_base& suppr);
+
 const char*
 get_private_types_suppr_spec_label();
 
diff --git a/src/abg-reader.cc b/src/abg-reader.cc
index 7c8a56a..915b2c1 100644
--- a/src/abg-reader.cc
+++ b/src/abg-reader.cc
@@ -794,6 +794,35 @@  public:
   get_suppressions() const
   {return const_cast<read_context*>(this)->get_suppressions();}
 
+  /// Test if there are suppression specifications (associated to the
+  /// current corpus) that match a given SONAME or file name.
+  ///
+  /// @param soname the SONAME to consider.
+  ///
+  /// @param the file name to consider.
+  ///
+  /// @return true iff there are suppression specifications (associated to the
+  /// current corpus) that match the SONAME denoted by @p soname or
+  /// the file name denoted by @p filename.
+  bool
+  corpus_is_suppressed_by_soname_or_filename(const string& soname,
+					     const string& filename)
+  {
+    using suppr::suppressions_type;
+    using suppr::file_suppression_sptr;
+    using suppr::is_file_suppression;
+
+    for (suppressions_type::const_iterator s = get_suppressions().begin();
+	 s != get_suppressions().end();
+	 ++s)
+      if (file_suppression_sptr suppr = is_file_suppression(*s))
+	if (suppr::suppression_matches_soname_or_filename(soname, filename,
+							  *suppr))
+	  return true;
+
+    return false;
+  }
+
   /// Add a given function to the set of exported functions of the
   /// current corpus, if the function satisfies the different
   /// constraints requirements.
@@ -1860,8 +1889,13 @@  read_corpus_from_input(read_context& ctxt)
       ctxt.set_exported_decls_builder(corp.get_exported_decls_builder().get());
 
       xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(reader, "path");
+      string path;
+
       if (path_str)
-	corp.set_path(reinterpret_cast<char*>(path_str.get()));
+	{
+	  path = reinterpret_cast<char*>(path_str.get());
+	  corp.set_path(path);
+	}
 
       xml::xml_char_sptr architecture_str =
 	XML_READER_GET_ATTRIBUTE(reader, "architecture");
@@ -1871,8 +1905,24 @@  read_corpus_from_input(read_context& ctxt)
 
       xml::xml_char_sptr soname_str =
 	XML_READER_GET_ATTRIBUTE(reader, "soname");
+      string soname;
+
       if (soname_str)
-	corp.set_soname(reinterpret_cast<char*>(soname_str.get()));
+	{
+	  soname = reinterpret_cast<char*>(soname_str.get());
+	  corp.set_soname(soname);
+	}
+
+      // Apply suppression specifications here to honour:
+      //
+      //   [suppress_file]
+      //     (soname_regexp
+      //      |soname_not_regexp
+      //      |file_name_regexp
+      //      |file_name_not_regexp) = <soname-or-file-name>
+      if ((!soname.empty() || !path.empty())
+	  && ctxt.corpus_is_suppressed_by_soname_or_filename(soname, path))
+	return nil;
 
       node = xmlTextReaderExpand(reader.get());
       if (!node)
diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc
index 663749d..91286f2 100644
--- a/src/abg-suppression.cc
+++ b/src/abg-suppression.cc
@@ -4335,14 +4335,39 @@  read_file_suppression(const ini::config::section& section)
     ? file_name_not_regex_prop->get_value()->as_string()
     : "";
 
+  ini::simple_property_sptr soname_regex_prop =
+    is_simple_property(section.find_property("soname_regexp"));
+  string soname_regex_str =
+    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";
+
+  ini::simple_property_sptr soname_not_regex_prop =
+    is_simple_property(section.find_property("soname_not_regexp"));
+  string soname_not_regex_str =
+    soname_not_regex_prop
+    ? soname_not_regex_prop->get_value()->as_string()
+    : "";
+
   if (file_name_regex_str.empty()
-      && file_name_not_regex_str.empty())
+      && file_name_not_regex_str.empty()
+      && soname_regex_str.empty()
+      && soname_not_regex_str.empty())
     return result;
-
   result.reset(new file_suppression(label_str,
 				    file_name_regex_str,
 				    file_name_not_regex_str));
 
+  if (!soname_regex_str.empty())
+    {
+      result->set_soname_regex_str(soname_regex_str);
+      result->set_drops_artifact_from_ir(true);
+    }
+
+  if (!soname_not_regex_str.empty())
+    {
+      result->set_soname_not_regex_str(soname_not_regex_str);
+      result->set_drops_artifact_from_ir(true);
+    }
+
   return result;
 }
 
@@ -4382,6 +4407,42 @@  file_is_suppressed(const string& file_path,
   return file_suppression_sptr();
 }
 
+/// Test if a given SONAME is matched by a given suppression
+/// specification.
+///
+/// @param soname the SONAME to consider.
+///
+/// @param suppr the suppression specification to consider.
+///
+/// @return true iff a given SONAME is matched by a given suppression
+/// specification.
+bool
+suppression_matches_soname(const string& soname,
+			   const suppression_base& suppr)
+{
+  return suppr.priv_->matches_soname(soname);
+}
+
+/// Test if a given SONAME or file name is matched by a given
+/// suppression specification.
+///
+/// @param soname the SONAME to consider.
+///
+/// @param filename the file name to consider.
+///
+/// @param suppr the suppression specification to consider.
+///
+/// @return true iff either @p soname or @p filename is matched by the
+/// suppression specification @p suppr.
+bool
+suppression_matches_soname_or_filename(const string& soname,
+				       const string& filename,
+				       const suppression_base& suppr)
+{
+  return (suppression_matches_soname(soname, suppr)
+	 || suppr.priv_->matches_binary_name(filename));
+}
+
 /// @return the name of the artificial private type suppression
 /// specification that is auto-generated by libabigail to suppress
 /// change reports about types that are not defined in public headers.
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index a38fadf..5031e6d 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -1273,6 +1273,18 @@  test-diff-suppr/test47-non-reachable-types-v1.o \
 test-diff-suppr/test47-non-reachable-types-v0.o.alltypes.abixml \
 test-diff-suppr/test47-non-reachable-types-v1.o.alltypes.abixml \
 test-diff-suppr/test47-non-reachable-types-report-10.txt \
+test-diff-suppr/libtest48-soname-abixml-v0.so \
+test-diff-suppr/libtest48-soname-abixml-v0.so.abi \
+test-diff-suppr/libtest48-soname-abixml-v1.so \
+test-diff-suppr/libtest48-soname-abixml-v1.so.abi \
+test-diff-suppr/test48-soname-abixml-v0.c \
+test-diff-suppr/test48-soname-abixml-v1.c \
+test-diff-suppr/libtest48-soname-abixml-report-1.txt \
+test-diff-suppr/libtest48-soname-abixml-report-2.txt \
+test-diff-suppr/libtest48-soname-abixml-suppr.txt \
+test-diff-suppr/libtest48-soname-abixml-suppr-2.txt \
+test-diff-suppr/libtest48-soname-abixml-suppr-3.txt \
+test-diff-suppr/libtest48-soname-abixml-suppr-4.txt \
 \
 test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1 \
 test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi \
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-report-1.txt b/tests/data/test-diff-suppr/libtest48-soname-abixml-report-1.txt
new file mode 100644
index 0000000..9ba2b12
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-report-1.txt
@@ -0,0 +1,16 @@ 
+ELF SONAME changed
+Functions changes summary: 0 Removed, 1 Changed, 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+SONAME changed from 'test48-soname-abixml-v0' to 'test48-soname-abixml-v1'
+
+1 function with some indirect sub-type change:
+
+  [C]'function void foo(S*)' at test48-soname-abixml-v1.c:8:1 has some indirect sub-type changes:
+    parameter 1 of type 'S*' has sub-type changes:
+      in pointed to type 'struct S' at test48-soname-abixml-v1.c:1:1:
+        type size changed from 32 to 64 (in bits)
+        1 data member insertion:
+          'char S::m1', at offset 32 (in bits) at test48-soname-abixml-v1.c:4:1
+
+
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-report-2.txt b/tests/data/test-diff-suppr/libtest48-soname-abixml-report-2.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-2.txt b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-2.txt
new file mode 100644
index 0000000..c9b7ad4
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-2.txt
@@ -0,0 +1,2 @@ 
+[suppress_file]
+  soname_regexp = test48<typo>-soname-abixml-v.*
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-3.txt b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-3.txt
new file mode 100644
index 0000000..c69c250
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-3.txt
@@ -0,0 +1,2 @@ 
+[suppress_file]
+  file_name_regexp = ^libtest48-soname-abixml-v.*$
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-4.txt b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-4.txt
new file mode 100644
index 0000000..1a20527
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr-4.txt
@@ -0,0 +1,2 @@ 
+[suppress_file]
+  file_name_regexp = ^libtest48<typo>-soname-abixml-v.*$
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr.txt b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr.txt
new file mode 100644
index 0000000..08d61c0
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-suppr.txt
@@ -0,0 +1,2 @@ 
+[suppress_file]
+  soname_regexp = test48-soname-abixml-v.*
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so b/tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..e805adf0f40efcc3d1be5531f38445ee9864b8d5
GIT binary patch
literal 8632
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
MU0D(eKw-sy02Vr;y8r+H

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so.abi b/tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so.abi
new file mode 100644
index 0000000..f9fa8e5
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so.abi
@@ -0,0 +1,24 @@ 
+<abi-corpus path='libtest48-soname-abixml-v0.so' architecture='elf-amd-x86_64' soname='test48-soname-abixml-v0'>
+  <elf-needed>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test48-soname-abixml-v0.c' comp-dir-path='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr' language='LANG_C99'>
+    <type-decl name='int' size-in-bits='32' id='type-id-1'/>
+    <type-decl name='void' id='type-id-2'/>
+    <class-decl name='S' size-in-bits='32' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v0.c' line='1' column='1' id='type-id-3'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='m0' type-id='type-id-1' visibility='default' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v0.c' line='3' column='1'/>
+      </data-member>
+    </class-decl>
+    <pointer-type-def type-id='type-id-3' size-in-bits='64' id='type-id-4'/>
+    <function-decl name='foo' mangled-name='foo' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v0.c' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='foo'>
+      <parameter type-id='type-id-4' name='a' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v0.c' line='7' column='1'/>
+      <return type-id='type-id-2'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so b/tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so
new file mode 100755
index 0000000000000000000000000000000000000000..a10a9f8b0f8cfef4c4764abae69757201e224006
GIT binary patch
literal 8664
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

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi b/tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi
new file mode 100644
index 0000000..060ceb4
--- /dev/null
+++ b/tests/data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi
@@ -0,0 +1,28 @@ 
+<abi-corpus path='libtest48-soname-abixml-v1.so' architecture='elf-amd-x86_64' soname='test48-soname-abixml-v1'>
+  <elf-needed>
+    <dependency name='libc.so.6'/>
+  </elf-needed>
+  <elf-function-symbols>
+    <elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+    <elf-symbol name='foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+  </elf-function-symbols>
+  <abi-instr version='1.0' address-size='64' path='test48-soname-abixml-v1.c' comp-dir-path='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr' language='LANG_C99'>
+    <type-decl name='char' size-in-bits='8' id='type-id-1'/>
+    <type-decl name='int' size-in-bits='32' id='type-id-2'/>
+    <type-decl name='void' id='type-id-3'/>
+    <class-decl name='S' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v1.c' line='1' column='1' id='type-id-4'>
+      <data-member access='public' layout-offset-in-bits='0'>
+        <var-decl name='m0' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v1.c' line='3' column='1'/>
+      </data-member>
+      <data-member access='public' layout-offset-in-bits='32'>
+        <var-decl name='m1' type-id='type-id-1' visibility='default' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v1.c' line='4' column='1'/>
+      </data-member>
+    </class-decl>
+    <pointer-type-def type-id='type-id-4' size-in-bits='64' id='type-id-5'/>
+    <function-decl name='foo' mangled-name='foo' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v1.c' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='foo'>
+      <parameter type-id='type-id-5' name='a' filepath='/home/dodji/git/libabigail/suppress-file-abixml/tests/data/test-diff-suppr/test48-soname-abixml-v1.c' line='8' column='1'/>
+      <return type-id='type-id-3'/>
+    </function-decl>
+  </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-diff-suppr/test48-soname-abixml-v0.c b/tests/data/test-diff-suppr/test48-soname-abixml-v0.c
new file mode 100644
index 0000000..3ea3ca7
--- /dev/null
+++ b/tests/data/test-diff-suppr/test48-soname-abixml-v0.c
@@ -0,0 +1,8 @@ 
+struct S
+{
+  int m0;
+};
+
+void
+foo(struct S *a __attribute__((unused)))
+{}
diff --git a/tests/data/test-diff-suppr/test48-soname-abixml-v1.c b/tests/data/test-diff-suppr/test48-soname-abixml-v1.c
new file mode 100644
index 0000000..fc74925
--- /dev/null
+++ b/tests/data/test-diff-suppr/test48-soname-abixml-v1.c
@@ -0,0 +1,9 @@ 
+struct S
+{
+  int m0;
+  char m1;
+};
+
+void
+foo(struct S *a __attribute__((unused)))
+{}
diff --git a/tests/test-diff-suppr.cc b/tests/test-diff-suppr.cc
index b513a4b..26de009 100644
--- a/tests/test-diff-suppr.cc
+++ b/tests/test-diff-suppr.cc
@@ -1958,6 +1958,56 @@  InOutSpec in_out_specs[] =
     "data/test-diff-suppr/test47-non-reachable-types-report-10.txt",
     "output/test-diff-suppr/test47-non-reachable-types-report-10.txt"
   },
+  {
+    "data/test-diff-suppr/libtest48-soname-abixml-v0.so",
+    "data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    "data/test-diff-suppr/libtest48-soname-abixml-report-1.txt",
+    "output/test-diff-suppr/libtest48-soname-abixml-report-1.txt"
+  },
+  {
+    "data/test-diff-suppr/libtest48-soname-abixml-v0.so",
+    "data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi",
+    "",
+    "",
+    "data/test-diff-suppr/libtest48-soname-abixml-suppr.txt",
+    "--no-default-suppression",
+    "data/test-diff-suppr/libtest48-soname-abixml-report-2.txt",
+    "output/test-diff-suppr/libtest48-soname-abixml-report-2.txt"
+  },
+  {
+    "data/test-diff-suppr/libtest48-soname-abixml-v0.so",
+    "data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi",
+    "",
+    "",
+    "data/test-diff-suppr/libtest48-soname-abixml-suppr-2.txt",
+    "--no-default-suppression",
+    "data/test-diff-suppr/libtest48-soname-abixml-report-1.txt",
+    "output/test-diff-suppr/libtest48-soname-abixml-report-1.txt"
+  },
+  {
+    "data/test-diff-suppr/libtest48-soname-abixml-v0.so",
+    "data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi",
+    "",
+    "",
+    "data/test-diff-suppr/libtest48-soname-abixml-suppr-3.txt",
+    "--no-default-suppression",
+    "data/test-diff-suppr/libtest48-soname-abixml-report-2.txt",
+    "output/test-diff-suppr/libtest48-soname-abixml-report-2.txt"
+  },
+  {
+    "data/test-diff-suppr/libtest48-soname-abixml-v0.so",
+    "data/test-diff-suppr/libtest48-soname-abixml-v1.so.abi",
+    "",
+    "",
+    "data/test-diff-suppr/libtest48-soname-abixml-suppr-4.txt",
+    "--no-default-suppression",
+    "data/test-diff-suppr/libtest48-soname-abixml-report-1.txt",
+    "output/test-diff-suppr/libtest48-soname-abixml-report-1.txt"
+  },
   // This should be the last entry
   {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
 };