Commit Graph

2772 Commits

Author SHA1 Message Date
Dodji Seketeli f068f4a98f doc/manuals/libabigail-concepts.rst: Fix typo
* doc/manuals/libabigail-concepts.rst: Fix a typo in the doc for
	the "end" named boundary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-05 17:09:45 +02:00
Dodji Seketeli a6108e69e4 abg-comparison[-priv]: Better detection of incompatible unreachable type changes
Whenever there is a change in unreachable type,
corpus_diff::has_incompatible_changes always reports that the
corresponding diff node carries an incompatible change.  It does this
even if the change is known to be compatible.

To be able to say if a diff node for a unreachable type carries a
compatible (not incompatible) change,
corpus_diff::has_incompatible_changes must look at the change category
of that diff node, instead of saying that any change to an unreachable
type is incompatible.

While looking at this, I noted that
corpus_diff::priv::apply_filters_and_compute_diff_stats doesn't
categorize the diffs in
corpus_diff::priv::changed_unreachable_types_, so it's not possible to
look at the categories of the changes held by that data member to see
if they are incompatible or not.

This patch thus categorizes the diff nodes held by
corpus_diff::priv::changed_unreachable_types_ and makes
corpus_diff::has_incompatible_changes look at those diff nodes to
detect if they are incompatible.

Let's see the result of this patch.

Consider the change in the input test source code from included in
this patch, from test-enumerator-changes1-v0.c to test-enumerator-changes1-v1.c:

    $ diff -u test-enumerator-changes1-v0.c test-enumerator-changes1-v1.c
    --- test-enumerator-changes1-v0.c	2023-10-04 11:25:30.722989530 +0200
    +++ test-enumerator-changes1-v1.c	2023-10-04 11:25:30.722989530 +0200
    @@ -1,13 +1,14 @@
     /*
      *
      * Compile this with:
    - *    gcc -g -c -fno-eliminate-unused-debug-types test-enumerator-changes1-v0.c
    + *    gcc -g -c -fno-eliminate-unused-debug-types test-enumerator-changes1-v1.c
      */

     enum foo
       {
	 E1_O,
    -    E1_1
    +    E1_1,
    +    E1_2
       };

     void
    $

The enumerator E1_2 has been added to the 'foo' enum.

Now, let's see what abidiff prior to this patch would say about the
change between the two result binaries test-enumerator-changes1-v0.o
and test-enumerator-changes1-v1.o:

    $ abidiff --non-reachable-types --harmless test-enumerator-changes1-v0.o test-enumerator-changes1-v1.o || echo "return value: $?"
    Functions changes summary: 0 Removed, 0 Changed, 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
    Unreachable types summary: 0 removed, 1 changed, 0 added type

    1 changed type unreachable from any public interface:

      [C] 'enum foo' changed:
	type size hasn't changed
	1 enumerator insertion:
	  'foo::E1_2' value '2'

    return value: 12
    $

See the return value of 12, that is actually the bits
abigail::tools_utils::ABIDIFF_ABI_CHANGE (of value 4) and
abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE (of value 8) being set.

Normally, only the bit abigail::tools_utils::ABIDIFF_ABI_CHANGE (of
value 4) should be set.

Now, let's look at what abidiff says with this patch:

    $ abidiff --non-reachable-types --harmless test-enumerator-changes1-v0.o test-enumerator-changes1-v1.o || echo "return value: $?"
    Functions changes summary: 0 Removed, 0 Changed, 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
    Unreachable types summary: 0 removed, 1 changed, 0 added type

    1 changed type unreachable from any public interface:

      [C] 'enum foo' changed:
	type size hasn't changed
	1 enumerator insertion:
	  'foo::E1_2' value '2'

    return value: 4
    $

Now the return value is 4, which is the bit
abigail::tools_utils::ABIDIFF_ABI_CHANGE being set, as we would expect
because that change is known to be not incompatible.

	* Src/abg-comparison-priv.h
	(corpus_diff::priv::changed_unreachable_types): Declare ...
	* src/abg-comparison.cc
	(corpus_diff::priv::changed_unreachable_types): ... new function.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Walk
	the nodes returned by corpus_diff:priv::changed_unreachable_types
	and apply the filters (including categorization filters) to them.
	Also make the loop similarly applying filters to the nodes
	returned by corpus_diff::priv::changed_unreachable_types_sorted be
	a ranged-based one, for the sake of consistency.
	(corpus_diff::has_incompatible_changes): Now that diff nodes
	returned by corpus_diff::priv::changed_unreachable_types are
	categorized, look at their change categories to see if they are
	incompatible or not.
	* tests/data/test-abidiff-exit/test-enumerator-changes1-report-1.txt:
	New test output reference.
	* tests/data/test-abidiff-exit/test-enumerator-changes1-v{0,1}.o:
	New test input binaries.
	* tests/data/test-abidiff-exit/test-enumerator-changes1-v{0,1}.c:
	New source code for the new test input binaries.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new test
	input binaries to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-04 12:15:24 +02:00
Dodji Seketeli 46e80debd6 comparison: Always apply filters on the diff graph
When looking at something else, I noticed that
diff_context::maybe_apply_filters doesn't apply the filters (i.e, the
various passes) on the diff graph if all the categories of changes are
allowed, typically when --harmless is passed to abidiff.

This is wrong because even if all the categories are allowed, the
changes carried by nodes of the diff graph should still be
categorized.  This was an early optimization dating back from the
times where the filtering was slow.

	* src/abg-comparison.cc (diff_context::maybe_apply_filters): Do
	not get out when all the categories of diff changes are allowed.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-03 11:08:53 +02:00
Dodji Seketeli 023d28abb4 ir: Fix output of 'debug(enum-type)'
The output of calling the debug function on an enum type wrongly says
that we are looking at a union.  Ooops.  Fixed thus.

	* src/abg-ir.cc (get_debug_representation): Don't say 'union' when
	we are looking at an enum.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-03 11:08:53 +02:00
Dodji Seketeli 528ed9fe55 test-abidiff-exit: Do not use debuginfo dir when its empty
If the debug info dir is empty in the input test specifier, the abidiff
command should not add any --debug-info-dir{1,2} option.  Fixed thus.

	* tests/test-abidiff-exit.cc (main): If debug info dir is empty in
	the input test specifier, do not try to use it in the abidiff
	command.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-03 11:08:53 +02:00
Dodji Seketeli 727452167e libabigail-concepts.rst: Remove trailing white spaces
* doc/manuals/libabigail-concepts.rst: Remove trailing white
	spaces.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-02 23:24:21 +02:00
Dodji Seketeli d304f4d501 libabigail-concepts.rst: Sort the properties of the directives
In documentation for the suppression directives, the properties of the
directives were not sorted, making it hard to look
for a particular one.

This patch sorts the properties in the lexicographic order.

	* doc/manuals/libabigail-concepts.rst: Sort the properties in the
	lexicographic order.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-10-02 12:08:09 +02:00
Dodji Seketeli 457f5cb202 configure,test-diff-pkg.cc: Handle symlinks presence in dist tarball
Since the commit below, there are tests that require symbolic links.

Unfortunately, the tar command used to construct tarballs copies the
target of a symbolic link (and thus doesn't keep the symlink) for the
purpose of greater portability, as some platforms don't support
symbolic links.

This patch uses a tar command that keeps the symlinks in place for the
tests introduced by the commit below to keep working.  On some
platforms however, symlinks are removed from the tarball no matter
what.  In those case, the test that needs symlinks is disabled.

Here is the commit in question:

    bad389f abipkgdiff: Avoid comparing binaries that are outside of the package

	* configure.ac: Use "tar -cf" instead of "tar -chf" to construct
	the tarball.  Detect if the presence of the symlink in the
	distribution and define the WITH_SYMLINKS_KEPT_IN_DIST
	preprocessor macro accordingly.
	* tests/test-diff-pkg.cc (in_out_specs): If symlinks are not
	present in the tarball then the test that requires symlinks is
	deactivated.  Also, fix the
	data/test-diff-pkg/symlink-dir-test1/dir1 test to make it point to
	the target of the symlinks directly, to avoid considering a binary
	twice, in cases where symlink targets are copied.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-20 13:07:30 +02:00
Dodji Seketeli 831b59a83f elf-reader, ir: Fix compilation on GCC 4.8.5
* src/abg-elf-reader.cc (reader::initialize): Use older-style
	initialization to keep the old lady happy.
	* src/abg-ir-priv.h (canonicalize_types): Avoid using type
	deduction in this context to keep the old lady happy.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-20 10:57:39 +02:00
Dodji Seketeli 2f61188d43 dwarf-reader: Do not re-use typedefs in a scope
Sometimes, two typedefs of the same name can appear at the same scope
but point to different types, in DWARF.  Unbelievable but true.  In
those case, we do not want to re-use the typedef, obviously, as we can
possibly misrepresent the type graph in that case.

This fixes one self-comparison issue for the x86_64 sub-package of the
gcc-gnat package that is tested by doing:

    $ fedabipkgdiff --self-compare  -a --from fc37 gcc-gnat

	* src/abg-dwarf-reader.cc (build_ir_node_from_die): Do not re-use
	a typedef from a given scope.
	* src/abg-reader.cc (build_typedef_type): Do not re-use typedefs
	with the same ID.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:39 +02:00
Dodji Seketeli 56e583a792 ir: Fix qualification as non-confirmed propagated canonical types
While looking at something else, there are some types considered
having "non-confirmed propagated canonical type", even though those
types are not even canonical-type-propagated.  This patch fixes that.

That doesn't have any visible impact, but it's definitely more
correct.

	* src/abg-ir.cc (return_comparison_result): A type that doesn't
	have propagated canonical type can't be considered having
	"non-confirmed propagated canonical type".

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:39 +02:00
Dodji Seketeli d8de76cfa8 ir: Use non qualified typedef name for type canonicalization
While looking into fixing self-comparison errors for the gcc-gnat
package[1], I stumbled upon the fact that a typedef that is defined in
the global scope is different from a typedef defined in a scope, even
if they both point to the same underlying type.  This is a spurious
difference that feeds a spurious explosion of the number of canonical
types, for no reason.  It can lead to spurious self-comparison errors
down the road.  Sadly, fixing this issue is not enough to fix the
self-comparison error in [1].

[1]: The command is:

    $ fedabipkgdiff --self-compare  -a --from fc37 gcc-gnat

	* include/abg-ir.h (reference_type_def::{pointed_to_type_,
	is_lvalue_}): Remove these data members.
	(reference_type_def::priv_): Add a unique data member.
	(typedef_decl::get_qualified_name): Add new virtual member
	functions.
	* src/abg-ir.cc (get_decl_name_for_comparison): If the decl we are
	comparing is a typedef, only consider its non-qualified name.
	(get_type_name): For internal purposes, the type name of a typedef
	is its non-qualified name.
	(pointer_type_def::get_qualified_name): For internal purposes, if
	the pointed-to name is a typedef, use the non-qualified name of
	the typedef.
	(reference_type_def::priv): Define new data type.
	(reference_type_def::reference_type_def): Initialize the new
	reference_type_def::priv_ data member and adjust to the move of
	the reference_type_def::pointed_to_type_ data member to
	reference_type_def::priv::pointed_to_type_.
	(reference_type_def::{s,g}et_pointed_to_type): Adjust.
	(reference_type_def::is_lvalue): Likewise.
	(reference_type_def::get_qualified_name): Support caching
	qualified names for internal and non-internal purposes.
	(typedef_decl::get_pretty_representation): For internal purposes,
	use non-qualified typedef name.
	(typedef_decl::get_qualified_name): Define the two overloads for
	this virtual member function.
	(function_decl::get_pretty_representation): Use the
	'qualified_name' parameter.  Also, rather than systematically
	using the qualified name of the return type, use get_type_name
	instead that knows when to use qualified names and when not to.
	(qualified_name_setter::do_update):
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 0239f89b4f ir: Really avoid canonicalizing decl-only classes
is_non_canonicalized_type uses is_declaration_only_class_or_union_type
to detect decl-only classes, but it doesn't differentiate between
decl-only classes that are associated to a class definition and those
that are not.

We want to avoid canonicalizing decl-only classes that are not
associated to any class definition.

This patch fixes the invocation of
is_declaration_only_class_or_union_type to express the above
assertion.

This fix uncovered another self-comparison issue that was being
expressed when running the command below:

    $ abidw --abidiff tests/data/test-types-stability/PR27086-libstdc++.so.6.0.26

That one was due to an error in method_decl::set_linkage_name which
was making classes contain the wrong overloads of methods.  The patch
fixes that error too.

	* include/abg-fwd.h (is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type): Remove declarations.
	(is_typedef_ptr_or_ref_to_decl_only_class_or_union_type): Declare
	new function.
	* src/abg-ir.cc (is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type): Remove definitions.
	(is_typedef_ptr_or_ref_to_decl_only_class_or_union_type): Define
	new function.
	(is_non_canonicalized_type): Change the invocation of
	is_declaration_only_class_or_union_type to make it look through
	decl-only types.  Use
	is_typedef_ptr_or_ref_to_decl_only_class_or_union_type in lieu of
	is_{pointer,reference,typedef}_to_decl_only_class_or_union_type
	that got removed.
	(method_decl::set_linkage_name): Remove the mapping between the
	method and the old linkage name, only if the old name is different
	from the new name.  Duh.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 0447eb27aa ir: Avoid forgetting potential seemingly duplicated member functions
In some rare cases expressed in DWARF from C++, a member function can
belong to both a declaration-only class (having no data member) in one
translation unit, and to a fully defined class in another translation
unit.  In those cases, the two classes are represented and considered
different.

But then, consider a destructor which mangled name is "D1".  D1 is
represented in both the decl-only class and the fully-defined class.
In the former case, its "this pointer" points to a decl-only class,
while in the later case its "this pointer" points a fully-defined
class.

So, D1 coming from the former case will compare different from the D1
coming from the later case, because of the spurious difference
"decl-only class" versus "fully-defined class".  This is in the
context of a self-comparison.

One way to fix this self-comparison subtle change is to give the
former D1 and the later D1 two different "function ID"s.  Today, the
function ID is just the mangled name, D1.  This patch is defining a
more involved ID which makes the difference between a member function
on a decl-only class and a member function on a fully-defined class.

Note that the only member functions that matter are virtual member
functions because they are the only member functions that are
considered when comparing two classes.

This fixes the self-comparison error found on the binary
gcc-gnat-12.3.1-1.fc37.x86_64/usr/libexec/gcc/x86_64-redhat-linux/12/gnat1
while running the self-comparison command below:

    $ fedabipkgdiff --self-compare -a --from fc37 gcc-gnat

	* src/abg-ir.cc (is_declaration_only_class_or_union_type): Add an
	overload for type_base_sptr.
	(function_decl::get_id): Virtual member functions that are defined
	on decl-only classes have a special ID to avoid confusing them
	with their counterparts defined on defined classes.
	* src/abg-reader.cc (build_function_decl)
	(build_function_decl_if_not_suppressed): Add a new
	add_to_exported_decls parameter to avoid adding the function to
	the set of exported decls to early.  For the function to be
	properly added to the set of exported decls, all its attributes
	must be set, including virtualness.  In some case, those
	attributes are not yet known by the end of the call to
	build_function_decl.  The caller must then set those properties
	and then add the function to the set of exported decls.
	(build_{class,union}_decl): Build the function first, then add its
	missing properties and *then* add it to the set of exported decls.
	(handle_function_decl): Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 59193e6942 ir: Fix forgetting canonicalizing some function types
It appears some function types are not canonicalized. Fixed thus.

	* src/abg-ir.cc (maybe_adjust_canonical_type): Once a missing
	member function has been copied from it's destination to the
	freshly canonicalized type, make sure the type of the member
	function is canonicalized as well.
	(copy_member_function): Bind the lifetime of the new function type
	to the lifetime of the current translation unit.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli e54349b096 ir: Add fn types to type lookup maps
This is a fix to an inconsistency I stumbled upon while looking at
something else.

So, function types were not being added to the type lookup maps.
Fixed this.

	* src/abg-ir.cc (maybe_update_types_lookup_map): Handle function
	types.
	(translation_unit::bind_function_type_life_time): Update types
	lookup map.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 2a8913fdd9 ir: Add missing ABG_RETURN in the comparison engine
During structural type comparison, we want to be able to break on the
first occurrence of two sub-types comparing different.  This is done
by setting a breakpoint into the notify_equality_failed function that
is called by the ABG_RETURN macro in the comparison functions.

The problem is that I stumbled upon some code paths that are missing
the ABG_RETURN macro.  Fixed thus.  This will help in debugging
sessions.

	* src/abg-ir.cc (equals): In the overload for function_type,
	class_decl and union_decl, add a missing ABG_RETURN.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli bad389f01a abipkgdiff: Avoid comparing binaries that are outside of the package
Some symlinks in some RPMs resolve to binaries outside of the package. In
those cases, avoid considering them.

	* src/abg-tools-utils.cc (maybe_get_symlink_target_file_path): Do
	not require that the file path points to a symlink.  A file path
	can point to a file that is not a symlink and yet the whole path
	can be in parent directory that is a symlink.  In this case,
	realpath will correctly resolve to the correct target file.
	* tools/abipkgdiff.cc (maybe_update_package_content): A path to a
	binary that is not inside the RPM (because a symlink resolved to a
	file outside of the RPM) should not be added to the set of
	binaries to be analyzed.
	* tests/data/test-diff-pkg/symlink-dir-test1-report1.txt: Add new
	test file.
	* tests/data/test-diff-pkg-ctf/symlink-dir-test1-report1.txt:
	Likewise.
	* tests/data/Makefile.am: Add new test file to source
	distribution.
	* tests/test-diff-pkg.cc (in_out_specs): for the
	data/test-diff-pkg/symlink-dir-test1/dir{1,2}/symlinks test, the
	root dir of the package is
	data/test-diff-pkg/symlink-dir-test1/dir{1,2}.  Use that to test
	that the symlinks are properly handled.  Also, use the
	data/test-diff-pkg/symlink-dir-test1/dir{1,2}/symlinks as a root
	of an alternative package for which the symlinks resolve outside
	the package, under
	data/test-diff-pkg/symlink-dir-test1/dir{1,2}/targets.  In this
	later case, the symlinked files should be ignored in the
	comparison.  Likewise for
	data/test-diff-pkg-ctf/symlink-dir-test1/dir1/symlinks.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 61a6f5fc1c {dwarf,elf}reader: Don't consider no symbol table as an error
Some binaries don't have any symbol table.  Libabigail's ELF and DWARF
readers error out on those binaries, making fedabipkgdiff emitting an
error when performing the self-comparison of the package containing
those binaries.

This patch handles a binary having no symbol table almost as a binary
that has an empty symbol table, making abipkgdiff and fedabipkgdiff
not error out on those binaries anymore.

This makes the command below succeed:

    $ fedabipkgdiff --self-compare -a --from fc34 glibc

	* src/abg-dwarf-reader.cc (reader::read_corpus): Return an empty
	corpus if no symbol was found. Do not crash when no symbol table
	is found.
	* src/abg-elf-reader.cc (reader::read_corpus): Consider a corpus
	with no symbol table as being OK.
	* src/abg-reader.cc (build_elf_symbol_from_reference): Do not
	crash when no symbol table is present.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 4a7416ade4 tools-utils: Avoid endless loop
* src/abg-tools-utils.cc (is_dir): Avoid endless loop.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 4071543456 abipkgdiff: Initialize libxml2 to use it in a multi-thread context
While running some test, I stumbled upon a transient deadlock
happening when using libxml2's text reader to create a reader from a
buffer.  After reading the documentation at
https://gitlab.gnome.org/GNOME/libxml2/-/wikis/Thread-safety, I
realized that users of the library need to initialize libxml2 before
using it in a multi-thread setting.

So this patch is providing the abigail::tools_utils::initialize()
function to be called prior to using the library.  This is going to be
the place where to perform this kind of one-time initialization.

	* include/abg-tools-utils.h (initialize): Declare ...
	* src/abg-tools-utils.cc (initialize): ... new function.
	* tools/abipkgdiff.cc (main): Invoke the new
	abigail::tools_utils::initialize() here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 3292453ee3 dwarf-reader: Fix some logging
* src/abg-dwarf-reader.cc
	(reader::{read_debug_info_into_corpus,
	canonicalize_types_scheduled}): Add missing new lines and spaces.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli ee9a4d085e dwarf-reader,ir: Make logging a property of the middle end
Add a "do-log" property to the abigail::ir::environment::priv.  That
way, we can log finer grain time stamps during type canonicalization.
This is useful for debugging.

	* src/abg-dwarf-reader.cc (reader::read_debug_info_into_corpus):
	Set the do_log property on the environment from the do_log
	property of the reader.
	* src/abg-ir-priv.h (environment::priv::do_log_): New data member.
	(environment::priv::priv): Initialize it.
	(environment::priv::do_log): Define new accessor method.
	(canonicalize_types): Add logging.
	* src/abg-ir.cc (canonicalize): Add logging to time the
	canonicalization of each type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli d4f50b2bea tools-utils: Fix indentation
* src/abg-tools-utils.cc (string_suffix): Fix indentation.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Dodji Seketeli 953e986769 reader: fix indentation
* src/abg-reader.cc (build_function_type): Fix indentation.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:23:38 +02:00
Giuliano Procida 9ac01c4141 operator!= fixes for C++-20
Without these changes, more recent versions of Clang will start to
emit diagnostics:

src/abg-ir.cc:15407:13: error: member 'operator!=' found in multiple base classes of different types
 15407 |   return *l == *r;
       |             ^
src/abg-ir.cc:14123:12: note: member found by ambiguous name lookup
 14123 | type_base::operator!=(const type_base& other) const
       |            ^
src/abg-ir.cc:5162:12: note: member found by ambiguous name lookup
 5162 | decl_base::operator!=(const decl_base& other) const
      |            ^

This fix was contributed by Ilya Biryukov.

	* include/abg-ir.h
	(qualified_typedef): Add definition of operator!=.
	(pointer_type_def): Likewise.
	(reference_type_def): Likewise.
	(class_or_union): Likewise.

Reported-by: Ilya Biryukov <ibiryukov@google.com>
Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-09-07 15:22:44 +02:00
Dodji Seketeli 320ab7fdab ir: Remove an unnecessary comparison
When looking at something else, I noticed that in
method_decl::set_linkage_name, we are unnecessarily testing if the
'this' pointer was equal to the pointer to the member function decl of
a member function looked up from the parent class.

This patch replaces that condition by an assert.  If the 'this'
pointer is different from the pointer to any member function decl
looked up from the parent class, then something is terribly wrong
about the integrity of the IR.

	* src/abg-ir.cc (method_decl::set_linkage_name): Assert that the
	'this' pointer always equals the pointer to any member function
	decl looked up from the parent class.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-11 12:30:56 +02:00
Dodji Seketeli 6424bb29cf reader: Fix a long standing Thinko
While looking at something else, I realized that member functions XML nodes
were not necessarily mapped to the right function declaration at
ABIXML parsing time.  Woops.

Fixed thus.

	* src/abg-reader.cc (build_class_decl): Map the XML node for the
	member function to the member function decl, not to the class
	decl.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-11 12:30:56 +02:00
Yaakov Selkowitz 33f64461bf Fix fedabipkgdiff configure check for Python 3.12
importlib is the Python 3 replacement to imp, which was deprecated in
Python 3.4 and removed in 3.12.

	* configure.ac (REQUIRED_PYTHON_MODULES_FOR_FEDABIPKGDIFF):
	Test for importlib.machinery instead of imp with python3.

Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-10 09:40:23 +02:00
Dodji Seketeli 0b338dfaf6 abidiff: Add --{follow,list}-dependencies & add-binaries{1,2} support
This patch implements comparing two sets of binaries constituted by the
binaries given in argument of the abidiff command, as well as their
respective dependencies (specified by the DT_NEEDED ELF property for
ELF binaries) or an arbitrary set of libraries found in the
directories determined by --added-binaries-dir{1,2}.

The detected dependencies can also be listed by the option
--list-dependencies.

	* tools/abidiff.cc (options::{follow_dependencies,
	list_dependencies, added_bins_dirs1, added_bins_dirs2,
	added_bins1, added_bins2}): Add new data members.
	(options::options): Initialize the new follow_dependencies and
	list_dependencies boolean data members.
	(display_usage): Add usage strings for --added-binaries-dir{1,2},
	--add-binaries{1,2}, --follow-dependencies, --list-dependencies.
	(parse_command_line): Parse the options --follow-dependencies,
	--list-dependencies, --added-binaries-dir{1,2},
	--add-binaries{1,2}.
	(display_dependencies): Add new static function.
	(main): Support the new --add-binaries{1,2},
	--follow-dependencies, --list-dependencies.
	* doc/manuals/abidiff.rst: Document the new options above.
	* tests/data/test-abidiff-exit/test-PR30034/libabigail.abignore: Add test input.
	* tests/data/test-abidiff-exit/test-PR30034/reference/include/rte_log.h:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_eal.so.23.1:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_kvargs.so.23.1:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/reference/lib64/librte_telemetry.so.23.1:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/include/rte_log.h:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_eal.so.23.2:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_kvargs.so.23.2:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_log.so.23.2:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/split/lib64/librte_telemetry.so.23.2:
	Likewise.
	* tests/data/test-abidiff-exit/test-PR30034/test-PR30034-report-1.txt:
	Likewise.
	* tests/data/Makefile.am: Add the test inputs to source
	distribution.
	* tests/test-abidiff-exit.cc
	(InOutSpec::in_elfv{0,1}_added_bins_dir): Add new data member.
	(main): Add --added-binaries-dir{1,2} option to abidiff if the
	InOutSpec::in_elfv{0,1}_added_bins_dir data members are non-empty.
	(in_out_specs): Add test inputs to this test
	harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:51 +02:00
Dodji Seketeli 3e568fef6b abidw: Add --{follow,list}-dependencies & --add-binaries support
This implements the --follow-dependencies , --list-dependencies,
--add-binaries <foo,bar,...> and --added-binaries-dir options for the
abidw command, as documented in the
README-ABIDIFF-BINARIES-SET-SUPPORT.md file.

	* tools/abidw.cc (options::{added_bins_dirs, added_bins,
	follow_dependencies, list_dependencies}): Add new data members.
	(options::options): Initialize follow_dependencies and
	list_dependencies.
	(display_usage): Add usage strings for --add-binaries,
	--follow-dependencies, --list-dependencies, --added-binaries-dir.
	(parse_command_line): Parse options --add-binaries,
	--follow-dependencies, --list-dependencies, --added-binaries-dir.
	(load_corpus_and_write_abixml): Implement the --list-dependencies,
	--follow-dependencies and --add-binaries sub-commands.
	* doc/manuals/abidw.rst: Document the --add-binaries,
	--follow-dependencies, --list-dependencies, --added-binaries-dir
	options.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:47 +02:00
Dodji Seketeli a30a3146b5 corpus,tools-utils: Support loading a corpus, its deps & other binaries
In preparation of implementing the support for "Handling split
libraries", this patch implements the functions
tools_utils::{get_comma_separated_args_of_option,
find_file_under_dirs, add_binaries_into_corpus_group,
add_dependencies_into_corpus_group,
stick_corpus_and_binaries_into_corpus_group,
stick_corpus_and_dependencies_into_corpus_group, get_dependencies}.

Given an ABI corpus, these functions enable adding arbitrary binaries
and dependencies found in a set of directories to form a corpus group.

	* include/abg-corpus.h (corpus_group::has_corpus): Declare new
	member function.
	* include/abg-tools-utils.h (get_comma_separated_args_of_option)
	(find_file_under_dirs, get_dependencies)
	(add_binaries_into_corpus_group)
	(add_dependencies_into_corpus_group)
	(stick_corpus_and_binaries_into_corpus_group)
	(stick_corpus_and_dependencies_into_corpus_group): Declare new
	functions.
	* src/abg-corpus.cc (corpus_group::priv::corpora_path): Add new
	data member.
	(corpus_group::add_corpus):  Do not add a corpus that was already
	added to the group.  Update the set of paths of added corpora so
	that we can detect if a corpus has already been added.
	* src/abg-tools-utils.cc (find_file_under_dir): If the file found
	is a symbolic link, return it.  Otherwise if the symbolic link is
	not the file we were looking for, then skip it, rather than
	following it, in case it's a directory.
	(get_comma_separated_args_of_option, find_file_under_dirs)
	(get_dependencies, add_binaries_into_corpus_group)
	(add_dependencies_into_corpus_group)
	(stick_corpus_and_binaries_into_corpus_group)
	(stick_corpus_and_dependencies_into_corpus_group): New functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:39 +02:00
Dodji Seketeli e8a61b1af2 Make fe_iface::initialize independent from the kind of interface
In the use case laid out by the "Library Splitting support" at
https://sourceware.org/bugzilla/show_bug.cgi?id=30034, tools might
want to be able to re-initialize a given front-end to load several
corpora in a row, independently from the kind of front-end (elf-based,
ABIXML, etc).  So we need a fe_iface::initialize() interface that is
similar to the elf_based_reader::initialize() interface but, unlike
that one, it should not depend on parameters that only make sense in a
elf-based context.  For instance, the fe_iface::initialize() interface
should not contain paths to debug-info as that information does not
make sense in an ABIXML context.

This patch thus renames fe_iface::reset() into fe_iface::initialize()
and makes it virtual.  It adjusts the plumbing accordingly, basically
making the other ::initialize() methods of classes that inherit
fe_iface use fe_iface::initialize() when appropriate.

The patch also provides an elf_based_reader::initialize()
implementation of the fe_iface::initialize() interface, so that
invoking ::initialize on elf_based_reader through the fe_iface
interface does the right thing so that the initial use case presented
at the beginning of this comment is supported.

	* include/abg-elf-based-reader.h (elf_based_reader::initialize):
	Rename elf_based_reader::reset into this.  Add a new virtual
	overload that implements fe_iface::initialize.
	* include/abg-elf-reader.h (reader::initialize): Rename
	elf_reader::reset into this.  Add a new virtual overload that
	implements fe_iface::initialize.
	* include/abg-fe-iface.h (fe_iface::initialize): Rename
	fe_iface::reset into this and make it virtual.
	* src/abg-btf-reader.cc (btf::reader::initialize): Adjust call to
	elf_based_reader::reset to elf_based_reader::initialize.
	* src/abg-ctf-reader.cc (ctf::reader::initialize): Likewise.
	* src/abg-dwarf-reader.cc (dwarf::reader::initialize): Likewise.
	* src/abg-elf-based-reader.cc (elf_based_reader::initialize):
	Rename elf_based_reader::reset into this.  Adjust call to
	elf::reader::reset into elf::reader::initialize.  Add a new
	virtual overload that implements fe_iface::initialize.
	* src/abg-elf-reader.cc (reader::initialize): Rename
	elf::reader::reset into this. Adjust call to fe_iface::reset into
	fe_iface::initialize.  Add a new virtual overload that implements
	fe_iface::initialize.
	* src/abg-fe-iface.cc (fe_iface::priv::initialize): Reset the
	corpus too.
	(fe_iface::initialize): Rename fe_iface::reset into this.  Invoke
	priv::initialize and set the new corpus_path.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:15 +02:00
Dodji Seketeli 3c68b44ea4 fedabipkgdiff: Fix previous commit
In the previous commit, I wrongly assumed that all Brew koji session objects
have a an "opts" attribute.  Fixed thus.

	 * tools/fedabipkgdiff (Brew::__init__): Do not try to access the
	'opts' attribute on sessions that don't have any.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-06 16:03:22 +02:00
Dodji Seketeli 08f23feaa4 fedabipkgdiff: Don't choke Koji servers with self-signed SSL certs
When doing some tests on particular Koji instances, the
Brew::getPackage function was choking because its underlying http
client would could not verify the self-signed SSL certificate used by
the server.

This patch sets the default option of the client so that it avoids
verifying SSL certificates altogether.

	* fedabipkgdiff (Brew::__init__): Se the "no_ssl_verify" option to
	false by default.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-06 12:37:40 +02:00
Dodji Seketeli a69bbac706 Bug 30461 - insight fails self-compare
This self-comparison issue is due to several different underlying
problems.

Class destructors are often implemented by the compiler using cloned
functions, even for virtual destructors.  In DWARF, for a given class,
the cloned function implementing the virtual destructor might come way
after the point where the class and its member functions (including
the destructors) have been declared.  So the DWARF reader needs to
match the "dangling" cloned function that implements the virtual
destructor with the destructor declared in the class declaration.
Note that it's the cloned definition that contains the address of the
ELF symbol for the destructor, not the declaration.  So we really need
to see the cloned function to build a proper IR (that also represents
the ELF symbol) for the destructor.

As the destructor is implemented by a cloned function, we might see
(in the DWARF) other clones of that function that have the same
linkage name.  In that case, if the IR of the class already has a
destructor with the same linkage name, then we not build another IR
for it, otherwise we'd wrongly duplicate the destructor.  And this is
exactly the error we were doing in this issue.  This patch addresses
that issue.

The ABIXML does unfortunately have classes with duplicated
destructors, due to this.  So as the DWARF reader is now going to be
fixed, the ABIXML reader also needs to be fixed to avoid reading
duplicated member functions.  The patch addresses that issue as well.

Then, when the above was fixed, I stumbled across an issue related to
type fundamentals of type canonicalization:

I think we will ultimately need to be able to canonicalize types in
the same order, if they come from DWARF or ABIXML.  It now appears to
me that because of recursive types in the context of ODR-violations
(two different types being present in different translation units and
yet having the same name.  For instance, the BFD type from binutils
and this insight package), type canonicalization is not a commutative
operation, unfortunately.  That is why we need to either store some
type hash in ABIXML to avoid having to re-do type canonicalization
when reading ABIXML, or canonicalize types coming from ABIXML in the
same order as they were, when they came from their initial format
(DWARF or otherwise).  This would be a project in it own right.  Until
then, a workaround that seems to be enough in this case is to clear
the type comparison result cache after canonicalizing each type.

The rest of the patch adjusts the regression tests output as needed.

For the record, below is the command line that triggered the issue:

    $ fedabipkgdiff --debug --self-compare -a --from fc38 insight

	* src/abg-dwarf-reader.cc (build_ir_node_from_die): If we are
	looking at a cloned function that's a member function to be added
	to an existing class, make sure a member function with the same
	linkage name doesn't already exist in the class before adding this
	one.  Otherwise, we'd be duplicating a member function inside the
	class.
	* src/abg-ir.cc (method_decl::set_linkage_name): When setting the
	linkage name of a method to a new one, erase the old method that
	had the old linkage name from the containing class.
	(compare_canonical_type_against_candidate): Clear the comparison
	type result cache after each type canonicalization to avoid
	re-using cached result that should have been invalidated.  This is
	a work-around the more fundamental type canonicalization issue
	outlined in the preamble of this commit log.
	* src/abg-reader.cc (build_function_decl): Avoid loading
	duplicated member functions.  The key of the function being its
	mangled name.
	(build_class_decl): The XML node to map when looking a member
	function is really the XML node for the member function.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-22 09:07:04 +02:00
Matthias Maennich c22bc178b1 symtab reader: fix symtab iterator to support C++20
Inheriting from std::vector::iterator causes the type to advertise
itself as a contiguous iterator. This causes a compilation error in
newer versions of libc++ that try to use contiguous-iterator-specific
optimizations in those situations. Fixed thus by explicitly specifying
the interator_concept tag.

	* abg-symtab-reader.h (symtab_iterator): Specify
	  iterator_concept as forward_iterator to support C++20 compilation.

Signed-off-by: Matthias Maennich <maennich@google.com>
2023-06-07 16:08:43 +02:00
Matthias Maennich 9ea703c2d2 symtab reader: use C++11 `using` syntax instead of typedefs
That is to increase readability and to incrementally modernize the code base.

	* abg-symtab-reader.h: replace typedefs by corresponding using
	  declarations.

Signed-off-by: Matthias Maennich <maennich@google.com>
2023-06-07 16:08:05 +02:00
Dodji Seketeli 7b565f399e Bug 30503 - Fail to compare non-anonymous struct vs named struct data members
Since this commit

    commit 321da66678
    Author: Dodji Seketeli <dodji@redhat.com>
    Date:   Tue Sep 14 18:11:39 2021 +0200

	Bug 28316 - Failure to represent typedef named anonymous enums

It seems like comparing a data member of a non-anonymous struct foo
against the same data member of an anonymous struct named by a typedef
foo wrongly leads yields a spurious difference.

This is because when looking at the data member,
get_decl_name_for_comparison doesn't return the same value in the two
cases (non anonymous struct foo vs anonymous struct named by a typedef
foo).  Looking deeper, it's because get_decl_name_for_comparison
wronly uses scope_anonymous_or_typedef_named.  Fixed thus.

	* src/abg-ir.cc (get_decl_name_for_comparison): Do not use
	scope_anonymous_or_typedef_named.  Rather, use
	decl_base::get_has_anonymous_parent instead.
	(scope_anonymous_or_typedef_named): Remove this as it's not used
	anymore.
	* include/abg-fwd.h (scope_anonymous_or_typedef_named): Remove
	this declaration as the definition has been removed.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.60/lib64/libSDL-1.2.so.1.2.60:
	New test input file.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.60/lib64/libSDL-1.2.so.1.2.60.debug:
	Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.64/lib64/libSDL-1.2.so.1.2.64:
	Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/1.2.64/lib64/libSDL-1.2.so.1.2.64.debug:
	Likewise.
	* tests/data/test-abidiff-exit/PR30503/libsdl/libsdl-1.2.60-1.2.64-report.txt:
	Likewise.
	* tests/data/Makefile.am: Add the new test inputs above to source
	distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new test
	inputs above to this test harness.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-07 14:12:11 +02:00
Dodji Seketeli f9333ab933 configure.ac: Bump to 2.4 version
Bump the version number to 2.4.  Also, as some interfaces have
changed, bump the SONAME's current number.

	* configure.ac: Bump library version number to 2.4.  Bump SONAME's
	current number to 3.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-05 14:06:44 +02:00
Dodji Seketeli 176afc535a Bug 30467 - enlightenment fails self check on f38
This is yet another instance of a latent canonical type propagation
issue.  Basically, when reading back a type from ABIXML,
canonicalizing it (in an order that is different from the initial
order in which it has been canonicalized by the DWARF front-end)
yields a different canonical type from the original one computed by
the DWARF front-end, yielding spurious self-comparison changes.

By looking at it a bit closer, I realized the cache of the comparison
results wasn't being cleared upon canceling canonical type
propagation, whenever that canceling occurs.  That leads to some
subsequent comparisons being wrong (albeit fast, heh) because they
rely on cached results that should have been invalidated.

This patch thus clears the type comparison result cache whenever
canonical type propagation canceling occurs.

	* src/abg-ir-priv.h (environment::priv::cancel_ct_propagation):
	Clear the type comparison results cache.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-05 13:06:36 +02:00
Dodji Seketeli d00a2cc2da Bug 30466 - harfbuzz fails self-check on f38
Since this commit:

    commit 43cbdd1501
    Author: Dodji Seketeli <dodji@redhat.com>
    Date:   Thu Apr 13 16:48:52 2023 +0200

	ir: Recognize "void* as being equal to all other pointers in C

a pointer to void is considered equal to all other pointers to avoid
emitting some spurious changes while self-comparing glibc from fc37.

As a void pointer can now equal several kinds of types, it could no
longer be canonicalized.  But then, the 'exemplar pointer' based
optimization in the ABIXML writer (cf get_exemplar_type) makes it so
that two different void pointer IR nodes (that are structurally
equivalent) would result in two different nodes (with different
type-ids) being serialized out in ABIXML.  Later at ABIXML reading
time, aggregates types using these two different void pointer nodes
might yield canonical types that are different from the original ones,
depending on the order in which ABIXML types are canonicalized as that
order might differ from the order in which they were initially
canonicalized.  This difference leads to spurious self-comparison
errors.

To handle this, I am proposing that the void pointer type be a unique
IR type node in the system.  That way, the exemplar type optimization
would still work and we get rid of the spurious self-comparison error
change.  While doing this, I realized that the void type and the
variadic parameter type that are also unique types were not properly
enforced in all the front-ends as such.  So this patch fixes that.

The patch also make typedefs and pointer to decl-only classes be
non-canonicalized types because decl-only classes are non-canonicalized
already.  Pointers and typedefs to those types being canonicalized can
lead to different canonicalized type depending on the order of
canonicalization.

The rest of the patch is basically adjusting the other moving parts to
these core changes.

	* include/abg-fwd.h (is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type)
	(is_void_pointer_type_equivalent, is_unique_type): Declare new
	functions.
	(is_typedef, is_void_pointer_type): Declare new overloads.
	(is_declaration_only_class_or_union_type): Add a new
	look_through_decl_only flag as parameter.
	* include/abg-ir.h (environment::{get_void_pointer_type,
	is_void_pointer_type}): Define new member functions.
	* src/abg-ir-priv.h (environment::priv::{void_pointer_type}): Add
	new data member.
	* src/abg-ir.cc (decl_topo_comp::operator()): For unique types,
	use lexicographic sorting.
	(environment::{get_void_pointer_type, is_void_pointer_type}):
	Define new member function.
	(is_typedef, is_pointer_to_decl_only_class_or_union_type)
	(is_reference_to_decl_only_class_or_union_type)
	(is_typedef_to_decl_only_class_or_union_type, is_unique_type):
	Define new functions.
	(is_declaration_only_class_or_union_type): Add a new
	look_through_decl_only parameter.  Some decl-only class or union
	do have an associated definition; this function return false for
	these types if look_through_decl_only is set to true.
	(is_void_pointer_type_equivalent): Rename is_void_pointer_type
	into this.
	(is_void_pointer_type): Now that is_void_pointer_type equals is
	old version of this is_void_poitner, make the new version test if
	the type equals the unique void pointer type, or if it a pointer
	to void type.  It doesn't take typedefs into account, like what
	is_void_pointer_type_equivalent does.
	(equals): In the overload for pointer_type_def, use the new
	is_void_pointer_type_equivalent instead of
	is_void_pointer_type_equivalent.
	(is_non_canonicalized_type): Re-organize this.  Now, all unique
	types are non-canonicalized.  This was sort-of the case already
	but was not clearly stated as such.  The decl-only class-or-union
	types were already non-canonicalized, but pointers and typedefs to
	class-or-unions should also be non-canonicalized for the system to
	work because a decl-only class-or-unions equals all defined types
	in C++.
	* src/abg-btf-reader.cc
	(reader::build_ir_node_for_void_pointer_type): Define new member
	function that return a unique type for void pointer types.
	(reader::build_pointer_type): Use
	build_ir_node_for_void_pointer_type to build void pointer types.
	(reader::{build_ir_node_for_void_type,
	build_ir_node_for_variadic_parameter_type}): Simplify.
	* src/abg-ctf-reader.cc (build_ir_node_for_void_type)
	(build_ir_node_for_void_pointer_type): Define new functions.
	(process_ctf_function_type): Use build_ir_node_for_void_type for
	void types.
	(process_ctf_pointer_type): Use
	build_ir_node_for_void_pointer_type for void pointer types.
	* src/abg-dwarf-reader.cc (build_ir_node_for_void_pointer_type):
	Define a new function that returns a unique type for void pointer
	types.
	(build_pointer_type_def): Use the new
	build_ir_node_for_void_pointer_type to build void pointers.
	(build_ir_node_for_variadic_parameter_type): Simplify.
	* src/abg-reader.cc (read_type_id_string): Define this even
	not debugging self-comparison.
	(build_ir_node_for_void_type)
	(build_ir_node_for_void_pointer_type): Define new functions.
	(reader::{get_scope_for_node, get_scope_ptr_for_node}): New member
	functions.
	(reader::push_decl_to_current_scope): Remove this member function.
	This was using the scope of the last IR node built as the current
	scope.  The problem is that the scope of a unique IR node is the
	scope where it was used the first time; that has nothing to do
	with the current scope.  So this function is obsolete now that we
	are using unique IR nodes for real.
	(reader::push_decl_to_scope): New member function.  This is the
	one to use, now that push_decl_to_current_scope is no more.
	(reader::push_and_key_type_decl): Pass the scope_decl to use.
	Make this push the decl to the scope passed in parameter.  Add an
	overload that has the XML node to use to determine the scope to
	push the decl to.
	(reader::get_scope_for_node): Support template parameter type
	composition nodes.  Also, add an overload that takes just an XML
	node.
	(reader::get_scope_ptr_for_node): Define new member function.
	(build_namespace_decl, build_function_decl, build_var_decl): Use
	to reader::push_decl_to_scope, now that
	reader::push_decl_to_current_scope is gone.
	(build_type_decl): Use build_ir_node_for_void_type to build a void
	type.  Adjust the call to reader::push_and_key_type_decl.
	(build_qualified_type_decl, build_reference_type_def)
	(build_subrange_type, build_array_type_def, build_enum_type_decl)
	(build_typedef_decl, build_class_decl, build_union_decl)
	(build_function_tdecl, build_function_tdecl, build_class_tdecl)
	(build_type_tparameter, build_type_composition)
	(build_non_type_tparameter, build_template_tparameter): Adjust the
	call to reader::push_and_key_type_decl.
	(build_pointer_type_def): Likewise.  Use
	build_ir_node_for_void_pointer_type to build a void pointer IR
	node.  Also, build the pointed-to-type before the pointer type
	itself; this is required to catch a void pointer type early and
	use build_ir_node_for_void_pointer_type to build it.
	* src/abg-comp-filter.cc (has_void_ptr_to_ptr_change): Use the new
	is_void_pointer_type_equivalent in lieu of is_void_pointer_type.
	This is because the former takes typedefs into account and so is
	more accurate.
	* src/abg-comparison.cc
	(scope_diff::ensure_lookup_tables_populated): Do not consider
	unique types when accounting for added/removed types.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test3.so.abi: Likewise.
	* tests/data/test-annotate/test5.o.abi: Likewise.
	* tests/data/test-read-btf/test1.o.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test8.o.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR27700/test-PR27700.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-suppressed-alias.o.abi:
	Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test3-alias-1.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3-alias-4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test17.xml: Likewise.
	* tests/data/test-read-write/test18.xml: Likewise.
	* tests/data/test-read-write/test19.xml: Likewise.
	* tests/data/test-read-write/test20.xml: Likewise.
	* tests/data/test-read-write/test21.xml: Likewise.
	* tests/data/test-read-write/test22.xml: Likewise.
	* tests/data/test-read-write/test23.xml: Likewise.
	* tests/data/test-read-write/test26.xml: Likewise.
	* tests/data/test-read-write/test27.xml: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-06-02 17:46:57 +02:00
Dodji Seketeli 06e8d54d04 Bug 29693 - clang-libs from f37 fails self test
To reproduce the issue reported in the bug above, here is the relevant
command line:

    $ tools/fedabipkgdiff --self-compare -a --from fc37 clang-libs

When the abixml reader encounters a decl-only class, it wrongly avoids
trying to read its members.  This is wrong because a decl-only class
can still have member types.  By doing so, the abixml might "forget"
some member types, leading to self comparison errors as the original
class from DWARF (for instance) might have those member types.

Fixed thus.

	* src/abg-reader.cc (build_class_decl): Read member types even
	when we are looking at a decl-only class.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-05-17 17:19:13 +02:00
Dodji Seketeli 676d8a8149 dwarf-reader: Don't compute canonical type while propagating one
When propagate_canonical_type sees that the source type doesn't have a
canonical type, it tries to compute one for it.

But then suppose we are into computing the canonical type of a type T
to begin with.  At some point we want to try to propagate the
canonical type of a sub-type S of T.  Suppose S recursively references
T.

When propagate_canonical_type is called from
maybe_propagate_canonical_type on S, it's going to try to compute a
canonical type for T (indirectly), as T doesn't yet have a canonical
type.

We then end up in a recursive calling loop that overflows the
execution stack.

	* src/abg-dwarf-reader.cc (propagate_canonical_type): If the
	source (right-hand-side) type has no canonical type, do not
	compute it and thus, do not try to propagate its canonical type to
	the destination (left-hand-side) type.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-05-12 21:35:45 +02:00
Dmitry V. Levin cc7cfc52ee elf-helpers: make sure config.h is included first
Before this change, verify-elf used to complain on x86 and armv7:
verify-elf: ERROR: ./usr/lib/libabigail.so.2.0.0: uses non-LFS functions: open

Include config.h in abg-elf-helpers.cc before other headers so that
AC_SYS_LARGEFILE applies to this file.  This fully enables LFS
in those of 32-bit systems that do not enable it by default.

	* src/abg-elf-helpers.cc: Include "config.h" first.

Fixes: 7bd6983052 ("Make Front Ends first class citizens")
Signed-off-by: Dmitry V. Levin <ldv@strace.io>
2023-05-11 18:07:48 +02:00
Dodji Seketeli eb573a50e1 release-text-template.txt: Modernize a little bit.
Modernize the release-text-template a little bit.

	* release-text-template.txt: Update this for the new xz tarball
	format and add highlights.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-05-10 16:29:55 +02:00
Dodji Seketeli 51ff66f33d Update website for the 2.3 release
* doc/website/mainpage.txt: Update for 2.3.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-04-27 15:42:22 +02:00
Dodji Seketeli cdf3f8e237 NEWS: Update for 2.3 release
* NEWS: Update using "git shortlog libabigail-2.2..HEAD".

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-04-27 11:55:38 +02:00
Dodji Seketeli f96de10e45 Update ChangeLog for 2.3 release
* ChangeLog: Update using the 'make update-changelog' command.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-04-27 11:53:10 +02:00
Dodji Seketeli 9260871326 test-ini: Fix a typo
* tests/test-ini.cc (in_out_specs): Fix a typo near the last
	record of the array.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-04-27 10:41:30 +02:00