[PATCH] abicompat: Add the ability to process abi corpus group
claudiu.zissulescu-ianculescu@oracle.com
claudiu.zissulescu-ianculescu@oracle.com
Thu Aug 7 15:17:57 GMT 2025
From: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>
This patch introduces a new option `--soname` to the `abicompat` tool.
This new option allows users to specify a shared library name when
comparing ABI XML files that contain groups of corpora. This is useful
when dealing with multiple shared libraries that have their ABIs
stored within a single XML file.
This patch also adds a new test case for this functionality, and
updates the documentation.
---
big-tests | 2 +-
doc/manuals/abicompat.rst | 8 ++
.../test-abicompat/libtest10-fn-changed.xml | 86 +++++++++++++++++++
.../test-abicompat/test10-fn-changed-app.xml | 45 ++++++++++
.../data/test-abicompat/test10-fn-changed.txt | 15 ++++
tests/test-abicompat.cc | 10 +++
tools/abicompat.cc | 41 ++++++++-
7 files changed, 205 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test-abicompat/libtest10-fn-changed.xml
create mode 100644 tests/data/test-abicompat/test10-fn-changed-app.xml
create mode 100644 tests/data/test-abicompat/test10-fn-changed.txt
diff --git a/big-tests b/big-tests
index e772c1e6..bcec65b5 160000
--- a/big-tests
+++ b/big-tests
@@ -1 +1 @@
-Subproject commit e772c1e67aba14141dd16735ecdf19368b0cb29e
+Subproject commit bcec65b53b8332710f8d74adf4d6a060a91ab5ee
diff --git a/doc/manuals/abicompat.rst b/doc/manuals/abicompat.rst
index 8f19c433..99e41896 100644
--- a/doc/manuals/abicompat.rst
+++ b/doc/manuals/abicompat.rst
@@ -131,6 +131,14 @@ Options
application but that are removed from the library. That is why it
is called ``weak`` mode.
+ * ``--soname`` <shared-library-name>
+
+ Specify a shared library name. When the shared libraries versions
+ are given as ABIXMLs and those XML files contains groups of
+ corpora, then the shared library name is used to select the right
+ ABI corpus to be used when checking the ABI compatibility between
+ the application and the shared library.
+
.. _abicompat_return_value_label:
Return values
diff --git a/tests/data/test-abicompat/libtest10-fn-changed.xml b/tests/data/test-abicompat/libtest10-fn-changed.xml
new file mode 100644
index 00000000..097af2af
--- /dev/null
+++ b/tests/data/test-abicompat/libtest10-fn-changed.xml
@@ -0,0 +1,86 @@
+<abi-corpus-group version='2.4' architecture='elf-amd-x86_64'>
+ <abi-corpus version='2.4' path='libtest-1.so' architecture='elf-amd-x86_64' soname='libtest-1.so'>
+ <elf-needed>
+ <dependency name='libstdc++.so.6'/>
+ <dependency name='libm.so.6'/>
+ <dependency name='libgcc_s.so.1'/>
+ <dependency name='libc.so.6'/>
+ </elf-needed>
+ <elf-function-symbols>
+ <elf-symbol name='_Z10first_funcv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='_Z11second_funcR3foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='_ZN3fooC1Ev' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='_ZN3fooC2Ev' type='func-type' binding='weak-binding' visibility='default-visibility' alias='_ZN3fooC1Ev' is-defined='yes'/>
+ </elf-function-symbols>
+ <undefined-elf-function-symbols>
+ <elf-symbol name='_ZdlPvm' version='CXXABI_1.3.9' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='_Znwm' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='__cxa_finalize' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ </undefined-elf-function-symbols>
+ <undefined-elf-variable-symbols>
+ <elf-symbol name='_ITM_deregisterTMCloneTable' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='_ITM_registerTMCloneTable' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='__gmon_start__' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ </undefined-elf-variable-symbols>
+ <abi-instr address-size='64' path='test1.cc' comp-dir-path='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample' language='LANG_C_plus_plus_14'>
+ <type-decl name='char' size-in-bits='8' hash='65b2d157027b431a' id='type-id-1'/>
+ <type-decl name='int' size-in-bits='32' hash='09d17c08f594edc7' id='type-id-2'/>
+ <class-decl name='foo' is-struct='yes' visibility='default' size-in-bits='64' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test1.h' line='1' column='1' hash='b9bca352028d2431' id='type-id-3'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='m0' type-id='type-id-2' visibility='default' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test1.h' 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/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test1.h' line='4' column='1'/>
+ </data-member>
+ <member-function access='public' constructor='yes'>
+ <function-decl name='foo' mangled-name='_ZN3fooC2Ev' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test1.h' line='6' column='1' declared-inline='yes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN3fooC2Ev' hash='7f32ffea222edbe7'>
+ <parameter type-id='type-id-4' is-artificial='yes'/>
+ <return type-id='type-id-5'/>
+ </function-decl>
+ </member-function>
+ </class-decl>
+ <reference-type-def kind='lvalue' type-id='type-id-3' size-in-bits='64' hash='1854f0b6950169b7' id='type-id-6'/>
+ <pointer-type-def type-id='type-id-3' size-in-bits='64' hash='dc66dea208456f85' id='type-id-4'/>
+ <qualified-type-def type-id='type-id-4' const='yes' hash='0ee8cf1f479fe91e' id='type-id-7'/>
+ <function-decl name='first_func' mangled-name='_Z10first_funcv' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test1.cc' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z10first_funcv' hash='fb51336c1fc02347'>
+ <return type-id='type-id-4'/>
+ </function-decl>
+ <function-decl name='second_func' mangled-name='_Z11second_funcR3foo' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test1.cc' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z11second_funcR3foo' hash='01ba306f4098d54e'>
+ <parameter type-id='type-id-6'/>
+ <return type-id='type-id-5'/>
+ </function-decl>
+ <type-decl name='void' id='type-id-5'/>
+ </abi-instr>
+ </abi-corpus>
+ <abi-corpus version='2.4' path='libtest-2.so' architecture='elf-amd-x86_64' soname='libtest-2.so'>
+ <elf-needed>
+ <dependency name='libstdc++.so.6'/>
+ <dependency name='libm.so.6'/>
+ <dependency name='libgcc_s.so.1'/>
+ <dependency name='libc.so.6'/>
+ </elf-needed>
+ <elf-function-symbols>
+ <elf-symbol name='_Z3fooP2S0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ </elf-function-symbols>
+ <undefined-elf-function-symbols>
+ <elf-symbol name='__cxa_finalize' version='GLIBC_2.2.5' is-default-version='yes' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ </undefined-elf-function-symbols>
+ <undefined-elf-variable-symbols>
+ <elf-symbol name='_ITM_deregisterTMCloneTable' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='_ITM_registerTMCloneTable' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='__gmon_start__' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ </undefined-elf-variable-symbols>
+ <abi-instr address-size='64' path='test2.cc' comp-dir-path='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample' language='LANG_C_plus_plus_14'>
+ <class-decl name='S0' is-struct='yes' visibility='default' size-in-bits='32' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test2.cc' line='4' column='1' hash='55ff770e9a972727' id='type-id-8'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='m0' type-id='type-id-2' visibility='default' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test2.cc' line='6' column='1'/>
+ </data-member>
+ </class-decl>
+ <pointer-type-def type-id='type-id-8' size-in-bits='64' hash='c816e79b49fbd0b0' id='type-id-9'/>
+ <function-decl name='foo' mangled-name='_Z3fooP2S0' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test2.cc' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z3fooP2S0' hash='a6fe781ceb581b24'>
+ <parameter type-id='type-id-9'/>
+ <return type-id='type-id-5'/>
+ </function-decl>
+ </abi-instr>
+ </abi-corpus>
+</abi-corpus-group>
diff --git a/tests/data/test-abicompat/test10-fn-changed-app.xml b/tests/data/test-abicompat/test10-fn-changed-app.xml
new file mode 100644
index 00000000..8e5b2728
--- /dev/null
+++ b/tests/data/test-abicompat/test10-fn-changed-app.xml
@@ -0,0 +1,45 @@
+<abi-corpus version='2.4' path='test-app' architecture='elf-amd-x86_64'>
+ <elf-needed>
+ <dependency name='libtest-0.so'/>
+ <dependency name='libstdc++.so.6'/>
+ <dependency name='libm.so.6'/>
+ <dependency name='libgcc_s.so.1'/>
+ <dependency name='libc.so.6'/>
+ </elf-needed>
+ <elf-function-symbols>
+ <elf-symbol name='_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ </elf-function-symbols>
+ <elf-variable-symbols>
+ <elf-symbol name='_IO_stdin_used' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ </elf-variable-symbols>
+ <undefined-elf-function-symbols>
+ <elf-symbol name='_Z10first_funcv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='_Z11second_funcR3foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='no'/>
+ <elf-symbol name='__libc_start_main@GLIBC_2.34' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='no'/>
+ </undefined-elf-function-symbols>
+ <undefined-elf-variable-symbols>
+ <elf-symbol name='__gmon_start__' type='no-type' binding='weak-binding' visibility='default-visibility' is-defined='no'/>
+ </undefined-elf-variable-symbols>
+ <abi-instr address-size='64' path='test-app.cc' comp-dir-path='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample' language='LANG_C_plus_plus_14'>
+ <type-decl name='int' size-in-bits='32' hash='09d17c08f594edc7' id='type-id-1'/>
+ <class-decl name='foo' is-struct='yes' visibility='default' size-in-bits='32' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test0.h' line='1' column='1' hash='c994494c47450411' id='type-id-2'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='m0' type-id='type-id-1' visibility='default' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test0.h' line='3' column='1'/>
+ </data-member>
+ </class-decl>
+ <reference-type-def kind='lvalue' type-id='type-id-2' size-in-bits='64' hash='1854f0b6950169b7' id='type-id-3'/>
+ <pointer-type-def type-id='type-id-2' size-in-bits='64' hash='dc66dea208456f85' id='type-id-4'/>
+ <function-decl name='main' mangled-name='main' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test-app.cc' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='main' hash='388da3fa973fde78'>
+ <return type-id='type-id-1'/>
+ </function-decl>
+ <function-decl name='first_func' mangled-name='_Z10first_funcv' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test0.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z10first_funcv' hash='fb51336c1fc02347'>
+ <return type-id='type-id-4'/>
+ </function-decl>
+ <function-decl name='second_func' mangled-name='_Z11second_funcR3foo' filepath='/home/cls/Projects/oracle/libabigail_work/BinLibCheck/simpleExample/test0.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Z11second_funcR3foo' hash='01ba306f4098d54e'>
+ <parameter type-id='type-id-3'/>
+ <return type-id='type-id-5'/>
+ </function-decl>
+ <type-decl name='void' id='type-id-5'/>
+ </abi-instr>
+</abi-corpus>
diff --git a/tests/data/test-abicompat/test10-fn-changed.txt b/tests/data/test-abicompat/test10-fn-changed.txt
new file mode 100644
index 00000000..357b9d75
--- /dev/null
+++ b/tests/data/test-abicompat/test10-fn-changed.txt
@@ -0,0 +1,15 @@
+Searching for soname libtest-1.so ... found.
+functions defined in library 'libtest10-fn-changed.xml'
+have sub-types that are different from what application 'test10-fn-changed-app.xml' expects:
+
+ function foo* first_func(void):
+ return type changed:
+ in pointed to type 'struct foo' at test1.h:1:1:
+ type size changed from 32 to 64 (in bits)
+ 1 data member insertion:
+ 'char m1', at offset 32 (in bits) at test1.h:4:1
+
+ function void second_func(foo&):
+ parameter 1 of type 'foo&' has sub-type changes:
+ referenced type 'struct foo' changed at test0.h:1:1, as reported earlier
+
diff --git a/tests/test-abicompat.cc b/tests/test-abicompat.cc
index 051cfba4..02ca97c3 100644
--- a/tests/test-abicompat.cc
+++ b/tests/test-abicompat.cc
@@ -334,6 +334,16 @@ InOutSpec in_out_specs[] =
"data/test-abicompat/test10/test10-fn-changed-report-4.txt",
"output/test-abicompat/test10/test10-fn-changed-report-4.txt",
},
+ {
+ "data/test-abicompat/test10-fn-changed-app.xml",
+ "data/test-abicompat/libtest10-fn-changed.xml",
+ "",
+ "",
+ "--show-base-names --weak-mode --soname libtest-1.so",
+ abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+ "data/test-abicompat/test10-fn-changed.txt",
+ "output/test-abicompat/test10-fn-changed.txt",
+ },
// This entry must be the last one.
{0, 0, 0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
};
diff --git a/tools/abicompat.cc b/tools/abicompat.cc
index b3e556dd..9b28d9ad 100644
--- a/tools/abicompat.cc
+++ b/tools/abicompat.cc
@@ -100,6 +100,7 @@ public:
string app_di_root_path;
string lib1_di_root_path;
string lib2_di_root_path;
+ string soname;
vector<string> suppression_paths;
bool display_help;
bool display_version;
@@ -246,6 +247,7 @@ display_usage(const string& prog_name, ostream& out)
<< " --redundant display redundant changes (this is the default)\n"
<< " --weak-mode check compatibility between the application and "
"just one version of the library.\n"
+ << " --soname specify the search so name (only for xml corpus groups)\n"
#ifdef WITH_CTF
<< " --ctf use CTF instead of DWARF in ELF files\n"
#endif
@@ -274,6 +276,14 @@ parse_command_line(int argc, char* argv[], options& opts)
else
return false;
}
+ else if (!strcmp(argv[i], "--soname"))
+ {
+ if (argc <= i + 1
+ || argv[i + 1][0] == '-')
+ return false;
+ opts.soname = argv[i + 1];
+ ++i;
+ }
else if (!strcmp(argv[i], "--version")
|| !strcmp(argv[i], "-v"))
{
@@ -887,8 +897,37 @@ read_corpus(options opts,
retval = rdr->read_corpus(status);
}
break;
- case abigail::tools_utils::FILE_TYPE_AR:
case abigail::tools_utils::FILE_TYPE_XML_CORPUS_GROUP:
+ {
+ if (opts.soname.empty())
+ {
+ cout << "No SONAME provided.\n";
+ return NULL;
+ }
+
+ corpus_group_sptr grp;
+ rdr = abixml::create_reader(path, env);
+ assert(rdr);
+ grp = abixml::read_corpus_group_from_input(*rdr);
+ cout << "Searching for soname " << opts.soname << " ...";
+ for (corpus_group::corpora_type::const_iterator i =
+ grp->get_corpora().begin();
+ i != grp->get_corpora().end();
+ ++i)
+ {
+ corpus_sptr c = *i;
+ if (c->get_soname().compare(opts.soname) == 0)
+ {
+ cout << " found.\n";
+ retval = c;
+ break;
+ }
+ }
+ if (!retval)
+ cout << "not found.\n";
+ }
+ break;
+ case abigail::tools_utils::FILE_TYPE_AR:
case abigail::tools_utils::FILE_TYPE_RPM:
case abigail::tools_utils::FILE_TYPE_SRPM:
case abigail::tools_utils::FILE_TYPE_DEB:
--
2.50.1
More information about the Libabigail
mailing list