platform/upstream/libabigail.git
5 years agoabg-writer: Refactor write_corpus API
Matthias Maennich [Tue, 21 May 2019 04:39:16 +0000 (05:39 +0100)]
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>
5 years agoabg-writer: Refactor write_translation_unit API
Matthias Maennich [Tue, 21 May 2019 04:39:15 +0000 (05:39 +0100)]
abg-writer: Refactor write_translation_unit API

Introduce a new overload for write_translation_unit that follows the
parameter order context, object (i.e. translation unit), indent.

Deprecate all other overloads that were part of the API and mostly
forward them to the new one. 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_translation_unit): Declare a new
overload write_translation_unit(ctxt, tu, indent) and deprecate
all others.
* src/abg-writer.cc (write_translation_unit): Likewise in the
definitions.
(write_corpus, dump, write_translation_unit): Adjust.
* tools/abilint.cc (main): use new write_translation_unit() API

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoAdd deprecation facilities
Matthias Maennich [Tue, 21 May 2019 04:39:14 +0000 (05:39 +0100)]
Add deprecation facilities

Add the macro 'ABG_DEPRECATED' to mark APIs as to be removed in a next
major release. APIs marked with that flag are supposed to work as
before, but might come with downsides. E.g. they could perform worse or
provide only limited functionality. All deprecated functions shall come
with a hint to equivalent functionality within the non-deprecated part
of the API.

* include/abg-fwd.h: Introduce deprecation macro ABG_DEPRECATED

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoabg-writer: Simplify 'annotate' propagation
Matthias Maennich [Tue, 21 May 2019 04:39:13 +0000 (05:39 +0100)]
abg-writer: Simplify 'annotate' propagation

'annotate' is one of many flags that could potentially influence the
way, output is written. Remove the default parameter from
write_context's constructor and let users explicitely set that flag on
the context.

* src/abg-writer.cc (write_context::write_context): remove
'annotate' parameter.
(write_translation_unit, write_corpus, write_corpus_group, dump): Adjust.

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoAdd .clang-format approximation
Matthias Maennich [Wed, 15 May 2019 17:34:04 +0000 (18:34 +0100)]
Add .clang-format approximation

Add .clang-format definitions that are an approximation of the current
coding style. As I understand it, the current style is based on what GNU
Emacs implements for C++. Hence these rules might not be entirely
accurate, but a good-enough approximation to allow contributers to
follow the coding style more easily.

I expect modifications for specific cases and when clang-format itself
evolves over time.

As of now, this definition is most useful in partial code formatting,
such as executed by `git clang-format` on staged files or
clang-format.py as a means of integration into various editors.

* .clang-format: New File.

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoBug 24552 - abidiff fails comparing a corpus against a corpus group
Dodji Seketeli [Thu, 16 May 2019 15:23:40 +0000 (17:23 +0200)]
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>
5 years agoBug 24560 - Assertion failure on an abixml with an anonymous type
Dodji Seketeli [Wed, 15 May 2019 10:46:56 +0000 (12:46 +0200)]
Bug 24560 - Assertion failure on an abixml with an anonymous type

When reading an abixml file, we should not try to re-use an anonymous
class, union or enum because by construction two anonymous unions of
the same (internal) name don't necessarily designate the same type.
We already do that in the ELF/DWARF reader so we need to update the
abixml reader too.

Fixed thus.

* src/abg-reader.cc (read_context::maybe_canonicalize_type): Delay
canonicalization of union types too.
(build_class_decl, build_union_decl): Do not try to re-use
anonymous types.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoHandle Linux kernel binaries with no __ksymtab section
Dodji Seketeli [Mon, 13 May 2019 12:54:20 +0000 (14:54 +0200)]
Handle Linux kernel binaries with no __ksymtab section

Some Linux kernel binaries can have no __ksymtab section.  It's
possible that only have a __ksymtab_gpl section or no __ksymtab_gpl
either.  And apparently they can also have a __ksymtab* section full
of zeroes.

This patch gets the ELF/DWARF reader prepared to handle these cases.

* src/abg-dwarf-reader.cc (find_section): Use elf_getshdrstrndx
rather than poking at the elf header on our own.
(read_context::find_any_ksymtab_section): Define new member
function.
(read_context::{get_symtab_format,
try_reading_first_ksymtab_entry_using_pre_v4_19_format}): Use the
new find_any_ksymtab_section rather than find_ksymtab_section.
(read_context::get_nb_ksymtab_entries): Handle the absence of
__ksymtab.
(read_context::get_nb_ksymtab_gpl_entries): Handle the absence of
__ksymtab_gpl.
(read_context::load_kernel_symbol_table): Handle the case of zero
ksymtab entries.
(read_context::{maybe_adjust_address_for_exec_or_dyn,
maybe_adjust_fn_sym_address, load_kernel_symbol_table}): Handle an
address that is zero.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix logic of get_binary_load_address
Dodji Seketeli [Fri, 10 May 2019 12:10:25 +0000 (14:10 +0200)]
Fix logic of get_binary_load_address

The value of the of the pointer to program header returned by
gelf_getphdr is always the same, assuming the value of the last
parameter to gelf_getphdr stays the same.  What changes is what is
pointed to by that pointer.  So rather than storing the the program
header (to determine the lowest load address among several program
headers returned by gelf_getphdr) we need to store the load address
pointed to by the pointer to the program header.

Thanks to Matthias Männich for spotting this and discussing it at
https://sourceware.org/ml/libabigail/2019-q2/msg00064.html.

Testing this is a bit annoying as we'd need to consider a prelinked binary which has
split debuginfo.  I should probably add such a binary to the regression
test suite at some point.

* src/abg-dwarf-reader.cc (get_binary_load_address): Consider the
load address pointed to by the program header pointer returned by
gelf_getphdr rather than the program header itself.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24431 Treat __ksymtab as int32_t for v4.19+ kernels
maennich@google.com [Fri, 10 May 2019 01:00:41 +0000 (02:00 +0100)]
Bug 24431 Treat __ksymtab as int32_t for v4.19+ kernels

Calculating the relocation for values in __ksymtab with GElf_Addr (i.e.
uint64_t), makes the calculation rely on overflows for negative offsets.
Address that by treating these as 32bit signed values for the v4.19+
__ksymtabs and calculate the offset with them. This also allows, similar
an earlier commit, to drop the distinction between 64bit and 32bit
kernels.

* src/abg-dwarf-reader.cc (maybe_adjust_sym_address_from_v4_19_ksymtab):
treat passed addr as 32bit signed offset in case of v4.19+ __ksymtabs

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoBug 24431 Read 32bit values when testing for the v4.19 symbol table format
maennich@google.com [Fri, 10 May 2019 01:00:40 +0000 (02:00 +0100)]
Bug 24431 Read 32bit values when testing for the v4.19 symbol table format

Reading into uint64_t when reading the symbol table values drops the
sign and subsequently offset calculations will only be correct if either
the offset is positive or if the calculation overflows.

Read the relative value as signed int32_t (indepently of the target's
bitness) to allow negative offsets.  That also allows to drop the code
that formerly handled the overflow.

That change fixes an assertion raised when dealing with aarch64 kernel
binaries that have a __ksymtab with 32bit relocations. i.e. Bug #24431

* src/abg-dwarf-reader.cc
(try_reading_first_ksymtab_entry_using_v4_19_format): attempt to
read first __ksymtab entry into int32_t to preserve sign

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agodwarf-reader: templatize read_int_from_array_of_bytes
maennich@google.com [Fri, 10 May 2019 01:00:39 +0000 (02:00 +0100)]
dwarf-reader: templatize read_int_from_array_of_bytes

Making the return value type a template type allows for signed types to
be passed and successfully interpreted.

* src/abg-dwarf-reader.cc (read_int_from_array_of_bytes):
templatize return type to allow passing of signed integer references

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agodwarf-reader: Fix comments for try_reading_first_ksymtab_entry_using_{pre_,}v4_19_format
maennich@google.com [Fri, 10 May 2019 01:00:38 +0000 (02:00 +0100)]
dwarf-reader: Fix comments for try_reading_first_ksymtab_entry_using_{pre_,}v4_19_format

Swap the descriptive comments for the two functions.

* src/abg-dwarf-reader.cc: swap the comments of
try_reading_first_ksymtab_entry_using_{pre_,}v4_19_format

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoBetter handle several anonymous types of the same kind
Dodji Seketeli [Thu, 9 May 2019 13:19:05 +0000 (15:19 +0200)]
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>
5 years agoHandle several member anonymous types of the same kind
Dodji Seketeli [Tue, 7 May 2019 08:22:29 +0000 (10:22 +0200)]
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>
5 years agoUse canonical types hash maps for type IDs in abixml writer
Dodji Seketeli [Wed, 24 Apr 2019 15:52:39 +0000 (17:52 +0200)]
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>
5 years agoDon't try to de-duplicate all anonymous struct DIEs
Dodji Seketeli [Wed, 24 Apr 2019 14:20:30 +0000 (16:20 +0200)]
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>
5 years agoCanonicalize types non tied to any DWARF DIE
Dodji Seketeli [Wed, 24 Apr 2019 13:52:04 +0000 (15:52 +0200)]
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>
5 years agoDon't try to read a build_id as string in find_alt_debug_info_link.
Mark Wielaard [Thu, 18 Apr 2019 15:41:41 +0000 (17:41 +0200)]
Don't try to read a build_id as string in find_alt_debug_info_link.

The GCC8 address sanitizer found an issue in find_alt_debug_info_link.
It tried to convert a build-id byte sequence into a string. But the
build-id byte sequence is not a zero terminated sequence of chars.
So it could run off way past the section data.

The code never actually uses the build-id. It could use it to verify
the referenced alt-file is the correct one. But since it uses elfutils
to actually load the alt file it doesn't have to, since elfutils will
already check the build-id matches.

So just remove the build_id argument from find_alt_debug_info_link
and don't try to convert and return it as a string.

* src/abg-dwarf-reader.cc (find_alt_debug_info_link): Remove
build_id argument. Don't try to read the buildid chars as a
string.
(find_alt_debug_info): Don't call find_alt_debug_info_link
with a build_id string argument.

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix an undefined behaviour in has_var_type_cv_qual_change
Mark Wielaard [Thu, 18 Apr 2019 14:24:15 +0000 (16:24 +0200)]
Fix an undefined behaviour in has_var_type_cv_qual_change

* src/abg-comp-filter.cc: (has_var_type_cv_qual_change):
Initialize the ch_kind variable before using it.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd --enable-{asan,ubsan} configure options
Dodji Seketeli [Thu, 18 Apr 2019 13:46:34 +0000 (15:46 +0200)]
Add --enable-{asan,ubsan} configure options

Add options to enable building with -fsanitize=address or
-fsanitize=undefined.

* configure.ac: Add configure options for -fsanitize=address and
-fsanitize=undefined.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoabg-tools-utils.cc: Plug a leak in find_file_under_dir
Dodji Seketeli [Thu, 18 Apr 2019 12:44:30 +0000 (14:44 +0200)]
abg-tools-utils.cc: Plug a leak in find_file_under_dir

We were forgetting to call fts_close on a file hierarchy returned by
fts_open.  Plugged thus.

* src/abg-tools-utils.cc (find_file_under_dir): Call fts_close
before return.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agodwarf-reader: fix undefined behaviour in get_binary_load_address
Matthias Maennich [Thu, 18 Apr 2019 09:33:34 +0000 (11:33 +0200)]
dwarf-reader: fix undefined behaviour in get_binary_load_address

Within the loop, the call `gelf_getphdr(elf_handle, i, &ph_mem)` is
returning a pointer to `ph_mem` that is only valid in this loop
iteration. The later assignment to *lowest_program_header and its
eventual use to assign load_address leads to undefined behaviour.

* src/abg-dwarf-reader.cc (get_binary_load_address): Move the
ph_mem and program_header variables out of the inner for-loop.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoDelay canonicalization for array and qualified types
Dodji Seketeli [Thu, 18 Apr 2019 09:26:44 +0000 (11:26 +0200)]
Delay canonicalization for array and qualified types

Array and qualified types can be edited after they are built, e.g, to
fold the qualifiers of the array as those should always apply to the
element types of the array, at least in C and C++.  So we need to
delay the canonicalization of these types until *after* all that type
editing is done.  We were not doing that properly and I suspect this
is the cause of some "heisenregressions" we are seeing on some
platforms intermittently.

This patch does delay the type canonicalization and insures that we
don't edit types that are canonicalized already.

* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Delay the
canonicalization of array and qualified types, just like what we
do for classes and function types already.
(maybe_strip_qualification):  Do not
re-canonicalize array and qualified types here because it should
not be necessary anymore.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix a memory leak in real_path
Dodji Seketeli [Thu, 18 Apr 2019 09:18:31 +0000 (11:18 +0200)]
Fix a memory leak in real_path

Running the testsuite with AddressSanitizer turned on flagged a memory
leak in real_path, in abg-tools-utils.cc.

Fixed thus.

* src/abg-tools-utils.cc (real_path): Fee the returned pointer of
realpath.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoEnable building with AddressSanitizer activated
Dodji Seketeli [Thu, 18 Apr 2019 09:01:47 +0000 (11:01 +0200)]
Enable building with AddressSanitizer activated

With this patch, configuring the project with the environment variables
ABIGAIL_DEVEL=on and ABIGAIL_DEVEL_ASAN=on will turn on
AddressSanitizer.

* configure.ac: If ABIGAIL_DEVEL_ASAN=on (in addition to
ABIGAIL_DEVEL=on), then turn on AddressSanitizer in the build.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24431 - ELF reader fails to determine __ksymtab format
Dodji Seketeli [Wed, 17 Apr 2019 05:40:43 +0000 (07:40 +0200)]
Bug 24431 - ELF reader fails to determine __ksymtab format

This is a fallout from this commit:

 ad8c253 Bug 24431 - ELF reader can't interpret ksymtab with Kernel 4.19+

The problem is that the method used to determine if the format of the
__ksymtab section is pre or post v4.19.  In that commit, we assumed
that a kernel without relocations for the __ksymtab section implies a
v4.19 format, because in that format, we don't need relocations for
that section.  But then it can happen that the entire kernel be built
without relocations, in the case a non relocatable kernels.  So just
looking a the presence of relocations is not a good enough
discriminant to determine the format of the __ksymtab section.

This patch rather tries to read the first entry of the __ksymtab
section assuming a pre v4.19 format, comes up with an address, and
then looks the .symtab section up with that address.  If the lookup
succeeds and we find a symbol, then we can reasonably assume that the
__ksymtab section is in the v4.19 format.  Otherwise, we do the same
assuming a v4.19 format, etc.

Tested on v4.9, v4.16 and v4.16 kernels in 32 and 64 bits.

* src/abg-dwarf-reader.cc
(read_context::{try_reading_first_ksymtab_entry_using_pre_v4_19_format,
try_reading_first_ksymtab_entry_using_v4_19_format}): Define new
member functions.
(read_context::maybe_adjust_sym_address_from_v4_19_ksymtab): Make
member function this const.
(read_context::get_ksymtab_format): Implement the new heuristic
here, using try_reading_first_ksymtab_entry_using_pre_v4_19_format
and try_reading_first_ksymtab_entry_using_v4_19_format, rather
than assuming that if we have no relocations, then we are in the
v4.19 format.
(maybe_adjust_sym_address_from_v4_19_ksymtab): When on a 64 bits
architecture, ensure the 32 bits address read from the v4.19
format __ksymtab section is converted into a 64 bits address.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate .gitignore files to ignore typical dev side products
Matthias Maennich via libabigail [Mon, 15 Apr 2019 09:42:15 +0000 (10:42 +0100)]
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>
5 years agodwarf-reader: fix recursion in expr_result::operator&
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:22 +0000 (18:05 +0100)]
dwarf-reader: fix recursion in expr_result::operator&

operator& was implemented in terms of itself, leading to infinite
recursion. Fix that by implementing it in terms of &='ing the const
value. That is consistent with all other ?= operators.

 * src/abg-dwarf-reader.cc: fix expr_result::operator&

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agodistinct_diff: avoid expression with side effects within typeid
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:21 +0000 (18:05 +0100)]
distinct_diff: avoid expression with side effects within typeid

When compiling with clang, the following warning is emitted:

abg-comparison.cc:2674:17: warning: expression with side effects will be
evaluated despite being used as an operand to 'typeid' [-Wpotentially-evaluated-expression]
  return typeid(*first.get()) != typeid(*second.get());
                ^

Mitigate that warning by moving potential side effects out of typeid.

 * src/abg-comparison.cc: fix clang warning "potentially-evaluated-expression"

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoir: drop unused data members from {environment,qualified_name}_setter
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:20 +0000 (18:05 +0100)]
ir: drop unused data members from {environment,qualified_name}_setter

The data members environment_setter::artifact_ and
qualified_name_setter::node_ are not used and can therefore be dropped
along with all their references.

 * src/abg-ir.cc: drop unused data members

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agosuppressions: drop unused parameter from type_is_suppressed
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:19 +0000 (18:05 +0100)]
suppressions: drop unused parameter from type_is_suppressed

Drop 'require_drop_property' as it is not used at all.
That fixes a clang warning.

 * include/abg-suppression-priv.h: drop unused argument from type_is_suppressed

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoviz-dot: remove unused members from dot
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:18 +0000 (18:05 +0100)]
viz-dot: remove unused members from dot

_M_canvas and _M_typo are unused within "dot". Remove them and all
references.

 * include/abg-viz-dot.h: remove unused data members from 'dot'

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoadd missing virtual destructors
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:17 +0000 (18:05 +0100)]
add missing virtual destructors

Several virtual desctructors were missing. Even though there might not
have been actual leaks or similar bugs, it is worth fixing these
locations as they might lead to bugs in the future.

Clang also warns at these locations:

  warning: delete called on non-final 'abigail::ir::corpus' that has virtual
  functions but non-virtual destructor [-Wdelete-non-virtual-dtor]

 * include/abg-comparison.h: add virtual destructor for corpus_diff and diff_node_visitor
 * include/abg-corpus.h: add virtual destructor for corpus
 * include/abg-reporter.h: add virtual destructor for reporter_base
 * include/abg-traverse.h: add virtual destructor for traversable_base

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agodiff-utils: point: fix postfix decrement/increment operator
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:16 +0000 (18:05 +0100)]
diff-utils: point: fix postfix decrement/increment operator

The postfix increment / decrement operators were implemented by calling
themselves recursively. Fix that by implementing these in terms of their
prefix counter parts.

 * include/abg-diff-utils.h: fix postfix dec/inc operator

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoabg-reader: clarify boolean use of assignment
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:15 +0000 (18:05 +0100)]
abg-reader: clarify boolean use of assignment

When compiling with clang, the following warning is emitted:

abg-reader.cc:1981:15: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
  while (corp = read_corpus_from_input(ctxt))
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

That is certainly a common pitfall and can be mitigated by placing
parentheses around the assignment.

 * src/abg-reader.cc: clarify boolean use of assignment

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoabilint: fix return types bool -> int
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:14 +0000 (18:05 +0100)]
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>
5 years agoabg-fwd.h: fix mismatched tags for ir_node_visitor
Matthias Maennich via libabigail [Mon, 15 Apr 2019 17:05:13 +0000 (18:05 +0100)]
abg-fwd.h: fix mismatched tags for ir_node_visitor

ir_node_visitor is defined as `class` in include/abg-ir.h:4429 and
should therefore also be forward-declared as such.

 * include/abg-fwd.h: forward-declare ir_node_visitor as class

Signed-off-by: Matthias Maennich <maennich@google.com>
5 years agoBug 24431 - ELF reader can't interpret ksymtab with Kernel 4.19+
Dodji Seketeli [Tue, 16 Apr 2019 11:42:05 +0000 (13:42 +0200)]
Bug 24431 - ELF reader can't interpret ksymtab with Kernel 4.19+

Since the commit
https://github.com/torvalds/linux/commit/7290d58095712a89f845e1bca05334796dd49ed2
of the kernel, the format of the ksymtab section changed, so the ELF
reader of Libabigail cannot get the list of kernel symbols that are
meaningful to analyze.

In the new format, each ksymtab entry is now 32 bits length,
independently of if the kernel was built in 32 or 64 bits mode.  This
way, 64 bit kernels save 32 bits per entry, from the ksymtab section
alone.

Also, note that the symbol address in the ksymtab entry is stored in a
"place-relative address" format.  That means for a given symbol value
'Sym_Addr', the value which is stored at a given offset 'Off' of the
ksymtab secthion which address is Ksymtab_Addr is:

  Sym_Addr - Ksymtab_Addr - Off.

This is what is meant by storing Sym_Addr in a "place-relative" manner.

One advantage, of course, is to make Sym_Addr take 32 bits, even on a
64 bits arch.  Another advantage is that the resulting value doesn't
need to be relocated!  So we don't need any relocation section either!
So lots of space saving.

This patch teaches the ELF reader into this new format.

* src/abg-dwarf-reader.cc (enum kernel_symbol_table_kind): Move this
enum at the top.
(enum ksymtab_format): Define new enum.
(read_context::{ksymtab_format_, ksymtab_entry_size_,
nb_ksymtab_entries_, nb_ksymtab_gpl_entries_}): Define new data
members.
(read_context::initiliaze): Initialize the new data members above.
(read_context::{get_ksymtab_format, get_ksymtab_symbol_value_size,
get_ksymtab_entry_size, get_nb_ksymtab_entries,
get_nb_ksymtab_gpl_entries,
maybe_adjust_sym_address_from_v4_19_ksymtab}): Define new member
functions.
(read_context::load_kernel_symbol_table): Support loading from
both pre and post v4.19 linux kernels with their different ksymtab
formats.  Add more comments.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24430 - Fold away const for array types
Dodji Seketeli [Wed, 10 Apr 2019 10:51:13 +0000 (12:51 +0200)]
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>
5 years agoFix "Add test for the fix for PR24410"
Dodji Seketeli [Tue, 9 Apr 2019 09:12:41 +0000 (11:12 +0200)]
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>
5 years agoAdd test for the fix for PR24410
Dodji Seketeli [Tue, 9 Apr 2019 08:35:42 +0000 (10:35 +0200)]
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>
5 years agoPropagate private type diff category through refs/qualified type diffs
Dodji Seketeli [Fri, 5 Apr 2019 11:55:07 +0000 (13:55 +0200)]
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>
5 years agoFix anonymous union constructed under the wrong context
Dodji Seketeli [Fri, 5 Apr 2019 09:42:38 +0000 (11:42 +0200)]
Fix anonymous union constructed under the wrong context

This patch is second 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"

What happens here is that when the DWARF reader sees an anonymous
union/struct, it can mistakenly think that it has seen it before
(because the comparison doesn't take the scope of the union/struct
into account), and thus mistakenly represent the union/struct.

The solution implemented by this patch is to take the scope of the
anonymous union/struct into account.

Note that regression tests are all updated in the last patch of the
series.

* src/abg-dwarf-reader.cc (add_or_update_class_type)
(add_or_update_union_type): Only reuse anonymous class/union types
which have the same scope as the current one.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoInternal pretty repr of union cannot be flat representation
Dodji Seketeli [Mon, 8 Apr 2019 09:17:09 +0000 (11:17 +0200)]
Internal pretty repr of union cannot be flat representation

This is the first patch of this 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"

The internal pretty representation of a union must be its fully
qualified name, even when it's a anonymous union.  It cannot be its
flat representation as for anonymous unions, that would lead to
confusion between anonymous unions that have the same flat
representation but are in different scopes.

Fixed thus.

Note that regression tests are all updated in the last patch of the
series

      * src/abg-ir.cc (union_decl::get_pretty_representation):
        Anonymous internal pretty representation of unin is its fully
        qualified name.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoMisc comment fixes
Dodji Seketeli [Mon, 8 Apr 2019 09:15:39 +0000 (11:15 +0200)]
Misc comment fixes

* src/abg-comp-filter.cc (has_harmless_name_change): Fix comment.
* src/abg-ir.cc (var_decl::get_qualified_name): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBump version number to 1.7
Dodji Seketeli [Fri, 29 Mar 2019 16:32:06 +0000 (17:32 +0100)]
Bump version number to 1.7

* configure.ac: Bump version number to 1.7

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate website mainpage for 1.6 release
Dodji Seketeli [Thu, 28 Mar 2019 17:25:18 +0000 (18:25 +0100)]
Update website mainpage for 1.6 release

* doc/website/mainpage.txt: Update for 1.6 release.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate ChangeLog libabigail-1.6
Dodji Seketeli [Wed, 27 Mar 2019 17:39:08 +0000 (18:39 +0100)]
Update ChangeLog

* ChangeLog: Update automatically by using "make
update-changelog".

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate NEWS file for 1.6
Dodji Seketeli [Wed, 27 Mar 2019 17:36:53 +0000 (18:36 +0100)]
Update NEWS file for 1.6

* NEWS: Update for 1.6

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd missing assignment operators
Dodji Seketeli [Wed, 27 Mar 2019 14:24:21 +0000 (15:24 +0100)]
Add missing assignment operators

This was detected by compiling with GCC 9.0.1

* include/abg-interned-str.h (interned_string::operator=): Define
assignment operator.
* include/abg-ir.h
({location, enum_type_decl::enumerator}::operator=): Declare
assignment operator.
* src/abg-ir.cc (enum_type_decl::enumerator::operator=): Define
assignment operator.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24378 - DW_TAG_subroutine_type as a DIE scope causes infinite loop
Dodji Seketeli [Mon, 25 Mar 2019 13:46:31 +0000 (14:46 +0100)]
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>
5 years agoMisc cleanups
Dodji Seketeli [Fri, 22 Mar 2019 13:43:15 +0000 (14:43 +0100)]
Misc cleanups

* src/abg-dwarf-reader.cc (build_function_type): Cleanup
indentation and comments.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBetter pointer name equality optimization in DIE de-duplication code
Dodji Seketeli [Thu, 21 Mar 2019 17:32:38 +0000 (18:32 +0100)]
Better pointer name equality optimization in DIE de-duplication code

During DIE de-duplication for the purpose of DIE canonicalization, we
use the so called "pointer name equality" optimization.  That is, when
in a given translation unit, we have two different pointers named T*,
we assume they are the same type, without having to compare their
pointed-to T types recursively.

Unfortunately, some Ts can be different, especially in C.  Think about
two typedefs with different underlying types, for instance.  Or two
struct with data members which types are pointers to typefefs with
different underlying types.  We are having the case in the libc binaries
provided in bug https://sourceware.org/bugzilla/show_bug.cgi?id=24257,
for instance.

In those case, we try not only to look at the name of the translation
unit associated to the pointer to T, but also, at the name of the
translation unit of the leaf node of T*.  By leaf node, I mean the
resulting of stripping T* from all pointers and typedefs.  This won't
solve the case of the Ts being structs with data members which types
are pointers to typedefs with different underlying types.  But it
helps with the easier earlier cases.

* src/abg-dwarf-reader.cc
(die_is_pointer_reference_or_typedef_type)
(die_peel_pointer_and_typedef): Define new static functions.
(compare_dies_string_attribute_value): Turn this function into a
static one.
(compare_dies_cu_decl_file): Make this function compare the cu
decl file name of the leaf type of the pointer, not just the one
of the pointer itself.
(compare_as_decl_dies): Compare the DWARF tags too.
(compare_dies): Simplify logic.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd ir::{lookup_data_member, get_function_parameter}
Dodji Seketeli [Thu, 21 Mar 2019 17:17:31 +0000 (18:17 +0100)]
Add ir::{lookup_data_member, get_function_parameter}

While looking at something else, I figured it's useful, for debugging
purposes, to be able to lookup a given data member of a union/class by
name, as well as a function parameter by index.

This patch adds both.

* include/abg-ir.h (lookup_data_member, get_function_parameter):
Declare new functions.
* src/abg-ir.cc (lookup_data_member, get_function_parameter):
Define them.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBetter detection of void* to something* change
Dodji Seketeli [Thu, 21 Mar 2019 17:08:59 +0000 (18:08 +0100)]
Better detection of void* to something* change

Whenever a void* pointer changes to a T* pointer, we already consider
that change to be ABI-compatible.  The issue though is that we don't
detect the case of foo* changing into T* where foo is typedef void
foo.  This patch fixes that.

* include/abg-ir.h (is_void_type): Add a new overload that takes
type_base*.
* src/abg-ir.cc (is_void_type): Define the new overload that takes
type_base*.
(is_void_pointer_type): Look through typedefs in
the pointed-to type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoPR24257 - Handle DW_TAG_typedef with no underlying type
Dodji Seketeli [Thu, 21 Mar 2019 16:31:12 +0000 (17:31 +0100)]
PR24257 - Handle DW_TAG_typedef with no underlying type

In this problem report the DWARF reader fails to recognize a
DW_TAG_typedef DIE with no underlying type as a "typedef void foo"
type.

This patch fixes that and adjusts the testsuite accordingly.

* src/abg-dwarf-reader.cc (build_typedef_type): DW_TAG_typedef
with no underlying type means typedef void foo.
* tests/data/test-annotate/test15-pr18892.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/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Likewise.
* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
Likewise.
* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Likewise.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Likewise.
* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Likewise.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoDo not build DIE -> parent map just because we see an asm TU
Dodji Seketeli [Wed, 20 Feb 2019 10:25:39 +0000 (11:25 +0100)]
Do not build DIE -> parent map just because we see an asm TU

For languages like C that don't have namespaces, we don't need to
build the DIE -> parent map, and that speeds up the analysis of the
ELF binary in the DWARF reader.

Unfortunately, just because we are seeing some MIPS assembler
translation unit, dwarf_reader::read_context::build_die_parent_maps
unnecessarily builds the DIE -> parent map, making the ELF binary
analysis slower.

This patch introduces the new function
dwarf_reader::read_context::do_we_build_die_parent_maps to make the
decision about building the DIE -> parent map in a central place.  And
it makes dwarf_reader::read_context::build_die_parent_maps use it.

With this, analysing the linux kernel becomes faster again.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAvoid over-suppressing fns & vars when analysing the Kernel
Dodji Seketeli [Tue, 19 Feb 2019 15:34:45 +0000 (16:34 +0100)]
Avoid over-suppressing fns & vars when analysing the Kernel

When analyzing the Linux Kernel (with e.g abidw) and providing a
symbol whitelist the DWARF reader performs a speed optimization which
is that it does not read the symbol table of the kernel binary.

To know if a function is to be suppressed (because it doesn't belong
to the whitelist, for instance) dwarf_reader::function_is_suppressed
actually tries to see if the address of the function corresponds to
the address of an ELF symbol that is publicly exported, before looking
at if the function was suppressed by a suppression specification.

But then, when a whitelist is provided and the speed optimization of
not reading the symbol table is at play, there is no information about
ELF symbol addressed around.  So dwarf_reader::function_is_suppressed
almost always supposes that the function is suppressed.

This patch fixes that by not trying to look at the address of the
function/variable when the symbol table optimization is on.

* include/abg-dwarf-reader.h (get_ignore_symbol_table): Take a
const read_context&.
* src/abg-dwarf-reader.cc (get_ignore_symbol_table): Likewise.
(function_is_suppressed): When the symbol table optimization is in
flight -- that is, when no symbol table has been loaded -- do not
try to see if a given function symbol was exported at the ELF
level or not.  Just look at if the function was suppressed or not.
(variable_is_suppressed): Likewise for variables.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24188 - Assertion failed while analysing a Fortran binary
Dodji Seketeli [Fri, 8 Feb 2019 08:48:40 +0000 (09:48 +0100)]
Bug 24188 - Assertion failed while analysing a Fortran binary

While analysing a Fortran binary the DWARF reader performs DIE
de-duplication.  During that process, the compare_dies function
stumbles accross the a DIE of the DW_TAG_string_type kind.  And it
doesn't know how to compare those DIEs.  And this leads to an abort of
the abipkgdiff program, in particular.

DW_TAG_string_type DIEs do have a DW_AT_string_length attribute which
value is a location expression that does not resolve to a constant
value.  In general, we cannot evaluate those expressions in a static
context like in Libabigail because we lack things like register values
which are dynamic in nature.

So, I decided for now to consider that two DW_TAG_string_type seen at
different DWARF offsets are considered to be different for now.  This
pessimises DIEs de-duplication for types that contain
DW_TAG_string_type as their subtypes, but at least this is a basic
support for DW_TAG_string_type.

Tested with the RPMs on which abipkgdiff was failing.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (compare_as_type_dies): Handle
DW_TAG_string_type DIEs here.
(compare_dies): Handle DW_TAG_string_type DIEs by using
compare_as_type_dies.
* tests/data/test-diff-pkg/netcdf-fortran-debuginfo-4.4.4-10.fc29.x86_64.rpm:
New test RPM.
* tests/data/test-diff-pkg/netcdf-fortran-debuginfo-4.4.4-11.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-4.4.4-10.fc29.x86_64-4.4.4-11.fc30.x86_64-report-0.txt:
New expected test reference output.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-4.4.4-10.fc29.x86_64.rpm:
New test RPM.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-4.4.4-11.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-debuginfo-4.4.4-10.fc29.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-debuginfo-4.4.4-11.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-devel-4.4.4-10.fc29.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/netcdf-fortran-mpich-devel-4.4.4-11.fc30.x86_64.rpm:
Likewise.
* tests/data/Makefile.am: Add the new test input material above to
source distribution.
* tests/test-diff-pkg.cc (in_out_spec): Add the new test RPMs
above to the set of RPMs to use as test input.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24157 - Wrong support of Ada ranges
Dodji Seketeli [Wed, 6 Feb 2019 12:16:44 +0000 (13:16 +0100)]
Bug 24157 - Wrong support of Ada ranges

In this problem report, the DWARF reader comes across an ADA subrange
which lower bound is a negative signed integer.  The problem is that
the internal representation of libabigail expects the bounds of the
subrange to be unsigned integer.  This incompatibility leads to an
assertion failure.

Further down the road I realized that the function
types_have_similar_structure doesn't support subrange types.

This patch thus introduces a new
array_type_def::subrange_type::bound_value class that captures the
signedness of the bound value.  This allows the internal
representation to keep the sign information of the bound value, and
yet be able to treat the bound value as either a signed or unsigned
value depending on the contexts.

The patch also extends the function types_have_similar_structure to
make it support subrange types.

* include/abg-ir.h (array_type_def::subrange_type::bound_value):
Define new class.
(array_type_def::subrange_type::subrange_type): Adjust to use the
new bound_value type for bound values.
(array_type_def::subrange_type::{get_upper_bound, get_lower_bound,
set_upper_bound, set_lower_bound}): Return or take int64_t rather
than size_t.
(array_type_def::subrange_type::get_length): Return uint64_t
rather than size_t.
* src/abg-dwarf-reader.cc (die_signed_constant_attribute)
(die_constant_attribute, die_attribute_has_form)
(die_attribute_is_signed, die_attribute_is_unsigned)
(die_attribute_has_no_signedness): Define new static functions.
(get_default_array_lower_bound): Return uint64_t rather than int.
(build_subrange_type): Use the new
array_type_def::subrange_type::bound_value type for bound values.
Use the new die_constant_attribute function, rather than
die_unsigned_constant_attribute to fecth the bound values.
* src/abg-ir.cc
(array_type_def::subrange_type::bound_value::{bound_value,
get_signedness, set_signedness, get_signed_value,
get_unsigned_value, set_unsigned, set_signed}): Define new member
functions.
(array_type_def::subrange_type::priv::{lower_bound_,
upper_bound}): Use the new class bound_value.
(array_type_def::subrange_type::priv::priv): Adjust to use the new
bound_value class to hold bound values.
(array_type_def::subrange_type::subrange_type): Likewise.
(array_type_def::subrange_type::{get_upper_bound, get_lower_bound,
set_upper_bound, set_lower_bound}): Return or take int64_t rather
than size_t.
(array_type_def::subrange_type::get_length): Return uint64_t
rather than size_t.
(types_have_similar_structure): Handle array_type_def::subrange_type
* src/abg-reader.cc (build_subrange_type): Use the new
array_type_def::subrange_type::bound_value to hold bound values.
* tests/data/test-diff-pkg/GtkAda-debuginfo-2.24.2-29.fc29.x86_64.rpm:
New binary RPM as test input.
* tests/data/test-diff-pkg/GtkAda-debuginfo-2.24.2-30.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/GtkAda-devel-2.24.2-29.fc29.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/GtkAda-devel-2.24.2-30.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt:
New expected test output.
* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64.rpm:
New binary RPM as test input.
* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-30.fc30.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-29.fc29.x86_64.rpm:
Likewise.
* tests/data/test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-30.fc30.x86_64.rpm:
Likewise.
* tests/data/Makefile.am: Add the new test material above to source
distribution.
* tests/test-diff-pkg.cc (in_out_specs): Add the new input testing
RPMs in here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoSmall apidoc fix
Dodji Seketeli [Wed, 30 Jan 2019 13:55:54 +0000 (14:55 +0100)]
Small apidoc fix

* src/abg-comparison.cc (enum_diff::changed_enumerators): Fix apidoc.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 24139 - Support suppressing some enumerator changes
Dodji Seketeli [Wed, 30 Jan 2019 12:46:29 +0000 (13:46 +0100)]
Bug 24139 - Support suppressing some enumerator changes

This patch teaches the suppression specification subsystem how to
ignore changes of some enumerators in particular.

The patch adds a new property to the [suppress_type] section which is:

    changed_enumerators = enumerator1, enumerator2, etc

This property is taken into accound iff the current suppress_type does
have the 'type_kind = enum' property.

Changes to enum types that match the new 'changed_enumerators'
property are suppressed.

* doc/manuals/libabigail-concepts.rst: Document the new
'changed_enumerators' property.
* include/abg-suppression.h
(type_suppression::{g, s}et_changed_enumerator_names): Declare two
new member functions.
* src/abg-suppression-priv.h
(type_suppression::priv::changed_enumerator_names_): Add a new
data member.
* src/abg-suppression.cc
(type_suppression::{g,s}et_changed_enumerator_names): Define two
new member functions.
(type_suppression::suppresses_diff): Support evaluating the new
'changed_enumerators = <vector of changed enumerators>'.
(read_type_suppression): Read the new list
property'changed_enumerators" and store it into the
type_suppression using the new
type_suppression::set_changed_enumerator_names ().
* tests/data/test-diff-suppr/libtest4{0,1}-enumerator-changes-v{0,1}.so:
Add new test inpujts.
* tests/data/test-diff-suppr/test4{0,1}-enumerator-changes-0.suppr:
Add a new suppr spec for this new test.
* tests/data/test-diff-suppr/test4{0,1}-enumerator-changes-report-0.txt:
The default report.
* tests/data/test-diff-suppr/test4{0,1}-enumerator-changes-v{0,1}.cc:
Add Source code of libtest4{0,1}-enumerator-changes-v{0,1}.so.
* tests/data/Makefile.am: Add the test files above to source
distribution.
* tests/test-diff-suppr.cc: Add the test input files above to the
harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBetter comments in the comparison engine
Dodji Seketeli [Fri, 25 Jan 2019 10:52:41 +0000 (11:52 +0100)]
Better comments in the comparison engine

* include/abg-comparison.h (enum diff_category): Add comments to
describe what to update when a new enumerator is added to this enum.
* src/abg-comp-filter.cc (has_fn_return_type_cv_qual_change): Fix
comment thinko here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 20175 - Classify CV qual changes in variable type as harmless
Dodji Seketeli [Fri, 25 Jan 2019 09:42:57 +0000 (10:42 +0100)]
Bug 20175 - Classify CV qual changes in variable type as harmless

When the type of a variable changes and that change is only a CV qual
change, we want libabigail to automatically classify that change as
being harmless.

This patch thus introduces a new VAR_TYPE_CV_CHANGE_CATEGORY change
category (enumerator of the abigail::comparison::diff_category enum)
for this kind of changes and classifies that category as being
harmless.

The patch then detects diff nodes that carry CV qualifiers change on
variable types and flags them as belonging to the new
VAR_TYPE_CV_CHANGE_CATEGORY.

* include/abg-comparison.h (VAR_TYPE_CV_CHANGE_CATEGORY): Add new
enumerator to diff_category enum.
(EVERYTHING_CATEGORY): Update this enumerator.
* src/abg-comp-filter.cc (type_diff_has_cv_qual_change_only):
Support array diff nodes carrying a cv qual change on the element
type.
(has_var_type_cv_qual_change): Define new static function.
(categorize_harmless_diff_node): Use the new
has_var_type_cv_qual_change to categorize variable diff node with
cv qual change on its type as harmless.
* src/abg-comparison.cc
(get_default_harmless_categories_bitmap): Update this.
(operator<<(ostream& o, diff_category c)): Likewise.
* include/abg-ir.h (equals_modulo_cv_qualifier): Declare new ...
* src/abg-ir.cc (equals_modulo_cv_qualifier): ... function.
* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
Update expected test output.
* 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/Makefile.am: Add the new test material below to
source distribution.
* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
New expecte test output.
* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64.rpm: New
test input.
* tests/data/test-diff-pkg/nss-3.24.0-1.0.fc23.x86_64.rpm: Likewise.
* tests/data/test-diff-pkg/nss-debuginfo-3.23.0-1.0.fc23.x86_64.rpm: Likewise.
* tests/data/test-diff-pkg/nss-debuginfo-3.24.0-1.0.fc23.x86_64.rpm: Likewise.
* tests/data/test-diff-pkg/nss-devel-3.23.0-1.0.fc23.x86_64.rpm: Likewise.
* tests/data/test-diff-pkg/nss-devel-3.24.0-1.0.fc23.x86_64.rpm: Likewise.
* tests/test-diff-pkg.cc (in_out_specs): Add the test input above
to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoProperly add the new rust tests to EXTRA_DIST
Dodji Seketeli [Thu, 24 Jan 2019 12:48:26 +0000 (13:48 +0100)]
Properly add the new rust tests to EXTRA_DIST

 * tests/data/Makefile.am: Add the new rust tests to
           EXTRA_DIST.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoConditionalize the Rust support regression test
Dodji Seketeli [Thu, 24 Jan 2019 10:06:57 +0000 (11:06 +0100)]
Conditionalize the Rust support regression test

* tests/test-diff-dwarf.cc: Run the rust support regression test
only if we support Rust on the platform.
* tests/test-utils.h: Include config.h.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix a typo in the recent Rust support and update regression tests
Dodji Seketeli [Thu, 24 Jan 2019 09:31:57 +0000 (10:31 +0100)]
Fix a typo in the recent Rust support and update regression tests

* configure.ac: Fix the typo HAS_LANG_Rust into HAS_DW_LANG_Rust.
* tests/data/test-diff-dwarf/test46-readme.txt: Add new file to
the test suite.
* tests/data/test-diff-dwarf/test46-rust-libone.so: Likewise.
* tests/data/test-diff-dwarf/test46-rust-libtwo.so: Likewise.
* tests/data/test-diff-dwarf/test46-rust-report-0.txt: Likewise.
* tests/test-diff-dwarf.cc (in_out_specs): Update the tests array
to compare the two new binaries included above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoOverhaul detection the DW_LANG_* enumerators from dwarf.h
Dodji Seketeli [Fri, 18 Jan 2019 10:21:48 +0000 (11:21 +0100)]
Overhaul detection the DW_LANG_* enumerators from dwarf.h

elfutils regularly adds new members to the anonymous DWARF language
encodings enum which contains the DW_LANG_* enumerators, from the
dwarf.h header file.

If we want libabigail to keep compiling with older versions of
elfutils, we need to detect the absence of a given DW_LANG_*
enumerator and avoid using it in that case.

Until now, we were doing #ifdef DW_LANG_* for that purpose.  But then
the DW_LANG_* are *enumerators*, not preprocessor macros.  So that
preprocessor macro.

This patch detects the presence of each of the "newer" DW_LANG_*
enumerator using autoconf.  And for each DW_LANG_xxx enumerator that
is present, autoconf defines the HAVE_DW_LANG_xxx_enumerator macro.
Libabigail source code can thus do #ifdef HAVE_DW_LANG_xxx_enumerator
to guard the use of DW_LANG_xxx.

Tested with the Rust binaries from
https://gitlab.gnome.org/federico/abi-rust.

* configure.ac: Detect the presence of DW_LANG_{UPC, D, Python,
Go, C11, C_plus_plus_03, C_plus_plus_11, C_plus_plus_14,
Mips_Assembler, Rust} and define the corresponding
HAVE_DW_LANG_*_enumerator macro accordingly.
* include/abg-ir.h (LANG_C_plus_plus_03): Define this new
enumerator in the translation_unit::language enum.
* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Use the
new HAVE_DW_LANG_*_enumerator macros.
(get_default_array_lower_bound): Support the
translation_unit::LANG_C_plus_plus_03 enumerator.
* src/abg-ir.cc (is_cplus_plus_language): Support the
translation_unit::LANG_C_plus_plus_03 enumerator.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix a thinko
Dodji Seketeli [Fri, 18 Jan 2019 09:40:31 +0000 (10:40 +0100)]
Fix a thinko

* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Fix a
thinko in the detection of the support of the DW_LANG_Rust enumerator.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoConditionalize the use of DW_LANG_C_plus_plus_03 and DW_LANG_Rust
Mark Wielaard [Thu, 17 Jan 2019 10:19:02 +0000 (11:19 +0100)]
Conditionalize the use of DW_LANG_C_plus_plus_03 and DW_LANG_Rust

Older elfutils (pre-0.170) don't define these constants in dwarf.h so
don't use them in that case.

* include/abg-ir.h (LANG_C_plus_plus_03): Add this new language
enum to "enum translation_unit::language".
* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Do not
use DW_LANG_Rust or DW_LANG_C_plus_plus_03 if these are not
defined.
(get_default_array_lower_bound): Handle the new
translation_unit::LANG_C_plus_plus_03 enumerator.

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoSupport some new DWARF language encoding for C and C++
Dodji Seketeli [Thu, 17 Jan 2019 09:06:02 +0000 (10:06 +0100)]
Support some new DWARF language encoding for C and C++

* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Support
new DW_LANG_{C11, C_plus_plus_03, C_plus_plus_11, C_plus_plus_14}
enumerators.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd (very) basic support for Rust
Dodji Seketeli [Thu, 17 Jan 2019 08:58:36 +0000 (09:58 +0100)]
Add (very) basic support for Rust

I tested this on the binaries generated from this project:
https://gitlab.gnome.org/federico/abi-rust and I got this:

    $ tools/abidiff libone.so libtwo.so
    Functions changes summary: 0 Removed, 1 Changed, 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

    1 function with some indirect sub-type change:

      [C]'function one::Foo one::foo(u32)' at lib.rs:8:1 has some indirect sub-type changes:
'function one::Foo one::foo(u32) {foo}' now becomes 'function two::Foo two::foo(u32, u32) {foo}'
return type changed:
  type name changed from 'one::Foo' to 'two::Foo'
  type size changed from 32 to 64 (in bits)
  1 data member insertion:
    'u32 two::Foo::b', at offset 32 (in bits)
  no data member change (1 filtered);
parameter 2 of type 'u32' was added

* include/abg-ir.h (LANG_Rust): Add this new enumerator to the
"enum language" enum.
* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Handle
the Rust language.
(get_default_array_lower_bound): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoSeparate public types of first binary from those of the second
Dodji Seketeli [Tue, 15 Jan 2019 17:33:12 +0000 (18:33 +0100)]
Separate public types of first binary from those of the second

In abidiff when the user uses --headers-dir{1,2}, she implicitly
indicates the public types of the first and the second binary.  That
means that any type that is defined in a file that is not located
under the directory tree designated by --headers-dir{1,2} is
considered private and any change involving those private types will
be suppressed.

In practice, what happens is that libabigail constructs a suppression
specification which suppress all types that are defined in files that
are not under the directories located by --headers-dir{1,2}.

abidiff has a problem, though.  It uses the same private type
suppressions (derived from --headers-dir1 and --headers-dir2) when
looking at the first binary *and* the second binary.  It should rather
only use the private type suppression specifications derived from
--headers-dir1 when looking at the first binary, and use the private
type suppression specifications derived from --headers-dir2 when
looking at the second binary.

This problem leads to some false positives like the one reported at
https://gitlab.gnome.org/GNOME/pango/issues/343#note_397761.

This patch fixes this issue by using the private type suppression
specifications derived from --headers-dir1 only when looking at the
first binary, and using the private type suppression specifications
derived from --headers-dir2 only when looking at the second binary.

* include/abg-dwarf-reader.h (read_context_get_path): Declare new
function.
* include/abg-reader.h (read_context_get_path): Likewise.
* src/abg-dwarf-reader.cc (read_context_get_path): Define new function.
* src/abg-reader.cc (read_context_get_path): Likewise.
* tools/abidiff.cc (set_suppressions): Set the suppression
specification derived from the --headers-dir1 option only for the first
binary, and similarly, from the --headers-dir2 option only for the
second binary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 23044 - Assertions with side effects
Dodji Seketeli [Wed, 9 Jan 2019 14:22:01 +0000 (15:22 +0100)]
Bug 23044 - Assertions with side effects

There are lots of spots in libabigail's source code where the argument
of the assert() call does have side effects.  This is a problem
because when the code is compiled with the NDEBUG macro defined, the
assert call does nothing, so the side effects of its argument are then
suppressed, changing the behaviour of the program.

To handle this issue, this patch introduces the ABG_ASSERT macro which
is a wrapper around the assert call that enable the use of side
effects in its argument.  The patch now uses that ABG_ASSERT macro
instead of using the assert call directly.

The patch also makes it so that the configure option accepts the
--disable-assert option so that the user can build libabigail with the
NDEBUG macro defined.

Tested by running the testsuite with and without the --disable-assert
option to configure.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate copyright for 2019
Dodji Seketeli [Mon, 7 Jan 2019 13:54:47 +0000 (14:54 +0100)]
Update copyright for 2019

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoSome documentation fixes
Xiao Jia via libabigail [Thu, 6 Dec 2018 22:39:34 +0000 (14:39 -0800)]
Some documentation fixes

* COMPILING: Add the pkg-config dependency.
* doc/manuals/kmidiff.rst: Replace the redundant --full-impact
documentation with the proper --impacted-interfaces one.

Signed-off-by: Xiao Jia <xiaoj@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd basic support for Fortran binaries
Dodji Seketeli [Thu, 29 Nov 2018 10:18:57 +0000 (11:18 +0100)]
Add basic support for Fortran binaries

Apparently, the only DWARF TAG that we needed to support to allow the
analysis of Fortran binaries is DW_TAG_string_type, at least for now.

The only place where we need to handle the DW_TAG_string_type is in
the DIE canonicalizer.  Basically, with this patch we now consider all
the DW_TAG_string_type DIEs as being equal.  This seems good enough for
ABIs purpose, unless proven otherwise.

Note that this fixes PR23492 and PR23905.

* src/abg-dwarf-reader.cc (die_pretty_print_type): Support
DW_TAG_string_type DIEs.  They all have the same representation
for now.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoSome light style change in abidiff.cc
Dodji Seketeli [Thu, 8 Nov 2018 08:10:58 +0000 (09:10 +0100)]
Some light style change in abidiff.cc

* tools/abidiff.cc (adjust_diff_context_for_kmidiff): Take a
reference to diff_context rather than a pointer.
(main): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd a --fail-no-debug-info to abidiff
Dodji Seketeli [Thu, 8 Nov 2018 08:04:53 +0000 (09:04 +0100)]
Add a --fail-no-debug-info to abidiff

Add an option to make abidiff to fail if doesn't find debug info.
Without this option, abidiff keeps going and works with only ELF
information, as it can't get the debug info.

* doc/manuals/abidiff.rst: Document the new --fail-no-debug-info
option.
* tools/abidiff.cc (options::fail_no_debug_info): Define new data
member.
(display_usage): Provide a help string for the new
--fail-no-debug-info option.
(parse_command_line): Parse the new option.
(main): If --fail-no-debug-info and no debug info was found, or
not alternate debuginfo file was found, bail out.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoSupport having several debuginfo search dirs for a binary
Dodji Seketeli [Thu, 8 Nov 2018 06:26:14 +0000 (07:26 +0100)]
Support having several debuginfo search dirs for a binary

There are use cases where the split debuginfo file of a given binary
is under a given root directory and that the split debuginfo file
itself depends on an alternate debuginfo file that is under another
unrelated root directory.

In that case, the dwarf reader must be able to look for the debuginfo
files under several unrelated root directories.  The tools abidiff and
abidw must thus support having several occurences of the option
--debug-info-dir1 (or --debug-info-dir2) meaning that the debuginfo
files for the binary must be looked for under several root
directories.

This is what this patch does.

* doc/manuals/abidiff.rst: Adjust doc for the
--debug-info-dir{1,2} that can now be provided several times.
* include/abg-dwarf-reader.h ({create, reset}_read_context)
(read_corpus_from_elf): Take a vector of debug info root dirs.
* include/abg-tools-utils.h (trim_leading_string)
(find_file_under_dir, make_path_absolute_to_be_freed)
(convert_char_stars_to_char_star_stars): Declare new functions.
* src/abg-dwarf-reader.cc (find_alt_debug_info_link): Renamed
find_alt_debug_info_location into this.
(find_alt_debug_info_path): Define new static function.
(find_alt_debug_info): Take a vector of debug info root dirs.  Use
the new find_alt_debug_info_path to look into the debug info root
dirs for the alt debug info.
(read_context::debug_info_root_paths_): Define new data member.
(read_context::read_context): Take a vector of debug info root
dirs and initialize the new read_context::debug_info_root_paths_.
(read_context::{initialize, create_default_dwfl}): Take a vector
of debug info root dirs and adjust.
(read_context::{add_debug_info_root_paths,
add_debug_info_root_path, find_alt_debug_info}): Define new member
functions.
(read_context::load_debug_info): Look into the debug info roots
for split debug info files.
(create_read_context, read_corpus_from_elf): Take a vector of
debug info root dirs and adjust.
(has_alt_debug_info): Adjust.
* src/abg-tools-utils.cc (trim_leading_string)
(make_path_absolute_to_be_freed, find_file_under_dir)
(convert_char_stars_to_char_star_stars): Define new functions.
(entry_of_file_with_name): Define new static function.
(build_corpus_group_from_kernel_dist_under): Adjust.
* tests/print-diff-tree.cc (main): Adjust.
* tests/test-diff-dwarf.cc (main): Adjust.
* tests/test-ir-walker.cc (main): Adjust.
* tests/test-read-dwarf.cc (main): Adjust.
* tools/abicompat.cc (main): Adjust.
* tools/abidiff.cc (options::di_root_paths{1,2}): Changed
di_root_path{1,2} into this, change their types into vectors of
allocated char*.
(options::prepared_di_root_paths{1,2}): Define new data members.
(options::~options): Define new destructor.
(parse_command_line): Adjust.
(prepare_di_root_paths): Define new static function.
(handle_error): Remove arguments input_file_name,
debug_info_dir{1,2}.  Now just take an instance of options
instead.  Adjust.
(main): Adjust.
* tools/abidw.cc (options::dir_root_paths): Renamed dir_root_path
into this and make it be a vector of allocated char*.
(options::prepared_di_root_paths): Define new data member.
(options::~options): Free the allocated char* in
options::dir_root_paths.
(parse_command_line): Support several --debug-info-dir.
(load_corpus_and_write_abixml): Adjust.
(prepare_di_root_paths): Define static function.
(main): Adjust.
* tools/abilint.cc (main): Adjust.
* tools/abipkgdiff.cc (compare): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate website for 1.5
Dodji Seketeli [Fri, 26 Oct 2018 14:54:51 +0000 (16:54 +0200)]
Update website for 1.5

       * doc/website/mainpage.txt: Update website for 1.5

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBump version number to 1.6
Dodji Seketeli [Fri, 26 Oct 2018 13:09:08 +0000 (15:09 +0200)]
Bump version number to 1.6

* configure.ac: Bump version number to 1.6

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate ChangeLog for 1.5 libabigail-1.5
Dodji Seketeli [Thu, 25 Oct 2018 12:19:47 +0000 (14:19 +0200)]
Update ChangeLog for 1.5

* ChangeLog: Update automatically by calling make
update-changelog.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoUpdate NEWS file for 1.5
Dodji Seketeli [Thu, 25 Oct 2018 12:17:24 +0000 (14:17 +0200)]
Update NEWS file for 1.5

* NEWS: Update for 1.5

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug rhbz1638554 - assertion failed in is_mostly_distinct_diff
Dodji Seketeli [Thu, 18 Oct 2018 13:52:12 +0000 (15:52 +0200)]
Bug rhbz1638554 - assertion failed in is_mostly_distinct_diff

* src/abg-comp-filter.cc (is_mostly_distinct_diff): Handle the
case of the type diff of the function parameter diff being a
distinct diff.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoDefine UINT64_MAX when it's not defined
Dodji Seketeli [Wed, 17 Oct 2018 08:41:35 +0000 (10:41 +0200)]
Define UINT64_MAX when it's not defined

It looks like GCC 4.4.x does not define UINT64_MAX so define it for
those platforms.

* src/abg-dwarf-reader.cc: Define UINT64_MAX when it's not defined.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBetter support array with unknown upper bound
Dodji Seketeli [Tue, 16 Oct 2018 08:59:37 +0000 (10:59 +0200)]
Better support array with unknown upper bound

It can happen that arrays are described in DWARF with an unknown upper
bound.  In those cases, if the array is the type of a global variable,
the ELF object corresponding to that global variable should have a
size.  It's that ELF object size that should be taken into account
when comparing versions of that global variable and its type.

This patch fixes issues in the detection and representation of array
subranges with unknown size so that we behave like presented above.

* include/abg-comparison.h
(BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY): A new enumerator in the
diff_category enum.
(EVERYTHING_CATEGORY): Adjust.
* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
Adjust.
(operator<<(ostream& o, diff_category)): Likewise.
* include/abg-ir.h (array_type_def::subrange_type::is_infinite):
Declare new member function.
* src/abg-ir.cc (array_type_def::subrange_type::priv::infinite_):
New data member.
(array_type_def::subrange_type::priv::priv): Initialize it.
(array_type_def::subrange_type::get_length): Better support
unknown sized subrange.
(array_type_def::subrange_type::is_infinite): Define new member
function.
* src/abg-comp-filter.cc (has_benign_infinite_array_change):
Define new static function.
(categorize_harmless_diff_node): Use the new
has_benign_infinite_array_change above.
* src/abg-dwarf-reader.cc (build_subrange_type): Better recognize a
subrange type with unknown upper bound.  Represent that with the
new array_type_def::subrange_type::is_infinite member property.
* src/abg-reader.cc (build_subrange_type): Likewise.
* tests/data/test-abidiff/test-PR18166-libtirpc.so.abi: Adjust.
* tests/data/test-annotate/libtest23.so.abi: Likewise.
* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Likewise.
* tests/data/test-annotate/test7.so.abi: Likewise.
* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise.
* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.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>
5 years agoAdd default suppression specification for the libvirt project
Dodji Seketeli [Thu, 11 Oct 2018 08:59:54 +0000 (10:59 +0200)]
Add default suppression specification for the libvirt project

* default.abignore: Suppress changes on functions with symbol
version LIBVIRT_PRIVATE in libvirt.so.* shared objects.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd default suppression specification for the krb5 project
Dodji Seketeli [Thu, 11 Oct 2018 08:53:45 +0000 (10:53 +0200)]
Add default suppression specification for the krb5 project

* default.abignore: Ignore changes about functions starting with
krb5int_.*.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoMisc comment fix
Dodji Seketeli [Wed, 3 Oct 2018 09:43:19 +0000 (11:43 +0200)]
Misc comment fix

* src/abg-suppression.cc (type_suppression::suppresses_diff): Fix
comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 23708 - categorize void* to pointer change as harmless
Dodji Seketeli [Wed, 3 Oct 2018 09:24:42 +0000 (11:24 +0200)]
Bug 23708 - categorize void* to pointer change as harmless

Changing a void* pointer into another pointer of the same size is a
change that is harmless in terms of data layout.

This commit thus categorizes such a change as harmless.

* include/abg-comparison.h (VOID_PTR_TO_PTR_CHANGE_CATEGORY): New
enumerator in the diff_category enum.  Also, adjust the
EVERYTHING_CATEGORY enumerator.
* include/abg-fwd.h (is_void_pointer_type): Declare new function.
* src/abg-comp-filter.cc (has_void_ptr_to_ptr_change): Define new
static function and ...
(categorize_harmless_diff_node): ... use it here.
* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
Add the new abigail::comparison::VOID_PTR_TO_PTR_CHANGE_CATEGORY
category in here.
(operator<<(ostream& o, diff_category c)): Add support for the new
VOID_PTR_TO_PTR_CHANGE_CATEGORY.
* src/abg-ir.cc (is_void_pointer_type): Define new function.
* tests/data/Makefile.am: Add the new test material below to source distribution.
* tests/data/test-diff-filter/test47-filter-void-ptr-change-report-0.txt:
New test reference output.
* tests/data/test-diff-filter/test47-filter-void-ptr-change-v{0,1}.c:
Source code of the new binary test input below.
* tests/data/test-diff-filter/test47-filter-void-ptr-change-v{0,1}.o:
New binary test input.
* tests/test-diff-filter.cc: Add the test input/output above to
test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoCategorize CV qualifier changes on fn return types as harmless
Dodji Seketeli [Tue, 2 Oct 2018 11:49:55 +0000 (13:49 +0200)]
Categorize CV qualifier changes on fn return types as harmless

This partially fixes PR23700.

A change in the CV qualifiers of a function return value type should
be categorized as harmless.  And this is what this patch does.

* include/abg-comparison.h (FN_RETURN_TYPE_CV_CHANGE_CATEGORY):
New enumerator for diff_category.
(EVERYTHING_CATEGORY): Update.
* src/abg-comp-filter.cc (type_diff_has_cv_qual_change_only):
Factorize this function out of ...
(has_fn_parm_type_cv_qual_change): ... this one.
(has_fn_return_type_cv_qual_change): Define new static function.
(categorize_harmless_diff_node): Use the new
has_fn_return_type_cv_qual_change.
* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
Adjust to add the new FN_RETURN_TYPE_CV_CHANGE_CATEGORY category.
(operator<<(ostream& o, diff_category c)): Support the new
FN_RETURN_TYPE_CV_CHANGE_CATEGORY.
* tests/data/Makefile.am: Add the new test material below to
source distribution.
* tests/data/test-diff-filter/test46-fn-return-qual-change-report-0.txt:
New reference output for the new input test.
* tests/data/test-diff-filter/test46-fn-return-qual-change-v{0,1}.c:
New source code for the new binary test input.
* tests/data/test-diff-filter/test46-fn-return-qual-change-v{0,1}.o:
New binary test input files.
* tests/test-diff-filter.cc: Add the new test input above to test
harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix propagation of private type suppression category
Dodji Seketeli [Mon, 1 Oct 2018 14:14:50 +0000 (16:14 +0200)]
Fix propagation of private type suppression category

This is a partial fix of PR23700.

Conceptually, there are two kinds of type suppression specifications:

1/ a generic user-provided suppression specification that is meant to
suppress changes on types specified by the user

2/ a private type suppression specification that is automatically
generated from the path to public header files provided by the user.

Technically, one difference between 1 and 2 lays in the way we
propagate categories of changes matched by those suppression
specifications.

If a class type change of category SUPPRESSED_CATEGORY is referenced
in a typedef change, then the typedef change is also considered to be
of category SUPPRESSED_CATEGORY.  In other words, the
SUPPRESSED_CATEGORY category is propagated to the typedef change.
That means that if a change to a class type is suppressed, a (changed)
typedef to that class is considered to be suppressed too.

But then that is not true if the class type was changed because it's
private.  In that, a typedef to that class can be *public*, because
the said typedef is defined in a public header.  In that case the
typedef change should *NOT* be considered suppressed just because the
class type change was suppressed.

The problem we have here is that we don't make any difference between
1/ and 2/.  So we need to introduce different propagation rules for 1/
and 2/.

So this patch introduces a new PRIVATE_TYPE_CATEGORY category for
types suppression specification that are automatically generated for
private types.  That new category has its own propagation rule which
is basically "no propagation"; every type must be matched by the
private type suppression specification to be considered as private.

* include/abg-comp-filter.h (has_harmful_name_change): Declare new
function overloads.
* include/abg-comparison.h (PRIVATE_TYPE_CATEGORY): New enumerator
for diff_category;
(EVERYTHING_CATEGORY): Adjust this enumerator in diff_category;
(is_suppressed): Take an output parameter to say if the
suppression is a private type suppression.
* include/abg-suppression.h (is_private_type_suppr_spec): Take a
const reference parameter and add an overload for a shared
pointer.
* src/abg-comp-filter.cc (has_harmful_name_change): Define new
function.
* src/abg-comparison-priv.h (diff::priv::is_filtered_out): Diffs
of category PRIVATE_TYPE_CATEGORY are also considered filtered
out.
* src/abg-comparison.cc (diff::is_filtered_out): Adjust to account
for canonical diffs of category PRIVATE_TYPE_CATEGORY.
(diff::is_suppressed): Add an overload that takes a
is_private_type output parameter.  Re-write the old overload in
terms of the new one.
(operator<<(ostream& o, diff_category c)): Handle
PRIVATE_TYPE_CATEGORY.
(category_propagation_visitor::visit_end):  Do not propagate
PRIVATE_TYPE_CATEGORY here. Do not propagate
HARMLESS_DECL_NAME_CHANGE_CATEGORY either, when the class does
have a harmful decl name change.
(suppression_categorization_visitor::visit_begin): Set the new
PRIVATE_TYPE_CATEGORY category but do not propagate it.
(suppression_categorization_visitor::visit_end): Add some
comments.
* src/abg-default-reporter.cc (default_reporter::report): Avoid
reporting typedef underlying types that are in the
PRIVATE_TYPE_CATEGORY category.
* src/abg-suppression.cc (type_suppression::suppresses_diff): Do
not peel typedefs if we are a private type suppression.
(is_private_type_suppr_spec): Take a const reference.
* tests/data/Makefile.am: Add the new test material below to
source distribution.
* tests/test-diff-suppr.cc: Use new test binary input.
* tests/data/test-diff-filter/test7-report.txt: Adjust.
* tests/data/test-diff-suppr/test39-opaque-type-report-0.txt: New
test reference output.
* tests/data/test-diff-suppr/test39-opaque-type-v{0,1}.c: Source
code of new test binary input.
* tests/data/test-diff-suppr/test39-opaque-type-v{0,1}.o: New test
binary input.
* tests/data/test-diff-suppr/test39-public-headers-dir/test39-header-v{0,1}.h:
Source code of new test binary input.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoPR23641 - confusion when a type definition DIE is matched by a supprspec and its...
Dodji Seketeli [Tue, 25 Sep 2018 10:17:52 +0000 (12:17 +0200)]
PR23641 - confusion when a type definition DIE is matched by a supprspec and its decl DIEs aren't

This is a followup of the patch with commit hash 90b4e76.

It turns out that in some cases, when we see a suppressed private
class definition, we haven't *previously* seen any declaration-only
instance of it.  So we cannot use any pre-existing declaration-only
instance as an opaque type for the private type that is suppressed.

In that case, this patch creates (and uses) a declaration-only
instance for the suppressed private type definition.

* src/abg-dwarf-reader.cc (get_opaque_version_of_type): If no
pre-existing opaque version was found, a new one is created and
returned.  Take a needed "where_offset" parameter.
(build_ir_node_from_die): Adjust the call to
get_opaque_version_of_type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoPR23641 - Type definition DIE matched by a supprspec but not its decl
Dodji Seketeli [Fri, 21 Sep 2018 12:33:19 +0000 (14:33 +0200)]
PR23641 - Type definition DIE matched by a supprspec but not its decl

Suppose we have two versions of a library which are almost identical.
Suppose the difference between the two binaries is a slight difference of
ordering in how the linker put together what the DWARF describes.

Then, while processing the debug info of the first library, libabigail
first comes across the forward declaration of a type T.  Suppose that
declaration is not matched by any private type suppression
specification.  Libabigail is going to keep the declaration of T and
build an internal representation (IR) for it.  It's also going to
build an IR for types and decls using T like "T*" or "T* var".

Now suppose that while processing the debug info of the second
library, libabigail first comes across the *definition* of T --
because in this second library, that definition comes first.  Suppose
that the definition is matched by a private type suppression
specification, unlike the declaration in the first library.  In this
case, T is going to be dropped, and no IR is going to be built for it.
If other types or decl like 'T*' or 'T *var" refer to this
*definition* of T, they will be dropped too.

We'll end up with those two libraries that are identical (modulo the
order in which libabigail sees type declarations and their
definitions) and are considered different when a suppression
specification makes us drop T: the second library appears to
libabigail as if T was removed from it.

This is the problem addressed by this patch.

When the definition of a type T is suppressed because it's considered
private then we look if there was a forward declaration for it
elsewhere, that is not matched by the private type suppression
specification.  If we encountered such a type declaration then it
means that declaration is in effect an "opaque" version of T.  So
rather than just dropping T altogether, we keep (and build an IR) for
its opaque version only.  And we drop the definition of T.

This seems to fix the issue.

I can't seem to reproduce the slight re-ordering of DIEs descriptions that
uncover the issue so I'll rely on integration tests to catch future
regressions on this issue, rather than on unit tests.  Sigh.

* include/abg-tools-utils.h (PRIVATE_TYPES_SUPPR_SPEC_NAME):
Remove this extern constant definition.
* src/abg-dwarf-reader.cc (type_is_suppressed): Add an overload
that takes an additional type_is_private output parameter.
(get_opaque_version_of_type): New static function.
(build_ir_node_from_die): For class types, get the opaque version
for suppressed private types rather than dropping them altogether.
* src/abg-reader.cc (type_is_suppressed): Adjust.
* src/abg-suppression-priv.h (type_is_suppressed): Add an overload
that takes a type_is_private output parameter.
* include/abg-suppression.h (get_private_types_suppr_spec_label)
(is_private_type_suppr_spec): Declare new functions.
* src/abg-suppression.cc
(get_private_types_suppr_spec_label, is_private_type_suppr_spec):
Define new functions.
(suppression_matches_type_name_or_location): Use the new
get_private_types_suppr_spec_label rather than a global extern
variable.
* src/abg-tools-utils.cc (handle_fts_entry): Adjust to use the new
get_private_types_suppr_spec_label.
(gen_suppr_spec_from_headers): Handle the case or an empty headers
root dir.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoAdd option to avoid walking abigail::ir nodes twice
Dodji Seketeli [Mon, 3 Sep 2018 09:10:25 +0000 (11:10 +0200)]
Add option to avoid walking abigail::ir nodes twice

When the ir_traversable_base::traverse() walks the IR graph, it
happens that it can visit a type node that was already visited before.
For instance, it visits the 'struct S' once and later, as part of its
visit of struct S*, it can visit struct S again.

There are use cases where we want the walker to avoid visiting a given
type node again.  This patch adds the option to do so.

Basically the ir_node_visitor class can now be configured to tell the
walker to avoid re-visiting a node.

The test-ir-walker.cc example is amended to avoid re-visiting type nodes
as well.

* include/abg-ir.h (struct ir_node_visitor): Make this be a class.
Add a private data member to it, following the 'pimpl' idiom.
(ir_node_visitor::{allow_visiting_already_visited_type_node,
mark_type_node_as_visited, forget_visited_type_nodes,
type_node_has_been_visited}): Declare new member functions.
* src/abg-ir.cc ({type_base, type_decl, scope_type_decl,
qualified_type_decl, pointer_type_def, reference_type_def,
array_type_def, enum_type_decl, typedef_decl, class_or_union,
class_decl, union_decl}::traverse): Avoid re-visiting the type
node if the visitor was configured as such.
(struct ir_node_visitor::priv): Define new struct.
(ir_node_visitor::{allow_visiting_already_visited_type_node,
mark_type_node_as_visited, forget_visited_type_nodes,
type_node_has_been_visited}): Define new member functions.
* tests/test-ir-walker.cc
(name_printing_visitor::name_printing_visitor): Avoid visiting a
type node twice.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoFix apidoc of dwarf_reader::get_soname_of_elf_file
Dodji Seketeli [Fri, 31 Aug 2018 07:31:41 +0000 (09:31 +0200)]
Fix apidoc of dwarf_reader::get_soname_of_elf_file

It turned out the first parameter of
abigail::dwarf_reader::get_soname_of_elf_file was not documented.
Fixed thus.

* src/abg-dwarf-reader.cc (get_soname_of_elf_file): Document the
first parameter.  Remove bogus documentation of the previous 'elf'
parameter.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoBug 23533 - Accept '=' in ini property values
Dodji Seketeli [Thu, 30 Aug 2018 08:54:33 +0000 (10:54 +0200)]
Bug 23533 - Accept '=' in ini property values

It appears that it's not possible to write a suppression specification
like the below at the moment:

  [suppress_file]
  label = Libabigail can't handle libgfortran.so (https://sourceware.org/bugzilla/show_bug.cgi?id=23492)
  file_name_regexp = libgfortran\\.so.*

This is because the ini parser won't accept the '=' character in the
URL as a valid character for ini property values.

So the entire [suppress_file] section is ignored by the suppression
specification engine.

This patch fixes that by making the equal character valid in property
values.

* src/abg-ini.cc (char_is_delimiter): Take a new include_equal
flag to control is the equal character should be considered as a
delimiter or not.
(char_is_property_value_char): Accept the equal character as a
valid property value character.
* tests/Makefile.am: Build a new runtestini test from the new
tests/test-ini.cc source file.
* tests/data/Makefile.am: Add the two new test inputs below to
source distribution.
* tests/data/test-ini/test01-equal-in-property-string.{abignore,
abignore.expected}: New test inputs.
* tests/test-ini.cc: New test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
5 years agoMake test-ir-walker work on ELF binaries directly
Dodji Seketeli [Mon, 6 Aug 2018 08:28:06 +0000 (10:28 +0200)]
Make test-ir-walker work on ELF binaries directly

The tests/test-ir-walker.cc example was working on abixml files
resulting from abidw.  This commit changes that to make it work on
ELF input files directly.  The commit also adds some comments to make
it easier to understand the concepts.

* test-ir-walker.cc (main): Load an ABI corpus from an elf file
and walk its translation units.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>