Commit Graph

549 Commits

Author SHA1 Message Date
Giuliano Procida
cc157f1265 Correct spelling of "alignment".
* src/abg-reporter-priv.cc: s/alignement/alignment/
	* tests/data/test-abidiff/test-struct0-report.txt: Ditto..
	* tests/data/test-abidiff/test-struct1-report.txt: Ditto.
	* tests/data/test-abidiff/test-var0-report.txt: Ditto.

Signed-off-by: Giuliano Procida <gprocida@google.com>
2020-03-06 11:30:33 +01:00
Dodji Seketeli
1d6731c438 Update copyright year to 2020
We are in February 2020 so this is long overdue.

	* include/abg-comp-filter.h: Update copyright year to 2020.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-cxx-compat.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-sptr-utils.cc: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-dot.cc: Likewise.
	* tests/test-ini.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-svg.cc: Likewise.
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/kmidiff.cc: Likewise.
	* update-copyright.sh: Fix the updating script to handle not just
	"Red Hat, Inc."

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-02-21 17:05:01 +01:00
Dodji Seketeli
6a0e7e120b abixml-reader: Support SONAME related properties on file suppression
When comparing binary files (using abidiff for instance) libabigail
can interpret the [suppress_file] section of a suppression
specification.  If the suppression specification matches either of the
compared files, no comparison is performed.

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

Thus, this patch implements that feature for abixml files.

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

  [suppress_file]
    soname_regexp = <some-regexp>

or

  [suppress_file]
    file_name_regexp = <some-regexp>

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-02-21 16:01:26 +01:00
Giuliano Procida
272817b253 Fix stray comma in leaf-changes-only mode.
This change replaces the "\n," sometimes seen in output (such as for
the PR25128 test cases) with a correctly indented "and".

	* src/abg-reporter-priv.cc (represent): Don't try to follow
        output of indented pretty representation with a comma, just
        emit "and" unconditionally; remove unnecessary intermediate
        ostringstream.
	* tests/data/Makefile.am: Add new test case files.
	* tests/data/test-abidiff-exit/test-no-stray-comma-*: New test
        cases.
        * tests/data/test-diff-suppr/test46-PR25128-report-?.txt:
        Replace unindented comma with indented "and".
	* tests/test-abidiff-exit.cc: Add no-stray-comma test case.

Signed-off-by: Giuliano Procida <gprocida@google.com>
Reviewed-by: Matthias Maennich <maennich@google.com>
2020-02-19 14:00:23 +01:00
Giuliano Procida
95535d8f6f Don't ignore options when diffing translation units (.bi files).
There was an inconsistency in the way the diff context was used for
different file types. This change eliminates this and so .bi files now
have all the command line options applied to their diffs.

	* tests/data/Makefile.am: Add test case files.
	* tests/data/test-abidiff-exit/test-loc-*: New test cases.
	* tests/test-abidiff-exit.cc (in_out_specs): Add new test cases.
	* tools/abidiff.cc (main): Use populated ctxt for translation unit
	diff.

Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-02-03 14:08:26 +01:00
Matthias Maennich
c45d70d08d Testing: add Catch Unit test framework
This patch adds the Catch [1] unit test framework in version v1.12.2 [2]
along with its integration into the existing build and test definition.

While there is version v2 available, v1 still supports C++98, hence we
can make use of it. The framework is distributed as a single header
file. And since it is less then 500k and it comes with a permissive
license, I decided to directly add the file rather than requiring
users/developers/distributors to satisfy the new dependency.

The integration is fairly simple: A new library libcatch.a provides the
`main` for the tests that run with Catch. The tests themselves require
to include the header as well and to link against said library.

As an example I migrated the test-kmi-whitelist test to Catch. The test
becomes a bit more structured and error reporting significantly
improved. E.g. see this intentional breakage:

 |  --- a/tests/test-kmi-whitelist.cc
 |  +++ b/tests/test-kmi-whitelist.cc
 |  @@ -140,5 +140,5 @@ TEST_CASE("WhitelistWithTwoSections", "[whitelists]")
 |     suppressions_type suppr
 |         = gen_suppr_spec_from_kernel_abi_whitelists(abi_whitelist_paths);
 |     REQUIRE(!suppr.empty());
 |  -  test_suppressions_are_consistent(suppr, "^test_symbol1$|^test_symbol2$");
 |  +  test_suppressions_are_consistent(suppr, "^test_symbol$|^test_symbol2$");

It leads to this test output:

 |  ---------------------------------------------------------------------------
 |  WhitelistWithTwoSections
 |  ---------------------------------------------------------------------------
 |  ../../tests/test-kmi-whitelist.cc:136
 |  ...........................................................................
 |
 |  ../../tests/test-kmi-whitelist.cc:81: FAILED:
 |    REQUIRE( left->get_symbol_name_not_regex_str() == expr )
 |  with expansion:
 |    "^test_symbol1$|^test_symbol2$"
 |    ==
 |    "^test_symbol$|^test_symbol2$"
 |
 |  ===========================================================================
 |  test cases:  6 |  5 passed | 1 failed
 |  assertions: 41 | 40 passed | 1 failed

[1] https://github.com/catchorg/Catch2
[2] https://github.com/catchorg/Catch2/releases/tag/v1.12.2

	* tests/.gitignore: Add entry for .dirstamp
	* tests/Makefile.am: Add libcatch test library and use it for
	runtestkmiwhitelist.
	* tests/lib/catch.cc: New test driver implementation.
	* tests/lib/catch.hpp: Add Catch v1.12.2 header only test library.
	* tests/test-kmi-whitelist.cc: Migrate to use Catch test framework.

Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-28 17:16:56 +00:00
Matthias Maennich
4457c10eec dwarf-reader: handle binaries with missing symtab
A broken elf file might not have a valid symtab. As of now we would hit
an ABG_ASSERT and crash. Let's catch that case and bail out instead.

        * src/abg-dwarf-reader.cc (load_symbol_maps_from_symtab_section):
        Handle elf file with missing symtab.
        * tests/test-read-dwarf.cc (InOutSpec): add test case.
        * tests/data/test-read-dwarf/test26-bogus-binary.elf: new test data.

Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-25 21:40:14 +00:00
Matthias Maennich
4252dfd6c5 dwarf-reader: handle symtab.section_header.sh_entsize == 0
A broken elf file with a sh_entsize of 0 makes the dwarf reader crash
due to a division by zero. Fix this by validating the input and exiting
early in that case.

	* src/abg-dwarf-reader.cc (load_symbol_maps_from_symtab_section):
	Handle elf file with invalid sh_entsize.
	* tests/test-read-dwarf.cc (test_task::perform): handle empty
	in_abi_path and out_abi_path as 'read only' test.
	(InOutSpec): add test case.
	* tests/data/test-read-dwarf/test25-bogus-binary.elf: new test data.

Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-24 22:53:30 +00:00
Matthias Maennich
4ecde9a800 KMI Whitelists: Add functionality to make whitelists additive
If multiple KMI whitelists are specified, either by passing
--kmi-whitelist several times or by having multiple whitelist sections
in the whitelist files, the generated suppressions are created as an
intersection of symbols. That is rather unusual, as whitelisting should
rather work additive. That means that the symbols (or expressions
thereof) defined across several sections or files shall be considered a
union of symbols. This patch combines the whitelist parsing to create
exactly one function_suppression and one variable suppression. A test
case has been added to ensure the functionality is working.

Please note, migrating the existing code to this new functionality is
done in a separate commit.

	* include/abg-tools-utils.h
	(gen_suppr_spec_from_kernel_abi_whitelists): New function.
	* src/abg-tools-utils.cc
	(gen_suppr_spec_from_kernel_abi_whitelists): Likewise.
	* tests/.gitignore: Ignore new test executable.
	* tests/Makefile.am: Add new test executable.
	* tests/data/test-kmi-whitelist/whitelist-with-another-single-entry:
	New test input file.
	* tests/data/test-kmi-whitelist/whitelist-with-duplicate-entry:
	Likewise.
	* tests/data/test-kmi-whitelist/whitelist-with-single-entry:
	Likewise.
	* tests/data/test-kmi-whitelist/whitelist-with-two-sections:
	Likewise.
	* tests/data/Makefile.am: Add above test material.
	* tests/test-kmi-whitelist.cc: Add new test executable.

Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-21 18:37:43 +00:00
Matthias Maennich
53d10a789d abg-reader: handle empty corpus nodes in xml representation
An abi-corpus might be part of the representation, but might (due to
filters like whitelisting) not contain actual symbols to be considered.
In that case, `abidw` produces an empty abi-corpus node.

Valid ways of representing this in XML are

 -  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'/>

 -  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'></abi-corpus>

 -  <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'>
    </abi-corpus>

abg-reader could currently only handle the last format and crashed upon
processing the first two ones. The crash happened due to the XMLNode
having no children, but that was assumed. The last case succeeded so
far as this form actually contains a text node (with the newline
character) as a child.

Fix this by handling the case of a node not having children by exiting
early with an empty node.

	* src/abg-reader.cc (read_corpus_from_input): when assigning a
	corpus node, assure the node actually has children.
	* tests/test-abidiff.cc (main): Add test for variants of empty
	xml nodes to the test harness.
	* tests/data/test-abidiff/test-empty-corpus-0.xml: Test input
	containing an empty xml node that closes immediately.
	* tests/data/test-abidiff/test-empty-corpus-0.xml: Test input
	containing an empty xml node that closes immediately with a tag.
	* tests/data/test-abidiff/test-empty-corpus-0.xml: Test input
	containing an empty xml node that closes with a tag on a new line.
	* tests/data/test-abidiff/test-empty-corpus-report.txt:
	Expected test output (empty abidiff) for diffing xml with itself.
	* tests/data/Makefile.am: Add the new test input material above
	to source distribution.

Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-20 12:20:09 +00:00
Dodji Seketeli
aa15698aaf Bug 25409 - Fix reading layout-offset-in-bits attribute of data-member
In the abixml format, when reading the value of the
'layout-offset-in-bits' attribute of the data-member child element of
a class-decl element, we wrongly use atoi.  The reason why atoi is
wrong is that it can only read an 'int' but layout-offset-in-bits can
be a 64 bits unsigned value which comes fromt the DWARF
DW_AT_bit_offset attribute.

We are thus using stroull instead, in this patch.

	* src/abg-reader.cc (read_offset_in_bits): Fix comment.  Use
	stroull rather than atoi.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0:
	Add new binary test input.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0-report-0.txt:
	Add new reference output.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
	Add new abixml representation for the binary test input above.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-dwarf-abixml.cc (in_out_specs): Add the test
	input above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-01-17 16:35:29 +01:00
Matthias Maennich
e84537afea abidiff/kmidiff: do not default-suppress added symbols
kmidiff and abidiff do filter out added symbols (vars, functions and
symbols without debug info) by default when dealing with kernel
binaries. The reason for this is that the ABI could be considered
compatible and not broken when adding symbols. In practice, this is
confusing as there is no possibility for a symmetric comparison (i.e. a
deleted function when comparing left to right is an added function when
comparing right to left). Furthermore, there is no option available to
actually report these added symbols. I thought of adding an option to
report added symbols, but in the end came to the conclusion that we
should behave consistent across the various ways you can diff an ABI
with abidiff and kmidiff and should not change default behaviour for a
particular type of binary. Hence, remove the default behaviour of
filtering out added symbols when comparing kernel binaries. To restore
the current behaviour, the user needs to parametrize with the tools with
--no-added-syms --no-unreferenced-symbols.

Adjusted test cases accordingly and add a new test that covers the old
behaviour new available with additional flags to abidiff.

	* tools/abidiff.cc (adjust_diff_context_for_kmidiff): Drop
	default suppression of added symbols.
	* tools/kmidiff.cc (set_diff_context): Likewise.
	* tests/data/test-diff-suppr/test46-PR25128-report-1.txt: Adjust
	test expectation.
	* tests/data/test-diff-suppr/test46-PR25128-report-2.txt: Add
	test case for abidiff with flag --no-added-syms.
	* tests/data/Makefile.am: add new testcase.

Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2020-01-17 12:40:27 +00:00
Dodji Seketeli
c32b8ec9f3 Bug 24690 - Support comparing non-reachable types of a binary
This patch adds the ability to compare all types of a binary,
including those types that are not reachable from global functions and
variables.

This implies that for types that are not reachable from public
interfaces, we want compare them against each others directly, without
first comparing global functions/variables and walking the graph of
reachable types from there.

The patch adds the --non-reachable-types option to abidiff and
abipkgdiff, instructing them to also compare types that are
non-reachable from global variables and functions.

Using that option, for instance, here is what the summary of
abipkgdiff now looks like, in the test case attached added by this
patch:

================ changes of 'libflatpak.so.0.10204.0'===============
  Functions changes summary: 0 Removed, 0 Changed (16 filtered out), 16 Added functions
  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
  Unreachable types summary: 3 removed (2 filtered out), 1 changed (15 filtered out), 3 added (1 filtered out) types

You can see that there is a new summary line which starts with the
string: "Unreachable types summary:"

Then in the body of the report, those unreachable types are reported
separately.

In practise, we want to limit the unreachable types to compare
somehow, otherwise we'll end up comparing all the types of the types
of the binary and that can be huge.  So we want to limit the
unreachable type analysis to types that are defined in public headers.

So, for abipkgdiff, one can limit the analysis of non-reachable types
to those defined in public headers by supplying the --devel{1,2}
options that specifies the development packages that contain said
public headers.  For abidiff however, you'll want to use the
--headers-dir{1,2} options for that.

The patch comes with appropriate regression tests.

	* include/abg-comparison.h (string_type_base_sptr_map): Define new
	typedef.
	(diff_context::show_unreachable_types): Declare new member
	functions.
	(corpus_diff::{deleted_unreachable_types,
	deleted_unreachable_types_sorted, added_unreachable_types,
	added_unreachable_types_sorted, changed_unreachable_types,
	changed_unreachable_types_sorted}): Likewise.
	(maybe_report_unreachable_type_changes): Declare this function a
	friend of class corpus_diff.
	(corpus_diff::diff_stats::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	net_num_added_unreachable_types, num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	net_num_removed_unreachable_types, num_changed_unreachable_types,
	num_changed_unreachable_types_filtered_out,
	net_num_changed_unreachable_types}): Likewise.
	* src/abg-comparison-priv.h
	(diff_context::priv::show_unreachable_types_): Define new data
	member.
	(diff_context::priv::priv): Initialize the new data member.
	(diff_comp::operator()): Use pretty representation of diff
	subjects to sort them, rather than just their name.  Also, add
	comment to the other member functions of diff_comp.
	(corpus_diff::{unreachable_types_edit_script_,
	deleted_unreachable_types_, deleted_unreachable_types_sorted_,
	suppressed_deleted_unreachable_types_, added_unreachable_types_,
	added_unreachable_types_sorted_,
	suppressed_added_unreachable_types_, changed_unreachable_types_,
	changed_unreachable_types_sorted_}): Define new data members.
	(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
	Changed the name of
	corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars into
	this.
	(corpus_diff::priv::{added_unreachable_type_is_suppressed,
	deleted_unreachable_type_is_suppressed,
	changed_unreachable_types_sorted, count_unreachable_types}):
	Declare new member functions.
	(corpus_diff::diff_stats::priv::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	num_changed_unreachable_types,
	num_changed_unreachable_types_filtered_out}): Define new data
	members.
	(sort_string_type_base_sptr_map): Declare new function.
	* src/abg-comparison.cc (sort_string_type_base_sptr_map)
	(diff_context::show_unreachable_types): Define new functions.
	(corpus_diff::diff_stats::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	net_num_added_unreachable_types,
	net_num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	num_removed_unreachable_types}): Define new member functions.
	(diff_maps::insert_diff_node): Do not update the map "diff ->
	impacted interfaces" if the current impacted interface is nil.
	This happens if we are looking at a diff node for a change on a
	type that is not reachable from any interfaces.
	(corpus_diff::priv::ensure_lookup_tables_populated): Handle the
	edit script for unreachable types.
	(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
	Rename
	corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars
	into this.  Apply suppression specifications to added and removed
	unreachable types as well.
	(corpus_diff::priv::{added,deleted}_unreachable_type_is_suppressed):
	Define new member functions.
	(corpus_diff::priv::{count_unreachable_types,
	changed_unreachable_types_sorted}): Likewise.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Update
	statistics (including walking changed unreachable types to apply
	categorization and redundancy filters to them) related to
	unreachable types.
	(corpus_diff::priv::emit_diff_stats): Emit diff stats related to
	unreachable types.
	(corpus_diff::priv::maybe_dump_diff_tree): Dump diff tree nodes
	related to unreachable types.
	(corpus_diff::{deleted_unreachable_types,
	deleted_unreachable_types_sorted, added_unreachable_types,
	added_unreachable_types_sorted, changed_unreachable_types,
	changed_unreachable_types_sorted): Define new member functions.
	(corpus_diff::has_changes): Take deleted/added/changed unreachable
	types into account.
	(corpus_diff::has_incompatible_changes): Take net removed/changed
	unreachable types into account.
	(corpus_diff::has_net_subtype_changes): Take net removed and
	changed unreachable types into account.
	(corpus_diff::has_net_changes): Take net removed/added/changed
	unreachable types into account.
	(corpus_diff::traverse): When traversing the components of a
	corpus_diff node, make sure to traverse the changed unreachable
	types of the corpus.
	(leaf_diff_node_marker_visitor::visit_begin): Arrange for the fact
	that the current topmost interface can be nil if we are looking at
	types not reachable from global functions/variables.  Also, make
	sure that only leaf nodes that are reachable from a global
	function/variable are recorded as leaf nodes.
	(compute_diff): In the overload for corpus_sptr, compute the
	changes between types not reachable from global functions and
	variables, if the user wishes that we do so.  Also, add more
	comments.
	(apply_suppressions): Update for the name change of the function
	apply_suppressions_to_added_removed_fns_vars to
	apply_supprs_to_added_removed_fns_vars_unreachable_types.
	* include/abg-corpus.h
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces,
	get_types_not_reachable_from_public_interfaces}): Declare new
	member functions.
	(corpus::recording_types_reachable_from_public_interface_supported):
	Declare new virtual member function.
	(corpus_group::get_public_types_pretty_representations): Declare
	new member functons.
	(corpus_group::recording_types_reachable_from_public_interface_supported):
	Declare new virtual member function.
	* src/abg-corpus-priv.h
	(corpus::priv::{types_not_reachable_from_pub_ifaces_,
	pub_type_pretty_reprs_}): Define new data members.
	(corpus::priv::priv): Initialize the pub_type_pretty_reprs_ data
	member because it's a pointer.
	(corpus::priv::get_public_types_pretty_representations): Declare
	new member function.
	(corpus::priv::~priv): Declare a destructor.
	* src/abg-corpus.cc
	(corpus::priv::get_public_types_pretty_representations): Define
	new member function.
	(corpus::priv::~priv): Define new destructor to delete the new
	pub_type_pretty_reprs_ member pointer.
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces,
	get_types_not_reachable_from_public_interfaces,
	recording_types_reachable_from_public_interface_supported}):
	Define new member functions
	(corpus_group::get_public_types_pretty_representations): Likewise.
	* include/abg-diff-utils.h (struct deep_ptr_eq_functor): Document
	the equality operator.  Also, add an overload to the equality
	operator, for weak_ptr<T>.  The existing equality operator
	overload was just for shared_ptr<T>.
	* include/abg-fwd.h (is_user_defined_type): Declare function.
	* include/abg-ir.h (operator!=(const decl_base_sptr&, const
	decl_base_sptr&)): Declare new operator.
	(type_maps::get_types_sorted_by_name): Declare
	new member function.
	(decl_base::{g,s}et_is_artificial): Declare new member function.
	(function_decl::parameter::{g,s}et_artificial): Remove these
	member functions.
	* src/abg-ir.cc (operator!=(const decl_base_sptr&, const
	decl_base_sptr&)): Define new operator.
	(decl_base::priv::is_artificial_): Define new data
	member.
	(type_maps::priv::sorted_types_): Define new data member.
	(struct type_name_comp): Define new comparison functor to sort
	types based on their pretty representations.
	(decl_base::priv::priv): Initialize it.
	(decl_base::{g,s}et_is_artificial): Define new member functions.
	(type_maps::get_types_sorted_by_name): Define new member function.
	(is_user_defined_type): Define new function overloads.
	(strip_typedef, function_type::{function_type, set_parameters}):
	Adjust using decl_base::get_is_artificial rather than
	function_decl::parameter::get_artificial.
	(function_decl::parameter::priv::artificial_): Remove this data
	member.
	(function_decl::parameter::priv::priv): Adjust to the removal of
	function_decl::parameter::priv::artificial_.  This constructor
	does not take an "is_artificial" flag anymore.
	(function_decl::parameter::parameter): Adjust to the removal of
	the is_artificial flag from the arguments of the constructor of
	function_decl::parameter::parameter::priv.
	(function_decl::parameter::get_artificial): Remove this member
	function.
	* src/abg-reporter-priv.h (maybe_report_unreachable_type_changes):
	Declare new function.
	* src/abg-reporter-priv.cc
	(maybe_report_unreachable_type_changes): Define new function.
	* src/abg-default-reporter.cc (default_reporter::report): In the
	overload for corpus_diff&, report added/removed/changed types that
	are not reachable from global functions and variables using the
	new function maybe_report_unreachable_type_changes.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
	overload for corpus_diff, report changes to types unreachable from
	global functions or variables, using the new function
	maybe_report_unreachable_type_changes.
	* src/abg-dwarf-reader.cc (build_ir_node_from_die): When the user
	requests that all types be loaded, record relevant types as
	reachable from global functions and variables.
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): Read the 'is-artificial' DWARF
	attribute and set the corresponding decl_base property
	accordingly.
	(finish_member_function_reading, strip_typedef)
	(function_type::function_type): Adjust using
	decl_base::get_is_artificial, rather than
	function_decl::parameter::get_artificial.
	* include/abg-reader.h
	(consider_types_not_reachable_from_public_interfaces): Declare new
	function.
	* src/abg-reader.cc
	(read_context::m_tracking_non_reachable_types): Add new data
	member.
	(read_context::read_context): Initialize it.
	(read_context::tracking_non_reachable_types): Define accessors for
	the new data member above.
	(read_is_declaration_only): Re-indent.
	(read_is_artificial): Define new helper function.
	(build_function_parameter): Use the new read_is_artificial
	function here, rather than open-coding it.
	(build_enum_type_decl, build_class_decl, build_union_decl):
	Support reading the 'is-artificial' property by using the new
	read_is_artificial function.
	(read_corpus_from_input): If the user wants us to take
	non-reachable types into account, then make sure we do so.
	(read_tracking_non_reachable_types, read_is_non_reachable_type):
	Define new static functions.
	(handle_element_node, build_type): Read the "is-non-reachable"
	attribute on type element nodes if the user wants us to track
	non-reachable types.
	(consider_types_not_reachable_from_public_interfaces): Define new
	function.
	* src/abg-writer.cc (write_is_artificial): Define new static
	helper function.
	(annotate): Adjust using decl_base::get_is_artificial rather than
	function_decl::parameter::get_artificial.
	(write_enum_type_decl, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Support writing the
	"is-artificial" property, using the new write_is_artificial
	function.
	(write_function_type): Adjust this to use the new
	write_is_artificial rather than open-coding writing the
	'is-artificial' attribute.
	(write_is_non_reachable)
	(write_tracking_non_reachable_types): Define new static functions.
	(write_enum_type_decl, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Write the 'is-no-reachable'
	attribute when applicable.
	(write_corpus, write_corpus_group): Write the
	'tracking-non-reachable-types' attribute when applicable.
	* tools/abidiff.cc (options::options): Initialize ...
	(options::show_all_types): ... new data member.
	(display_usage): Add help string from the new
	--non-reachable-types option.
	(parse_command_line): Parse the new --non-reachable-types option.
	(set_diff_context_from_opts): Set the
	dwarf_reader::read_context::show_unreachable_types property.
	(set_native_xml_reader_options): Define new
	static function.
	(main): Load all types when analyzing the DWARF or the ABIXML
	files, if the user wants us to do so.
	* tools/abipkgdiff.cc (options::show_all_types): Define new data
	member.
	(options::options): Initialize it.
	(parse_command_line): Parse the --non-reachable-types option to
	set the options::show_all_types data member.
	(display_usage): Add a help string for the new
	--non-reachable-types option.
	(set_diff_context_from_opts): Set the
	dwarf_reader::read_context::show_unreachable_types property based
	on the options::show_all_type data member.
	(compare): Configure the read context to load all types while
	analyzing the DWARF info, depending on the options::show_all_type
	data member.
	* doc/manuals/abidiff.rst: Document the new --non-reachable-types
	option added to abidiff above.
	* doc/manuals/abipkgdiff.rst: Add documentation for the
	--non-reachable-types option.
	* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.c:
	Source code files of test binary input.
	* tests/data/test-diff-suppr/test47-non-reachable-types-suppr-{1,2,3,4,5}.txt:
	New test input files.
	* tests/data/test-diff-suppr/test47-non-reachable-types-report-{1,2,3,4,5,6,7,8,9,10}.txt:
	New test reference output files.
	* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.o.alltypes.abixml:
	New test input abixml.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new tests above
	to this test harness.
	* tests/data/test-abidiff/test-struct1-report.txt: Adjust.
	* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.2.4-3.fc30.x86_64.rpm:
	New input binary RPM.
	* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/PR24690-report-0.txt: New test
	reference output.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test material
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-01-06 14:26:00 +01:00
Dodji Seketeli
847800d497 Bug 25128 - Handle decl-only classes that differ only in size
Because DWARF sometimes emit decl-only classes (real one, with no
members) with a size property, and the rest of the time, would emit
the same decl-only class without a size property, comparing the two
might yield some false positives.

This patch handles those beasts when comparing classes.

	* include/abg-comp-filter.h (is_decl_only_class_with_size_change):
	Declare an overload.
	* include/abg-fwd.h (look_through_decl_only_class): Declare an
	overload.
	* src/abg-comp-filter.cc (is_decl_only_class_with_size_change):
	Define an overload that takes class_or_union& type. Re-write the
	previous overload in terms of this new one.
	* src/abg-ir.cc (look_through_decl_only_class): Define a new
	overload that takes a class_or_union&.  Rewrite the previous
	overload in terms of this one.
	(equals): In the overload for class_or_union&, use
	is_decl_only_class_with_size_change to detect cases of decl-only
	classes that differ only by their size attribute and avoid
	comparing them.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-11-08 11:09:13 +01:00
Dodji Seketeli
1f4dbe3515 Bug 25128 - Leaf diff reporter shouldn't compare decl-only classes
The leaf_diff_node_marker_visitor pass which collects leaf diff nodes
for the leaf diff reporter considers bogus decl-only classes (that have the
is-declaration-only flag set, are empty, and yet have a non-nil size
property) originated from bogus DWARF.

The leaf reporter thus potentially reports size changes among
decl-only classes, which does not make sense.  Two decl-only classes
of the same name should always be considered equal, in this context.

This patch thus teaches the leaf_diff_node_marker_visitor to avoid
collecting a leaf diff node that is about a size change on a true
decl-only class.

	* include/abg-comp-filter.h (is_decl_only_class_with_size_change):
	Declare new function.
	* src/abg-comp-filter.cc (is_decl_only_class_with_size_change):
	Define new function.
	* src/abg-comparison.cc
	(leaf_diff_node_marker_visitor::visit_begin): Use the newly
	defined is_decl_only_class_with_size_change above to ignore bogus
	decl-only classes with a size change.
	* tests/data/test-diff-suppr/test45-abi-report-1.txt: New test input.
	* tests/data/test-diff-suppr/test45-abi-wl.xml: Likewise.
	* tests/data/test-diff-suppr/test45-abi.xml: Likewise.
	* tests/data/test-diff-suppr/test45-abi.suppr.txt: New reference
	output for the test input above.
	* tests/data/test-diff-suppr/test46-PR25128-base.xml: New test input.
	* tests/data/test-diff-suppr/test46-PR25128-new.xml: Likewise.
	* tests/data/test-diff-suppr/test46-PR25128-report-1.txt: New
	reference input for the test input above.
	* tests/data/Makefile.am: Add the new test material to source distribution.
	* tests/test-diff-suppr.cc (in_out_spec): Add the new test input
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-11-08 11:08:38 +01:00
Dodji Seketeli
b00976517f Support symbol_name_not_regexp in [suppress_{function, variable}]
In the suppress_function and suppress_variable directives of the
suppression specification language, we lack the
'symbol_name_not_regexp' properties, that would allow users to specify
which (function/variable) symbols to *keep* as opposed to specifying
which symbols to suppress.

This patch adds that feature.  That will later allow us to make the
linux kernel symbol white lists[1] functionality use this feature;
that is, upon analysing the content of a kernel symbol whitelist which
lists a symbol named "foo", Libabigail would automatically generate a
suppression specification which contains, e.g a 'suppress_function"
directive that has this new 'symbol_name_not_regexp' property which
value is set to "foo".

Note that the patch makes sure that feature is supported when
analyzing both abixml and DWARF formats.

[1]: You can learn about what a Linux Kernel symbols white list is by
reading about it at
https://sourceware.org/libabigail/manual/kmidiff.html#environment.

	* doc/manuals/libabigail-concepts.rst: Document the new
	symbol_name_not_regexp properties for the
	suppress_{function,variable} directives.
	* include/abg-suppression.h
	({function,variable}_suppression::{g,s}et_symbol_name_not_regex_str):
	Declare new member functions.
	* src/abg-dwarf-reader.cc
	(read_context::is_elf_symbol_suppressed): Define new member functions.
	(read_context::{load_symbol_maps_from_symtab_section,
	populate_symbol_map_from_ksymtab,
	populate_symbol_map_from_ksymtab_reloc}): Drop suppressed symbols
	when reading symbol tables.
	({function,variable}_is_suppressed): Consider that in C, the
	linkage name is _by default_ the same as the function/variable
	name. Remove local variable.
	* include/abg-ir.h (elf_symbol_is_{function,variable}): Add ...
	* src/abg-ir.cc (elf_symbol_is_{function,variable}): ... new
	functions.
	* src/abg-reader.cc (build_elf_symbol): Take an additional boolean
	to detect and drop suppressed symbols.
	(build_elf_symbol_db): Adjust the call to build_elf_symbol to make
	it detect and drop suppressed symbols.
	(read_corpus_from_input): Be mindful that the set of symbols for a
	given corpus can be empty because of suppression specifications.
	* src/abg-suppression-priv.h
	({function,variable}_suppression::priv::symbol_name_not_regex[_str_]):
	Add new data members.
	(function,variable}_suppression::priv::get_symbol_name_not_regex):
	Add new member functions.
	({function,variable}_is_suppressed): Guard against empty name.
	(is_elf_symbol_suppressed): Define new function template.
	* src/abg-suppression.cc
	({function,variable}_suppression::{g,s}et_symbol_name_not_regex_str):
	Define new member functions.
	({function,variable}_suppression::suppresses_function)
	(suppression_matches_{function,variable}_sym_name)
	(read_{function,variable}_suppression): Support the new
	"symbol_name_not_regex" property.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp-report-1.txt:
	New test reference report.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp-report-2.txt:
	Likewise.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp-v{0,1}.c:
	Sources of the new test input.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp-v{0,1}.o:
	New test input binaries.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp-v{0,1}.o.abi:
	New test input abixml files.
	* tests/data/test-diff-suppr/test44-suppr-sym-name-not-regexp.suppr.txt:
	Next test suppression specification.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the input tests
	above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-11-08 11:01:54 +01:00
Dodji Seketeli
2f7248f340 PR25058 - Support decl DIEs referring to symbols using DW_AT_ranges
Usually, function DIEs (DW_TAG_subprogram) refer to the address of the
underlying ELF symbol by using the DW_AT_low_pc attribute.  However,
there are cases where it does so by using the DW_AT_ranges attribute.
In those cases, the first address of the sequence defined in the value
of that attribute is the address of the ELF symbol.

The problem is that the DWARF reader of Libabigail fails to get the
address of the underlying ELF symbol when the DW_AT_low_pc attribute
is missing.  Rather, it should then look at the value of the
DW_AT_ranges attribute instead.

This is what this patch does.

	* src/abg-dwarf-reader.cc
	(read_context::get_first_address_from_DW_AT_ranges): Define new
	member function.
	(read_context::get_function_address): Use the new
	read_context::get_first_address_from_DW_AT_ranges here.
	* tests/data/test-diff-dwarf/PR25058-liblttng-ctl-report-1.txt:
	New reference test output.
	* tests/data/test-diff-dwarf/PR25058-liblttng-ctl.so: New test
	input binary.
	* tests/data/test-diff-dwarf/PR25058-liblttng-ctl2.10.so: New test
	input binary.
	* tests/data/Makefile.am: Add the new test materials above to
	source distribution.
	* tests/test-diff-dwarf.cc (in_out_specs): Add the new input test
	input binary files to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-10-03 17:42:30 +02:00
Dodji Seketeli
568dee18a1 PR25042 - Support string form DW_FORM_strx{1,4} from DWARF 5
* configure.ac: Detect the presence of the DW_FORM_strx{1,4}
	enumerators.
	* src/abg-dwarf-reader.cc (form_is_DW_FORM_strx): Define new
	function.
	(compare_dies_string_attribute_value): Use the new
	form_is_DW_FORM_strx here.
	* tests/data/Makefile.am: Add the new test input files below to
	source distribution.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0:
	New binary test input file.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Reference output of the new binary test input file.
	* tests/test-read-dwarf.cc (in_out_specs): Add the input test
	files above to the test harness, for platforms that support the
	DW_FORM_strx form.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-10-01 14:14:41 +02:00
Dodji Seketeli
d2c88645e8 Support the "name_not_regexp" property in the [suppress_type] section
When writting a suppression specification in which the user wants to
keep a family of types (whose names set is specified by a regular
expression) and suppress/drop all other types, one needs to write
something like:

[suppress_type]
  name_regexp = (?!the-regexp-of-the-types-to-keep)

It would be nicer (like what is done for other properties that take
regular expressions as value in suppression specifications) to be able
to write:

[suppress_type]
  name_not_regexp = the-regexp-of-types-to-keep

This patch does just that.

It augments the abigail::suppr::type_suppression type to make it carry
the new 'name_not_regex' property.  It updates the suppression engine
to take the 'name_not_regex' property into account when interpreting
instances of abigail::suppr::type_suppression.  The parser for type
suppression directives is updated to recognize the new name_not_regexp
property.  The manual has been updated accordingly to describe the new
property.  New regression tests have been added.

	* doc/manuals/libabigail-concepts.rst: Update this to document the
	new name_not_regexp property of the suppress_type directive.
	* include/abg-suppression.h
	(type_suppression::{g,s}et_type_name_not_regex_str): Declare new accessors.
	* src/abg-suppression-priv.h
	(type_suppression::priv::{type_name_not_regex_str_,
	type_name_not_regex_}): Define new data members.
	(type_suppression::priv::{get_type_name_not_regex,
	set_type_name_not_regex, get_type_name_not_regex_str,
	set_type_name_not_regex_str}): Define new member functions.
	* src/abg-suppression.cc
	(type_suppression::get_type_name_regex_str): Fix comments.
	(type_suppression::{set_type_name_not_regex_str,
	get_type_name_not_regex_str}): Define new data members.
	(suppression_matches_type_name): Adapt to support the new
	type_name_not_regex property.
	(read_type_suppression): Support parsing the type_name_not_regexp
	property.
	* tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt:
	New test reference output.
	* tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt:
	New test input.
	* tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt: Likewise.
	* tests/data/test-diff-suppr/test42-negative-suppr-type-v0.{cc, o}: Likewise.
	* tests/data/test-diff-suppr/test42-negative-suppr-type-v1.{cc,
	o}: Likewise.
	* tests/data/Makefile.am: Add the test files above to source
	distribution.
	* tests/test-diff-suppr.cc (int_out_specs): Add the new tests to
	the harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-09-30 14:56:52 +02:00
Dodji Seketeli
bdd927f663 Better propagation of suppressed-ness to function types
In the comparison engine, when a sub-type of a function type (say, a
parameter type size change) has been suppressed, this suppression is
not necessarily well propagated to the function carrying the function
type, because the parameter type size, for instance, is considered as
a type local change to that function; and we generally don't propagate
suppression to a non-suppressed parent diff node that already carries
a local change.

This leads to an empty change report for the function we are looking
at because the only sub-type change has been suppressed.

This patch properly propagates the suppressed-ness in that case, so
that the parent function diff node is suppressed as well.

	* src/abg-comparison.cc
	(suppression_categorization_visitor::visit_end): Propagate
	suppression-ness from suppressed function type diff node to its
	parent function node if the latter doesn't have any local non-type
	change.
	* tests/data/test-diff-suppr/test43-suppr-direct-fn-subtype-report-1.txt:
	New test reference output.
	* tests/data/test-diff-suppr/test43-suppr-direct-fn-subtype-suppr-1.txt:
	New test input suppression file.
	* tests/data/test-diff-suppr/test43-suppr-direct-fn-subtype-v{0,1}.cc:
	Source code of input binary file.
	* tests/data/test-diff-suppr/test43-suppr-direct-fn-subtype-v{0,1}.o:
	Input binary files.
	* tests/data/Makefile.am: Add the new test input files above to
	source distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the test input to
	test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-09-30 14:56:41 +02:00
Dodji Seketeli
583bc40deb Guard testing v4.19+ AARCH64 kernel module loading for EL6 support
When analyzing an AARCH64 linux kernel module built with support for
either R_AARCH64_ABS64 or R_AARCH64_PREL32 relocations, we need these
macros to be defined in elf.h (i.e a recent enough version of libelf),
otherwise we cannot properly support those kernel modules using the
scheme that uses the relocation table of the __ksymtab and
__ksymtab_gpl sections to read those sections.

In the future, I think we should automatically fallback to another way
of trying to read those sections if those macros are not defined, and
emit a message hinting at what is happening, when in verbose mode.  I
am keeping it as is for the moment, so that we can get a better case
of the when these macros are not defined and whatnot.

In the mean time, this patch conditionalizes the test that reads a
kernel module build with support for these relocations to avoid
running it on platform that support these relocations.

	* tests/test-read-dwarf.cc: Do not run the test on
          PR25007-sdhci.ko if the macros R_AARCH64_PREL32 and
          R_AARCH64_ABS64 are not defined.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-09-20 15:59:56 +02:00
Dodji Seketeli
01e5bfc4a4 Bug 25007 - Don't use section-relative symbol values on ET_REL binaries
In relocatable files, two symbols listed in the .symtab section can
have the same value and yet be different.  That is because those
symbols can be *defined* in different sections.  And the value of
those symbols represent addresses (offsets) within their own
respective sections (a.k.a section-relative addresses).

In the same time, symbol address as referred-to in the DWARF
information are *not* section-relative, rather, they are relative to
the beginning of the whole binary.

Until now, the DWARF-referred-to symbol addresses were translated into
section-relative addresses, so that they could be compared to the
other section-relative addresses we were getting from listing the
symbols and their values from the .symtab section.  The problem with
that approach is that, during the translation from binary-relative to
section-relative addresses we were wrongly assuming that all symbols
referenced from the DWARF were defined in the .text section.  This is
wrong especially for ET_REL files because they could be defined in
sections named .foo.text or .bar.text, for instance.

This leads to issues where we wrongly consider that two symbols having the
same value are the same.  Because we wrongly assume that they are all
defined in the same .text section.

This patch fixes this problem by translating the section-relative
addresses we see in .symtab into binary-relative addresses by adding
the address of the section to the section-relative address.  Those
binary-addresses can thus safely be compared to the binary-relative
addresses we see in the DWARF.  And also, when two symbols have the
same binary-relative address, we can now safely assume that they are
the same -- they are aliases, basically.

	* src/abg-dwarf-reader.cc
	(read_context::{lookup_native_elf_symbol_from_index,
	maybe_adjust_et_rel_sym_addr_to_abs_addr}): Define new member
	functions.
	(read_context::lookup_elf_symbol_from_index): Add a new overload.
	Write the old overloads in terms of the new one.
	(read_context::{load_symbol_maps_from_symtab_section,
	populate_symbol_map_from_ksymtab_reloc}): Use the new
	maybe_adjust_et_rel_sym_addr_to_abs_addr function to translate the
	symbol value/address into a binary-relative address before adding
	it to the addr->sym maps.
	(read_context::maybe_adjust_{fn, var}_sym_address): Do not adjust
	DWARF-referred-to addresses of ET_REL symbols anymore.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko: New binary test input.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: ABI
	representation of the above.
	* tests/test-read-dwarf.cc: Add the new test input to the harness.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test20-inline-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test20-inline-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test9-report.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-09-20 14:13:12 +02:00
Dodji Seketeli
bc2d2ce660 Serialize canonical types to avoid testing if types have been emitted
When emitting abixml, profiling shows that we spend a great deal of
time testing if a given type has been emitted already, to avoid
emitting a given type more than once.  This makes the serialization
phase take more time than the binary analysis phase!

This patch leverages the fact that we already have the set of
canonical types in the system.  While emitting that set entirely, we
don't need to test if a type has been emitted already because we know
by definition that every type is present just once in that set, more
or less.  OK, because there are also types that don't have canonical
types (for instance, declaration-only class/structs), we'll still have
to check of those types have already been emitted, but this is a very
small set to handle.

The patch thus organizes the canonical types per scope, so that when
emitting a scope and the canonical types within it, the type is
emitted in its correct namespace.

Then, when emitting a translation unit and each namespaces in it, the
patch emits the canonical types of those namespaces.

The patch arranges for some ancillary things that are needed to make
the whole picture be coherent enough for things to keep working.

Testing shows that we gained ~ 30% of performance by doing this, while
analysing the whole linux kernel 5.1 version.  We went from ~ 3m30s
minutes to less than 2m30s.

With this patch, the serialization phase now takes less time than the
analysis time.

	* include/abg-fwd.h (is_decl_slow)
	(peel_pointer_or_reference_type): Declare new functions.
	* include/abg-ir.h (struct canonical_type_hash): Define new type.
	(type_base_ptr_set_type, type_base_ptrs_type)
	(type_base_sptrs_type, canonical_type_sptr_set_type): Define new
	typedefs.
	(environment::get_canonical_types_map): Declare new member
	function.
	(scope_decl::{get_canonical_types, get_sorted_canonical_types}):
	Declare new member functions.
	* src/abg-ir.cc (is_ptr_ref_or_qual_type)
	(peel_pointer_or_reference_type, is_decl_slow): Define new
	functions.
	(environment::{get_canonical_types_map}): Define new member
	functions.
	(canonical_type_hash::operator()): Likewise.
	(scope_decl::{get_canonical_types, get_sorted_canonical_types}):
	Likewise.
	(struct type_topo_comp): Define new comparison functor type.
	(environment::{sorted_canonical_types_}): Define new data member.
	(scope_decl::priv::{canonical_types_, sorted_canonical_types_}):
	Likewise.
	(scope_decl::is_empty): Take the presence of canonical types into
	account when determining if a scope is empty or not.
	(is_decl): Make this work for cases where the artifact at hand is
	a type which has a declaration, as opposed to being a pure
	declaration like a variable or a function.
	(canonicalize): Add the canonical type the list of canonical types
	of its scope.
	* src/abg-dwarf-reader.cc (read_context::die_is_in_cplus_plus):
	Define new member function.
	* src/abg-writer.cc (write_type, write_canonical_types_of_scope):
	Define new static functions.
	(fn_type_ptr_set_type): Define new typedef.
	(write_context::{m_referenced_fn_types_set,
	m_referenced_non_canonical_types_set}): Add new data members.
	(write_context::m_referenced_types_set): Renamed
	m_referenced_types_map into this.
	(write_context::get_referenced_types): Adjust.
	(write_context::get_referenced_{function_types,
	non_canonical_types}):
	(write_context::record_type_as_referenced): Adjust to add the
	referenced type in the proper set which would be one of the three
	following: write_context::{get_referenced_types,
	get_referenced_function_types,
	get_referenced_non_canonical_types}.
	(write_context::{type_is_referenced, clear_referenced}): Adjust.
	(write_translation_unit): Use the new
	write_canonical_types_of_scope.  Also emit declaration-only
	classes that have member types.  Do not test if a given type of a
	given scope has been emitted, in general, as this was super slow
	given the number of types.  Emit referenced function types (as
	these don't belong to any scope).  Rather than using the expensive
	"is_function_type" on *all* the referenced types, just walk the
	set write_context::get_referenced_function_types.  Likewise,
	rather than using type_base::get_naked_canonical_type on
	*all* the referenced types, just walk the set
	write_context::get_referenced_non_canonical_types
	(write_class): Use write_canonical_types_of_scope here.
	* tools/abilint.cc (main): Support linting corpus group abixml
	files.
	* 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/test4.so.abi: Likewise.
	* tests/data/test-annotate/test6.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.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/PR24378-fn-is-not-scope.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/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test1.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/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/test4.so.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test10.xml: Likewise.
	* tests/data/test-read-write/test14.xml: Likewise.
	* tests/data/test-read-write/test15.xml: 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/test2.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/test24.xml: Likewise.
	* tests/data/test-read-write/test25.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.
	* tests/data/test-read-write/test3.xml: Likewise.
	* tests/data/test-read-write/test6.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-09-17 17:52:26 +02:00
Matthias Maennich
d7ae619ff3 Ensure a consistent C++ standard use
On older compilers (such as g++ 4.8), the default C++ standard is set to
gnu++98. When compiling libabigail with --enable-cxx11=yes, src/ and
tests/ where compiled with the correct flag, while tools/ was compiled
without specifying a standard. With a compiler falling back to gnu++98
that leads to unresolved references when linking the tools against the
libabigail library. Fix that by consistently using the std= flag across
the code base.

	* configure.ac: add -std=c++11 flag to CXXFLAGS when compiling
	for C++11
	* src/Makefile.am: drop now obsolete setting of the -std flag
	* tests/Makefile.am: likewise

Reported-by: Chun-Hung Wu <Chun-hung.Wu@mediatek.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-22 11:18:13 +02:00
Dodji Seketeli
f2437aabad Bug 24787 - Filter out enum changes into compatible integer types
Libabigail's filtering engine fails to recognize an enum changing into
a compatible integer (or vice versa) as a harmless change.

This patch fixes that.

	* include/abg-comparison.h (peel_typedef_or_qualified_type_diff):
	Declare new function.
	(peel_pointer_or_qualified_type_diff): Rename
	peel_pointer_or_qualified_type into this.
	* include/abg-fwd.h (is_enum_type): Declare a new overload for
	type_or_decl_base*.
	* src/abg-comp-filter.cc (has_harmless_enum_to_int_change): Define
	new static function.
	* src/abg-comparison.cc (categorize_harmless_diff_node): Use the
	new has_harmless_enum_to_int_change here.
	(peel_pointer_or_qualified_type_diff): Renamed
	peel_pointer_or_qualified_type into this.
	(is_diff_of_basic_type): Adjust.
	(peel_typedef_or_qualified_type_diff): Define new function.
	* test-diff-filter/PR24787-lib{one, two}.so: New test input
	binaries.
	* test-diff-filter/PR24787-{one, two}.c: Source files of the test
	input binaries above.
	* test-diff-filter/PR24787-report-0.txt: Test output reference.
	* tests/data/Makefile.am: Add the new testing material to source
	distribution.
	* tests/test-diff-filter.cc (in_out_specs): Add the new test to
	the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-19 18:22:12 +02:00
Dodji Seketeli
400ac7a412 Implement fast comparison of Linux Kernel types when applicable
During type canonicalization there are observations that can speed-up
type comparison significantly without impacting correctness too much.

Typically, when two types are of the same name and kind, are found in
the same corpus and are defined in the same translation unit, they
ought to be the same type, even in C.  So there is no need in this
case to actually perform the structural comparison of the two types
which does have a quadratic performance at best.

Using this optimization made the loading of the
drivers/gpu/drm/i915/i915.ko module go from a quasi inifite time (many
hours on my system) to less than two minutes.  I am confining this
optimization to the Linux kernel case only for now, but I believe it
could benefit all C programs.  I am waiting for more testing before
applying it more broadly.

Also, while looking at this, I noticed that when loading several
corpora into a given corpus group (i.e, loading several linux kernel
binaries to represent a single conceptual kernel), we sometimes fail
to recognize that a type defined in a header file that is included in
several corpora is actually the same type, and should be re-used,
rather than being re-defined in each corpus.  This later adds stress
(time and space) on the system as we need to canonicalize and
de-duplicate these type later on.

This is because the "per-corpus" type maps that we use to lookup a
type by name and location when we see it (so that we know it's defined
in a different corpus of our current group) should really be
per-corpus-group type maps!  That is a type can be defined in the
corpus representing a .ko binary, and that type would be seen again in
another .ko binary later.  Until now, we were wrongly considering that
types were to be first defined in the corpus of the vmlinux binary,
and then could be re-used later.

I have thus fixed the code so that whenever we add a type to its
scope, the relevant per-corpus type maps are updated, as well as the
per-corpus-group ones, so that we can later lookup types in those
per-corpus-group type maps to know if a type is already defined in any
corpus of the group.

	* include/abg-corpus.h (corpus::origin): Add a new
	LINUX_KERNEL_BINARY_ORIGIN enumerator.
	(corpus::{s,g}et_group): Declare new member
	functions.
	(class corpus): Make the corpus_group class friend of this one.
	(corpus_group::get_main_corpus): Declare new member function.
	* src/abg-corpus-priv.h (corpus::priv::group): Define new data
	member.
	(corpus::priv::priv): Initialize the new corpus::priv::group data
	member.
	* src/abg-corpus.cc (corpus::{g,s}et_group): Define new member
	functions.
	(corpus_group::get_main_corpus): Likewise.
	(corpus_group::add_corpus): Use the new corpus::set_group() here
	to to make the corpus be aware of the group it belongs to.
	* src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Set the
	current corpus origin to the corpus::LINUX_KERNEL_BINARY_ORIGIN if
	we are looking at a Linux Kernel binary.
	(read_context::main_corpus_from_current_group): Use the
	corpus_group::get_main_corpus method.
	(should_reuse_type_from_corpus_group): Return the corpus group,
	rather than the main corpus.
	(read_debug_info_into_corpus): Add the current corpus to the
	current corpus group before the debug info reading is done.  That
	way, the corpus group will be accessible from the current corpus
	during the construction of the internal representation.
	(read_and_add_corpus_to_group_from_elf): Add the corpus to the
	group only if it wasn't added to it before.
	* include/abg-ir.h (operator{==,!=}): Declare new deep equality
	and inequality operators for class_or_union_sptr and
	union_decl_sptr.
	* src/abg-ir.cc (types_defined_same_linux_kernel_corpus_public):
	Define a new static function.
	(type_base::get_canonical_type_for): Use the new
	types_defined_same_linux_kernel_corpus_public here to speed up
	type comparison.
	(equals): In the overload of class_or_union, use the new
	types_defined_same_linux_kernel_corpus_public as well, to speed up
	type comparison.
	(operator{==,!=}): Define new deep equality and inequality
	operators for class_or_union_sptr and union_decl_sptr.
	(maybe_update_types_lookup_map): In the overload function for
	type_decl_sptr, class_decl_sptr, union_decl_sptr,
	enum_type_decl_sptr, typedef_decl_sptr, qualified_type_def_sptr,
	reference_type_def_sptr, array_type_def_sptr,
	array_type_def::subrange_sptr, and function_type_sptr, update the
	type lookup maps of the containing corpus group as well, not just
	the ones of the current corpus.
	* src/abg-reader.cc (build_enum_type_decl): Forgot to set the
	"is-anonymous" flag.  Oops, fix this.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-17 19:35:38 +02:00
Matthias Maennich
beededda29 Add compatibility layer for C++11 mode
Introduce a compatibility layer for C++11 code by adding
include/abg-cxx-compat.h. abg-cxx-compat defines a new namespace
abg_compat and defines
	abg_compat::hash
	abg_compat::shared_ptr
	abg_compat::weak_ptr
	abg_compat::dynamic_pointer_cast
	abg_compat::static_pointer_cast
	abg_compat::unordered_map
	abg_compat::unordered_set
based on definitions from std::tr1 (std=gnu++98) or std:: (std=gnu++11).

I decided for introducing abg_compat:: rather than polluting abigail::
to allow an easier transition to C++11 at a later time and to not subtly
break existing code.

As the shared_ptr in C++11 defines shared_ptr::operator bool() explicit,
some locations where a shared_ptr is assigned to boolean, needed to be
adjusted to explicitly cast to bool.

	* include/abg-cxx-compat.h: new file introducing the abg_compat
	  namespace to provide C++11 functionality from either std::tr1
	  or std::
	* include/Makefile.am: Add the new abg-cxx-compat.h to source
	  distribution.
	* include/abg-comparison.h: replace std::tr1 usage by abg_compat
	  and adjust includes accordingly: likewise
	* include/abg-diff-utils.h: likewise
	* include/abg-fwd.h: likewise
	* include/abg-ini.h: likewise
	* include/abg-interned-str.h: likewise
	* include/abg-ir.h: likewise
	* include/abg-libxml-utils.h: likewise
	* include/abg-libzip-utils.h: likewise
	* include/abg-reporter.h: likewise
	* include/abg-sptr-utils.h: likewise
	* include/abg-suppression.h: likewise
	* include/abg-tools-utils.h: likewise
	* include/abg-workers.h: likewise
	* src/abg-comp-filter.cc: likewise
	* src/abg-comparison-priv.h: likewise
	* src/abg-corpus.cc: likewise
	* src/abg-dwarf-reader.cc: likewise
	* src/abg-hash.cc: likewise
	* src/abg-ir.cc: likewise
	* src/abg-reader.cc: likewise
	* src/abg-suppression.cc: likewise
	* src/abg-tools-utils.cc: likewise
	* src/abg-writer.cc: likewise
	* tests/test-diff-filter.cc: likewise
	* tests/test-diff-pkg.cc: likewise
	* tests/test-read-dwarf.cc: likewise
	* tests/test-read-write.cc: likewise
	* tests/test-types-stability.cc: likewise
	* tests/test-write-read-archive.cc: likewise
	* tools/abicompat.cc: likewise
	* tools/abidiff.cc: likewise
	* tools/abidw.cc: likewise
	* tools/abilint.cc: likewise
	* tools/abipkgdiff.cc: likewise

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-09 18:05:28 +02:00
Matthias Maennich
c06c45f345 Update tests/.gitignore to ignore runtesttoolsutils
* tests/.gitignore: ignore runtesttoolsutils

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-07-09 17:33:58 +02:00
Matthias Maennich
42cd02a9be Drop requirement to compile with GNU extensions
__gnu_cxx::stdio_filebuf is a GNU extension only available in certain
std libraries. It is not e.g. in libc++. In order to be able to compile
with using libc++, replace the usage of __gnu_cxx::stdio_filebuf with
standard C++ methods. In this case, reopen the temporary file with a
std::fstream and expose that stream rather than the previously exposed
std::iostream.

	* include/abg-tools-utils.h (get_stream): Change return type to
	  std::fstream
	* src/abg-corpus.cc: remove unused #include of ext/stdio_filebuf.h
	* src/abg-tools-utils (temp_file::priv): remove filebuf_ member,
	  and replace iostream_ by fstream_ with changing the shared_ptr
	  type accordingly
	  (temp_file::priv::priv): initialize fstream_ based on
	  temporary file name
	  (temp_file::priv::~priv): adjust destruction accordingly
	  (temp_file::is_good): test the fstream rather than the fd
	  (temp_file::get_stream): adjust return type to std::fstream
	  and adjust implementation based on the changes in temp_file::priv
	* src/Makefile.am: remove gnu extension from c++ standard flag
	* tests/Makefile.am: likewise

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-09 17:16:59 +02:00
Dodji Seketeli
35312fa92a [dwarf-reader] Make sure to canonicalize anonymous types
For a reason, anonymous types are not canonicalized.  I think this is
due to the fact that because they have no name,
read_context::lookup_type_from_die(die) used by maybe_canonicalize_type()
falls short in trying to canonicalize the *DIE*.

So later, at comparison time, things can be really slow because we
can't do canonical comparison; we ressort to structural comparison.

This patch ensures that even anonymous types are canonicalized.

	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Add two new
	overloads.  One that takes type_base_sptr, one that takes a
	Dwarf_Die* and type_base_sptr.  These force canonicalization for
	anonymous types.
	(build_function_type): Schedule function types for
	canonicalization.
	(build_ir_node_from_die): For struct/classes and unions, use the
	new overload of maybe_canonicalize_type to schedule
	canonicalization.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 09:50:29 +02:00
Dodji Seketeli
2209df1b90 Make abidiff --harmless show harmless changes in unions
Since the previous commit filters out harmless changes inside unions,
this one allows those changes to be reported whenever the user runs
abidiff with the --harmless option.

The patch just displays the "before" and "after" of the union because
some of the harmless changes are not tracked anymore.

Because we want to display the before and after of the union we use
the function get_class_or_union_flat_representation.  The patch adds a
"qualified_name" boolean parameter to that function so that we can
choose to display union members names in a non-qualified fashion,
which is the natural way of displaying those names in the context of a
union (or class) representation.  Because
get_class_or_union_flat_representation uses
type_or_decl_base::get_pretty_representation, the patch has also added a
"qualified_name" boolean parameter to that function so that we can
choose to display names in a non-qualified manner.

	* include/abg-fwd.h (get_class_or_union_flat_representation): Add
	a "qualified_name" boolean parameter.
	* include/abg-ir.h ({type_or_decl_base, decl_base, type_decl,
	namespace_decl, array_type_def::subrange_type, array_type_def,
	enum_type_decl, typedef_decl, var_decl, function_decl,
	function_decl::parameter, function_type, method_type, class_decl,
	union_decl}::get_pretty_representation): Likewise.
	* src/abg-ir.cc ({type_or_decl_base, decl_base, type_decl,
	namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl,
	typedef_decl, var_decl, function_decl, function_decl::parameter,
	function_type, method_type, class_decl, union_decl,
	}::get_pretty_representation): Adjust the code to emit qualified
	or non-qualified names depending on the new "qualified_name"
	boolean parameter.
	(get_class_or_union_flat_representation): Likewise.
	* src/abg-default-reporter.cc (default_reporter::report): Use
	get_class_or_union_flat_representation with the new
	"qualified_name" boolean set to false.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Adjust.
	* tests/test-diff-filter.cc (in_out_specs): Run the test harness
	on test-PR24731-v{0,1}.o make abidiff use the --harmless option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-26 12:08:55 +02:00
Dodji Seketeli
a11a0068ea Bug 24731 - Wrongly reporting union members order change
When union data members are re-ordered, abidiff reports the
re-ordering as if it was a meaningful ABI change.

This patch teaches Libabigail to categorize that benign type layout
change as a HARMLESS_UNION_CHANGE_CATEGORY kind of change and ignore it.

	* include/abg-comp-filter.h (union_diff_has_harmless_changes):
	Declare new function and ...
	* src/abg-comp-filter.cc (union_diff_has_harmless_changes):
	... define it here.
	(categorize_harmless_diff_node): Use the new
	union_diff_has_harmless_changes here.
	* include/abg-comparison.h (HARMLESS_UNION_CHANGE_CATEGORY): Add a
	new enumerator to diff_category enum.  Adjust the value of the
	other enumerators.
	* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
	Add the new HARMLESS_UNION_CHANGE_CATEGORY in here.
	(operator<<(ostream& o, diff_category c)): Support the new
	HARMLESS_UNION_CHANGE_CATEGORY.
	* tests/data/test-diff-filter/test-PR24731-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test-PR24731-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v0.c: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v0.o: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v1.c: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v1.o: Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-filter.cc (in_out_spec): Add the new test input
	to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-26 11:09:43 +02:00
Dodji Seketeli
bf100fcb41 Fully account for anonymous-ness of scopes when comparing decl names
When comparing internal decl names (as part of decl comparison), we
need to take into account the fact that a given decl might be
anonymous and that it might have anonymous scopes in its tree of
containing scopes.

For instance, "__anonymous_struct__1::foo" and
"__anonymous_struct__2::foo" are considered equivalent.

So are "__anonymous_struct__1::foo::__anonymous_struct__2::bar" and
"__anonymous_struct__10::foo::__anonymous_struct__11::bar".

But "__anonymous_struct__1::bar::__anonymous_struct__2::baz" and
"__anonymous_struct__10::foo::__anonymous_struct__11::bar" are not.

This patch introduces the function tools_utils::decl_names_equal that
compares fully qualified names by taking into account anonymous
component names.

That function is thus used in the equals() function overload for
decl_base types.  Because tools_utils::decl_names_equal compares strings the
usual way (character by character) it's slower than comparing
instances of interned_string in a O(1) time.  So the patch carefully
tries to use tools_utils::decl_names_equal sparringly; that is, it
uses it only when we are looking at decls that have some anonymous
scope.  That way, we use the fast interned_string comparison most of
the time.  By doing this, we barely see any performance degradation
while running abidw --noout on a full blown vmlinux binary.

	* include/abg-ir.h (decl_base::{get_has_anonymous_parent,
	set_has_anonymous_parent,
	get_is_anonymous_or_has_anonymous_parent}): Declare new member
	functions.
	* src/abg-ir.cc (decl_base::priv::has_anonymous_parent_): Define
	new data member.
	(decl_base::priv): Initialize the new data member.
	(decl_base::{get_has_anonymous_parent, set_has_anonymous_parent,
	get_is_anonymous_or_has_anonymous_parent}): Define new member
	functions.
	(equals): In the overload for decl_base, use the new
	decl_names_equal for decls that have anonymous scopes.
	(scope_decl::add_member_decl): Propagate the
	decl_base::has_anonymous_parent_ property.
	* include/abg-tools-utils.h
	(get_anonymous_struct_internal_name_prefix)
	(get_anonymous_union_internal_name_prefix)
	(get_anonymous_enum_internal_name_prefix, decl_names_equal):
	Declare new functions.
	* src/abg-comp-filter.cc (has_harmless_name_change): Handle the
	case where the name change is actually from an anonymous name to
	another one, using the new decl_names_equal function.
	* src/abg-dwarf-reader.cc
	(get_internal_anonymous_die_prefix_name): Renamed
	get_internal_anonynous_die_base_name into this.  Use the new
	get_anonymous_{struct, union, enum}_internal_name_prefix functions
	here.
	(get_internal_anonymous_die_name, die_qualified_type_name)
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): Adjust.
	* src/abg-tools-utils.cc (get_anonymous_struct_internal_name_prefix)
	(get_anonymous_union_internal_name_prefix)
	(get_anonymous_enum_internal_name_prefix, decl_names_equal):
	Define new functions.
	* tests/test-tools-utils.cc: New test file.
	* tests/Makefile.am: Add new runtesttoolsutils test, built from
	test-tools-utils.cc.
	* tests/data/test-diff-dwarf/test46-rust-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-21 11:42:44 +02:00
Dodji Seketeli
23744b4b8e [dwarf-reader] Better use of linkage name for fn decl de-duplication
When looking at a C program, during function decl DIE de-duplication
at we can rely on linkage names of function declarations to quickly
determine if two function decls are equal, in a given binary.

This patch uses that observation to speed up function decl DIE
de-duplication.  abidw --noout vmlinux goes from 8 to 5 minutes with
this.

	* src/abg-dwarf-reader.cc (read_context::{die_is_in_c,
	die_is_in_c_or_cplusplus}): Define new member functions.
	(fn_die_equal_by_linkage_name): Define new static function.
	(compare_dies): In the case for for DW_TAG_subprogram, use the new
	fn_die_equal_by_linkage_name.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 18:28:12 +02:00
Dodji Seketeli
6149fb02d0 [dwarf-reader] Re-use function types inside a given TU
Whenever we see a function type inside a translation unit, if it
matches one that has already been seen -- i.e, one that has the same
textual representation -- we should be able to re-use that same
function type without having to compare their types to be sure they
are the same, as part of the type canonicalization process.

This slittly increases analysis speed (by a few tens of seconds on a
total of 8 minutes) by decreasing the load on type canonicalization
when anlyzing vmlinux.  It also slightly reduces memory consumption,
so I am getting it in for now.

	* src/abg-dwarf-reader.cc (istring_fn_type_map_type): Declare new
	typedef.
	(die_is_function_type): Define new static function.
	(read_context::per_tu_repr_to_fn_type_maps_): Define new data
	member ...
	(read_context::per_tu_repr_to_fn_type_maps): ... and its accessor.
	(read_context::{associate_die_repr_to_fn_type_per_tu,
	lookup_fn_type_from_die_repr_per_tu}): Define new member
	functions.
	(build_function_type): Use the new
	read_context::lookup_fn_type_from_die_repr_per_tu and
	read_context::associate_die_repr_to_fn_type_per_tu functions,
	instead of read_context::lookup_type_from_die.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 18:28:11 +02:00
Dodji Seketeli
073608f47d Take anonymous scopes into account when comparing decls
This is another attempt at handling anonymous decls comparison.  It's
not the full blown method that I'd like, but this one seems to be fast
enough.  In this method, we take the immediate scope (and whether it's
anonymous or not) of the anonymous decl into account.

	* include/abg-interned-str.h (interned_string::clear): Add new
	member function.
	* src/abg-ir.cc (equals): In the overload for decl_base, consider
	the scope of the current (anonymous) decl.  If that scope is
	anonymous then take that into account as well.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Adjust.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 17:54:45 +02:00
Matthias Maennich
948f27480f abg-writer: Refactor write_corpus API
Introduce a new overload for write_corpus that follows the parameter
order context, object (i.e. corpus), indent.

Deprecate all other overloads that were part of the API and mostly
forward them to the new overload. That effort is made to ensure
write_context is always provided. write_context allows access to all
options that influence the output format.

	* include/abg-writer.h (write_corpus): Introduce new overload
	write_corpus(ctxt, corpus, indent) and deprecate all others.
	* src/abg-writer.cc (write_corpus): Likewise for the definitions
	and adjust.
	* tests/test-read-dwarf.cc (test_task::perform): Use the new
	write_corpus which requires a write_context.
	* tools/abidw.cc (load_corpus_and_write_abixml, ): Likewise.
	* tools/abilint.cc (main): Likewise. Also simplify logic around the
	locations as they now can be expressed with less code.

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Dodji Seketeli
f754d81116 Bug 24552 - abidiff fails comparing a corpus against a corpus group
In this problem report, the issue is that when comparing two corpus
groups, especially when looking up function/variable symbols, the
get_fun_symbol_map() and get_var_symbol_map() member functions used
are corpus::get_{fun,var}_symbol_map, rather than
corpus_group::get_{fun, var}_symbol_map.  Note that the type
corpus_group inherits from the type corpus.  That leads to unexpected
comparison results, especially for symbols.

This patch fixes this by making the corpus::get_{fun, var}_symbol_map
member function be virtual and by using it during the lookup of
function/variable symbols.  That way, the right symbol map gets used.

	* include/abg-corpus.h (corpus{_group}::get_{fun,
	var}_symbol_map): Make these member functions virtual.
	* src/abg-corpus.cc (corpus::lookup_{function, variable}_symbol):
	Use the virtual corpus::get_{fun, var}_symbol_map() member
	function to get the symbols of the current corpus or corpus_group.
	* tests/data/Makefile.am: Add the new test input material below to
	source distribution.
	* tests/data/test-abidiff/test-PR24552-report0.txt: New test input.
	* tests/data/test-abidiff/test-PR24552-v0.abi: Likewise.
	* tests/data/test-abidiff/test-PR24552-v1.abi: Likewise.
	* tests/test-abidiff.cc (main): Support comparing corpus groups.
	(specs): Add the new test inputs to the harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-16 18:10:08 +02:00
Dodji Seketeli
2cf9a18e8c Better handle several anonymous types of the same kind
This is a follow-up patch for the commit:

   43d56de Handle several member anonymous types of the same kind

It allows support for severan anonymous types even when these are not
members of a class/unions.

The patch introduces the concept of a scoped name.  It's a qualified
name for a decl made of the name of the decl appended to the
*unqualified* name of its scope.  Unlike for qualified names, the
scoped name won't have a "__anonymous_*__" string in its name if its
directly containing scope is not anonymous; a qualified name might
still have that string in its name because the decl has a parent scope
(not necessarily its directly containing scope though) that is
anonymous.

The patch goes on to update the logic for comparison of decls that are
anonymous.  For a decl which direct scope is *NOT* anonymous, the
scoped name is what's used in the comparison.  Otherwise, only the
name of the decl is used.

The patch also updates how we detect changes in data members and
member types, in the comparison engine.  It now uses the names of the
data members, rather than their qualified name.  This is in the scope
of the current class/union anyway.  The improvement is that the fact
that the class/union itself is anonymous (even if its anonymous name
changes to another anonymous name) won't have any spurious impact on
the detection of name change of the members.

The patch considers the change of an anonymous decl name which
anonymous name changes to another anonymous name as being harmless.

The patch updates the logic of category propagation in the comparison
engine.  Although a public typedef to private underlying type needs to
stay public and thus not propagate the PRIVATE_TYPE_CATEGORY from its
child diff node to himself, it still needs to suppress the changes to
the private underlying diff node that were suppressed (because of the
private-ness), unless that typedef has local changes.

	* include/abg-ir.h (decl_base::get_scoped_name): Declare new
	member function.
	(scope_decl::get_num_anonymous_member_{classes, unions, enums}):
	Declare new virtual member functions.
	(class_decl::get_num_anonymous_member_{classes, unions, enums}):
	Adjust to make these virtual.  It's not necessary but I feel
	redundancy is a kind of self-documentation here.
	* src/abg-comp-filter.cc (has_harmless_name_change): Consider
	anonymous name changes as harmless.
	* src/abg-comparison.cc
	(class_or_union_diff::ensure_lookup_tables_populated): Consider
	the names of the members rather than their qualified names.
	(suppression_categorization_visitor::visit_end): Suppress the
	changes to the private underlying diff node that were suppressed
	because of the private-ness, unless that typedef has local
	changes.
	* src/abg-dwarf-reader.cc (build_enum_type)
	(add_or_update_class_type, add_or_update_union_type): Handle
	anonymous types in namespaces as well, not just in class/unions.
	* src/abg-ir.cc (decl_base::priv::scoped_name_): Define new data
	member.
	(decl_base::get_scoped_name): Define new member function.
	(equals): For the decl_base overload, use scoped name in the
	comparison, unless the decl belongs to an anonymous type.  For the
	class_or_union_diff, only consider scoped_name during comparison.
	Avoid name comparison between anonymous types.
	(scope_decl::get_num_anonymous_member_{classes, unions, enums}):
	Define new member functions.
	(types_have_similar_structure): Do not compare names between
	anonymous types.
	(qualified_name_setter::do_update): Update scoped names too.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-annotate/libtest23.so.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/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-dwarf/test43-PR22913-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test46-rust-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	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/test33-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test44-anonymous-data-member-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.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/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/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>
2019-05-09 15:19:05 +02:00
Dodji Seketeli
43d56de89b Handle several member anonymous types of the same kind
When there are several anonymous types (e.g, anonymous classes, unions
or enums) in a given class or union, libabigail's internals do
struggle.

An anonymous class, for instance, is named __anonymous_struct__.  When
there are more than one of these inside a given class, then we can't
name and look them up, because they all have the same name.

Incidentally, when add_or_update_class_type completes a class type
that was initially constructed before, it fails to determine that an
anonymous member type of that class was already present in that
context.  It thus wrongly duplicates anonymous structs/unions/enums in
there and that leads to spurious textual (abixml) representation
differences later, where duplicated anonymous member types would
appear intermittently, depending on the order in which the class was
built.

This patch addresses this general issue by naming anonymous member
types in a way that allows several of them to exist. That is, if there
are two anonymous structs in a class, they are going to be named
__anonymous_struct__ and __anonymous_struct__1.  We do follow a
similar scheme for anonymous unions and enums. This is handled by the
DWARF reader that builds the internal representation.

While looking at this issue, I also fixed a tangent bug; some DWARF
emitters wrongly *define* types in the scope of a
DW_TAG_subroutine_type or DW_TAG_array_type.  We handle that by
actually defining those types in the scope of that subroutine or
array.  But then it appears that if that scope itself a class and if
the type defined is an anonymous type, then putting that anonymous
type in the class scope might interfere with the *naming* of the
existing legit anonymous types of that scope.  I decided to put those
anonymous types in the containing namespace instead.  We'll see how
that goes in real time use.

The patch also updates lots of existing tests and adds a new one.

	* include/abg-ir.h
	(class_or_union::get_num_anonymous_member_{classes, unions,
	enums}): Declare new member functions.
	* src/abg-dwarf-reader.cc (get_internal_anonynous_die_base_name)
	(build_internal_anonymous_die_name)
	(get_internal_anonymous_die_name, is_anonymous_type_die): Define
	new static functions.
	(die_qualified_type_name): Use the new
	get_internal_anonymous_die_name.
	(get_scope_for_die): Fix this to put anonymous types that were
	wrongly emitted into the scope of DW_TAG_subroutine_type or
	DW_TAG_array_type by buggy DWARF emitters into the enclosing
	namespace, rather than into the enclosing class/union.
	(build_enum_type): Take the scope of the enum to have a chance to
	properly name potential anonymous enums.
	(lookup_class_typedef_or_enum_type_from_corpus): Take an anonymous
	member type index for when the DIE we are lookup up represents an
	anonymous type.  Support proper building of the internal anonymous
	name of the anonymous type we are lookup up.
	(add_or_update_class_type): Use the new
	get_internal_anonynous_die_base_name and
	build_internal_anonymous_die_name functions.  Support making sure
	that the anonymous member type we are adding to the class wasn't
	already there, especially for cases where we are updating a class
	type.
	(add_or_update_union_type): Use the new
	get_internal_anonynous_die_base_name and
	build_internal_anonymous_die_name functions.
	(build_ir_node_from_die): Adjust the use of build_enum_type to
	pass it the scope of the enum type we are building.
	* src/abg-ir.cc	(lookup_union_type): Add a new overload.
	(lookup_class_or_typedef_type): Use the new overload of
	lookup_union_type above to support looking up union types too.
	(class_or_union::get_num_anonymous_member_{classes, unions,
	enums}): Define new member functions.
	* src/abg-reporter-priv.cc (represent): Detect when anonymous
	types of anonymous data members have their internal names change,
	probably because anonymous member types were inserted in the scope.
	* tests/data/Makefile.am: Add the new test-anonymous-members-0.*
	test input files to the source distribution.
	* tests/data/test-annotate/test-anonymous-members-0.cc: New test
	input file.
	* tests/data/test-annotate/test-anonymous-members-0.o: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* 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/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.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/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/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/test-annotate.cc (int_out_specs): Add the new test inputs
	to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-07 14:31:16 +02:00
Dodji Seketeli
eafa097433 Use canonical types hash maps for type IDs in abixml writer
This patch stores canonical types in the hash maps that are used in
the abixml writer to compute the type IDs.  This limits the
possibility that two types that are equivalent (especially when one is
a declaration-only class) end-up in the same abixml.

	* src/abg-writer.cc (write_context::{type_has_existing_id,
	get_id_for_type}): Save the canonical type of the type in the map,
	not the type itself.
	(write_context::{type_is_emitted}): Use the canonical type rather
	than the type itself.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 17:52:39 +02:00
Dodji Seketeli
04d61a726d Don't try to de-duplicate all anonymous struct DIEs
Trying to de-duplicate anonymous struct DIEs can lead to subtle
issues, because there can be two different naming typedefs designating
two anonymous structs that are equivalent, in the same translation
unit.  In that case, de-duplicating the two leaf anonymous structs
DIEs leads to non-resolvable conflict.

This patch avoids de-duplicating anonymous structs DIEs and rather
de-duplicates (naming) typedefs.

	* include/abg-fwd.h (is_typedef): Remove the overloads for
	type_base_sptr and decl_base_sptr.  Replace those with an overload
	for type_or_decl_base_sptr.
	* src/abg-ir.cc (is_typedef): Do the same for the definitions.
	* src/abg-dwarf-reader.cc (add_or_update_class_type)
	(add_or_update_union_type): Do not de-duplicate anonymous
	struct/union DIEs.
	(build_typedef_type): Try to de-duplicate typedefs DIEs.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.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/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 16:59:35 +02:00
Dodji Seketeli
451d34d1ad Canonicalize types non tied to any DWARF DIE
During DWARF reading, it can happen that some types are created that
are not tied to a given DIE.  This happens for instance when editing
the internal representation of types to better reflect the intent of
the code rather than the letter of the code; more precisely this
happens when a qualified array is edited to represent an array of
qualified elements, for instance.  In that case, the qualified element
type is created by the DWARF analyser.  And in the present incarnation
of the code, we forget to canonicalize that type.

The fact that that type is not canonicalized leads to cases where two
equivalent types can still be present in a translation unit in the
resulting abixml representation, without the abixml writer noticing
it.  That duplication can lead to unnecessary cycles in the type graph
where passes can either take one side or the other of the cycle; and
that leads to subtle heisen-changes in the emitted abixml representation.

This patch thus canonicalizes those newly created types.

	* src/abg-dwarf-reader.cc
	(read_context::extra_types_to_canonicalize_): Add new data member.
	(read_context::{initialize, clear_types_to_canonicalize}): Adjust.
	(read_context::extra_types_to_canonicalize): Create new accessor.
	(read_context::schedule_type_for_late_canonicalization): Add new
	overload for type_base_sptr.
	(read_context::perform_late_type_canonicalizing): Perform the
	canonicalization of the types created by the DWARF analyzer, but
	that are not tied to any DIE.
	(maybe_strip_qualification): Take a read_context&.  Schedule newly
	created types (during type edition) for late canonicalization.
	(build_ir_node_from_die): Adjust the call to
	maybe_strip_qualification to pass a read_context.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.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/test17-pr19027.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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 16:28:42 +02:00
Matthias Maennich via libabigail
b01918eb18 Update .gitignore files to ignore typical dev side products
Add / update .gitignore files for tests/ and tools to ignore
binaries, logs, traces typically produced during development.

 * tests/.gitignore: exclude tests binaries and test results
 * tools/.gitignore: update to ignore produced binaries

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-04-16 16:32:52 +02:00
Matthias Maennich via libabigail
eec8e69b7d abilint: fix return types bool -> int
Returning bool literals from main can be misleading. Returning booleans
maps to (by convention):

   return false -> converted to 0 -> rc=0 considered SUCCESS
   return true  -> converted to 1 -> rc=1 considered FAILURE

Compiling with clang also emits:

  abilint.cc:258:7: warning: bool literal returned from 'main' [-Wmain]
      return true;
      ^      ~~~~

The issues can be addressed by consistently returning integers as also
done in all other mains across the project.

Same issue applies to print-diff-tree.cc.

 * tools/abilint.cc: return int in main rather than bool.
 * tests/print-diff-tree.cc: Likewise.

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-04-16 16:11:01 +02:00
Dodji Seketeli
286cadf841 Bug 24430 - Fold away const for array types
In C and C++ the qualifiers of a qualified array type apply to the
element type of said array.

In this particular problem report, GCC and Clang emit DWARF that
represent the qualifiers either on the array type, or on the element
type.  Quoting the test of the bug:

    Given the following example:

	struct test {
	  const char asdf[4];
	};

	void func(struct test arg) {}

    abidiff says:

     1 function with some indirect sub-type change:

       [C]'function void func(test)' at test.c:5:1 has some indirect sub-type
     changes:
	 parameter 1 of type 'struct test' has sub-type changes:
	   type size hasn't changed
	   1 data member change:
	    type of 'const char test::asdf[4]' changed:
	      entity changed from 'const char[4]' to 'const char[4] const'

This is because GCC represents the array as const array of const
signed char, whereas clang represents it as an array of const signed
char.

In this patch, libabigail's DWARF reader detects qualified array types
and appropriately qualifies the array element type, instead of
qualifying the array type.  The patch accordingly adjusts the various
regression tests and adds a new test which comes from the problem
report.

	* include/abg-fwd.h (is_array_of_qualified_element): Declare 2
	overloads of this function.
	(re_canonicalize): Declare a new function.
	* include/abg-ir.h (class {decl_base, type_base}): Declare
	re_canonicalize as a friend of these classes.
	* src/abg-dwarf-reader.cc (maybe_strip_qualification): Detect
	qualified array types and appropriately qualifies the array
	element type, instead of qualifying the array type itself.
	Re-canonicalize the resulting type if necessary.
	* src/abg-ir.cc (is_array_of_qualified_element): Define 2
	overloads of this function.
	(re_canonicalize): Define new function.
	* tests/data/Makefile.am: The two new test binary input files
	PR24430-fold-qualified-array-clang and
	PR24430-fold-qualified-array-gcc to source distribution, as well
	as the expected reference output.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-clang:
	New binary test input coming from the bug report.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-gcc:
	Likewise.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-report-0.txt:
	Expected reference abi difference.
	* tests/data/test-diff-filter/test33-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.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/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.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/test-diff-filter.cc: Add the new binary test input to this
	test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-10 13:02:36 +02:00
Dodji Seketeli
80bbf3dd62 Fix "Add test for the fix for PR24410"
Oops, seems like I forgot to add some of the binaries.

There you go.

	* tests/data/test-diff-pkg/PR24410-new/poppler-debuginfo-0.73.0-8.fc30.x86_64.rpm:
	Really add this.
	* tests/data/test-diff-pkg/PR24410-new/poppler-qt5-0.73.0-8.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-new/poppler-qt5-debuginfo-0.73.0-8.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-new/poppler-qt5-devel-0.73.0-8.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-old/poppler-debuginfo-0.73.0-4.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-old/poppler-qt5-0.73.0-4.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-old/poppler-qt5-debuginfo-0.73.0-4.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-old/poppler-qt5-devel-0.73.0-4.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24410-report-0.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-09 11:16:12 +02:00
Dodji Seketeli
e54191eac9 Add test for the fix for PR24410
PR24410 was fixed by these recent commits:

    1b83138 Propagate private type diff category through refs/qualified type diffs
    dc84fee Fix anonymous union constructed under the wrong context
    522ac25 Internal pretty repr of union cannot be flat representation

But then I forgot to add a regression test for that issue.

This patch does that.

	* tests/data/test-diff-pkg/PR24410-new/poppler-debuginfo-0.73.0-8.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-new/poppler-qt5-0.73.0-8.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-new/poppler-qt5-debuginfo-0.73.0-8.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-new/poppler-qt5-devel-0.73.0-8.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-old/poppler-debuginfo-0.73.0-4.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-old/poppler-qt5-0.73.0-4.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-old/poppler-qt5-debuginfo-0.73.0-4.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-old/poppler-qt5-devel-0.73.0-4.fc30.x86_64.rpm:
	Add new test input.
	* tests/data/test-diff-pkg/PR24410-report-0.txt: Add new test
	input.
	* tests/data/Makefile.am: Add the test input above to source
	distribution.
	* tests/test-diff-pkg.cc: Make this test harness use the new input
	rpms above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-09 11:02:53 +02:00
Dodji Seketeli
1b831382d0 Propagate private type diff category through refs/qualified type diffs
This patch is the third of the series:

    Internal pretty repr of union cannot be flat representation
    Fix anonymous union constructed under the wrong context
    Propagate private type diff category through refs/qualified type diffs

The intent of this series is to fix the bug:

    https://sourceware.org/bugzilla/show_bug.cgi?id=24410
    "Empty change report emitted for libpoppler-qt5.so.1.18.0"

We (mistakenly) don't propagate private type diff categories through
reference and qualified type diffs.  This leads to some diff nodes not
being suppressed just because they are private type diffs which
category weren't properly propagated.

This patch fixes this.

Note that the tests updated in this patch reflect the regression tests
changes needed for the entire set of 3 patches.

	* src/abg-comparison.cc
	(suppression_categorization_visitor::visit_end): Propagate
	suppressed and private type diff categories for reference and
	qualified types.  For qualified types, make sure they don't have
	local changes.  Even when there are no local changes, do not
	propagate private diff categories to typedefs.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.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/test17-pr19027.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>
2019-04-08 11:30:45 +02:00
Dodji Seketeli
5bb7194b0a Bug 24378 - DW_TAG_subroutine_type as a DIE scope causes infinite loop
GCC 4.3.2 wrongly emits some type definition DIEs in the scope of a
DW_TAG_subroutine_type.  Whenever the DWARF reader tries to get the
scope of a DIE during the computation of the pretty name of a type DIE
which scope is (wrongly) emitted as being a DW_TAG_subroutine_type
things end-up in an infinite loop.

This patch makes get_scope_die to look through the
DW_TAG_subroutine_type to return the proper scope instead, just like
what we already do for DW_TAG_subprogram and DW_TAG_array_type.

	* src/abg-dwarf-reader.cc (get_scope_die): Look through
	DW_TAG_subroutine_type to get the scope of a given DIE.
	* tests/data/Makefile.am: Add the two new files below to source
	distribution.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi: New
	reference test output.
	* tests/data/test-read-dwarf/PR24378-fn-is-not-scope.o: New binary
	test input.
	* tests/test-read-dwarf.cc (in_out_specs): Add the new test input
	to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-03-25 14:46:31 +01:00