$$$$$$$$$$$$$$$$$$$
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:
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:
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
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();
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.
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");
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)
? 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;
}
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.
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 \
--- /dev/null
+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
+
+
--- /dev/null
+[suppress_file]
+ soname_regexp = test48<typo>-soname-abixml-v.*
--- /dev/null
+[suppress_file]
+ file_name_regexp = ^libtest48-soname-abixml-v.*$
--- /dev/null
+[suppress_file]
+ file_name_regexp = ^libtest48<typo>-soname-abixml-v.*$
--- /dev/null
+[suppress_file]
+ soname_regexp = test48-soname-abixml-v.*
--- /dev/null
+<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>
--- /dev/null
+<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>
--- /dev/null
+struct S
+{
+ int m0;
+};
+
+void
+foo(struct S *a __attribute__((unused)))
+{}
--- /dev/null
+struct S
+{
+ int m0;
+ char m1;
+};
+
+void
+foo(struct S *a __attribute__((unused)))
+{}
"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}
};