platform/upstream/libabigail.git
9 years agoBug 19173 - Abidiff doesn't detect symbol size change in library
Dodji Seketeli [Sat, 7 Nov 2015 19:51:29 +0000 (20:51 +0100)]
Bug 19173 - Abidiff doesn't detect symbol size change in library

It appears that libabigail does not represent the size of ELF symbols,
so it doesn't detect when a symbol size changes without impacting the
size of the type of said symbol, as described by debug info.

It appears that Address Sanitizer as implemented by Clang does change
the size of variable symbols when it instruments those variables.  And
of course, the size of type of said symbols (as described by debug
information) remains unchanged.

This patch makes Libabigail become aware of symbol sizes, especially
for variables.  Symbol sizes for functions are ignored for now,
because a change in a function symbol size is not an ABI change.

The patch makes libabigail detect and report symbol size changes for
variables, but looking at the ELF information, independently from the
debug information.

The patch adjusts the existing tests and adds a new test using the
binaries that were filed in the bug report.

* include/abg-ir.h (elf_symbol::{elf_symbol, create}): Take a size
parameter.
(elf_symbol::{get,set}_size): New accessors.
* src/abg-ir.cc (elf_symbol::priv::size_): New data member.
(elf_symbol::priv::priv): Initialize it.
(elf_symbol::{elf_symbol, create}) Take a size parameter.
(textually_equals): Compare the size of variable symbols.
(elf_symbol::{get, set}_size): New accessors.
* src/abg-comparison.cc (maybe_report_diff_for_symbol): New static
function.
({function_decl_diff,var_diff}::report): Use it.
* src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab)
(lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab)
(read_context::lookup_elf_symbol_from_index): Set the size of the
elf symbols' internal representation.
* src/abg-reader.cc (build_elf_symbol): Read the size attribute if
present.
* src/abg-writer.cc (write_elf_symbol): Write the size attribute
for variable symbols, if it's not zero.
* tests/data/test-diff-dwarf/test34-pr19173-libfoo.so: New test
input binary.
* tests/data/test-diff-dwarf/test34-pr19173-libfoo2.so: Likewise.
* tests/data/test-diff-dwarf/test34-pr19173-libfoo-report-0.txt:
New reference test output.
* tests/data/Makefile.am: Add the new test input binaries to the
build system.
* tests/test-diff-dwarf.cc (in_out_specs): Add the new test input
above to the test harness.
* tests/data/test-diff-dwarf/test9-report.txt: Adjust.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise.
* tests/data/test-read-dwarf/test0.abi: Likewise.
* tests/data/test-read-dwarf/test1.abi: Likewise.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/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/test6.so.abi: Likewise.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd some needed vertical space
Dodji Seketeli [Sat, 7 Nov 2015 22:05:55 +0000 (23:05 +0100)]
Add some needed vertical space

* src/abg-dwarf-reader.cc (build_array_type): Add a new line after
this function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoPass a bunch of parameters by reference as they ought to be
Dodji Seketeli [Sat, 7 Nov 2015 22:04:01 +0000 (23:04 +0100)]
Pass a bunch of parameters by reference as they ought to be

* include/abg-ir.h (operator==): In the overload for
elf_symbol_sptr, pass the parameters by reference.
* src/abg-ir.cc (operator==): Do the same at definition site.
* src/abg-comparison.cc (maybe_report_diff_for_member): Pass
parameters by reference.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19139 - DWARF reader doesn't handle garbage in function names
Dodji Seketeli [Thu, 5 Nov 2015 15:01:56 +0000 (16:01 +0100)]
Bug 19139 - DWARF reader doesn't handle garbage in function names

In this bug, the DWARF debug info of the binary (generated by Intel's
ICC compiler) has interesting constructs like:

     [ 6b5a0]    subprogram
 decl_line            (data2) 787
 decl_column          (data1) 15
 decl_file            (data1) 46
 declaration          (flag)
 accessibility        (data1) public (1)
 type                 (ref4) [ 6b56a]
 prototyped           (flag)
 name                 (string) "ldiv"
 MIPS_linkage_name    (string) "ldiv"
     [ 6b5b6]      formal_parameter
   type                 (ref4) [ 5f2aa]
   name                 (string) "$Ë2"
     [ 6b5bf]      formal_parameter
   type                 (ref4) [ 5f2aa]
   name                 (string) "$Ë3"

Note the strings that make up the name of the formal parameters of the
function, near the end:

     [ 6b5b6]      formal_parameter
   type                 (ref4) [ 5f2aa]
   name                 (string) "$Ë2"
     [ 6b5bf]      formal_parameter
   type                 (ref4) [ 5f2aa]
   name                 (string) "$Ë3"

The strings "$Ë2" and $Ë3" (which are the names of the
parameters of the function) are garbage.

Libabigail's DWARF reader naively uses those strings as names for the
function parameters, in the type of the function.

Then, the abixml writer emits an XML document, with these strings as
property values, representing the name of the type of the function.

And of course, the XML later chokes when it tries to read that XML
document, saying that the property is not valid UTF-8.

This patch addresses the issue by dropping those garbage names on the
floor, for function type names.  In that context, any string that is
not made of ASCII characters is considered as being garbage, for now.

The patch, in the abixml writer, also escapes function parameters
names so that they don't contain characters that are not allowed in
XML.  The abixml reader already handles the un-escaping of the names
it reads, so I think there is nothing to do there.

Ultimately, I guess I should get the unicode value of the characters
of that string, encode the string into UTF-8 and use the result as the
name for the parameter.  That would mean using UTF-8 strings for
function parameter names, and, for all declarations names.  But that
is too much for worfk too little gain for now.  The great majority of
the binaries we are dealing with are still using ASCII for declaration
names.

The patch also introduces a new test harness that runs "abidw
--abidiff" on a bunch of input binaries.  This harness runs over the
binaries that were submitted in this bug report.

* include/abg-tools-utils.h (string_is_ascii): Declare new
function ...
* src/abg-tools-utils.cc (string_is_ascii): ... and define it.
* src/abg-writer.cc (write_function_type): Escape forbidden XML
characters in function type names.
* src/abg-dwarf-reader.cc (build_function_type):  If a parameter
name is not ascii, drop it on the floor.
* tests/data/test-types-stability/pr19139-DomainNeighborMapInst.o:
New test input binary.
* tests/data/test-types-stability/pr19202-libmpi_gpfs.so.5.0:
Likewise.
* tests/data/Makefile.am: Add the new binaries above to the build
system.
* tests/test-types-stability.cc: New test harness.
* tests/Makefile.am: Add the new test harness to the build system.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoIntroduce the name abixml in some comments
Dodji Seketeli [Thu, 5 Nov 2015 14:54:36 +0000 (15:54 +0100)]
Introduce the name abixml in some comments

Until now, the native XML format of libabigail didn't have a name.  I
am introducing the name "abixml" that I am slowing starting to use
these days.  So I am adding that name in comments of the files where
we emit and read that format.

* src/abg-reader.cc: Mention abixml in the comment at the top of
the file.
* src/abg-writer.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19026 - Types with same name and different size considered equivalent
Dodji Seketeli [Sat, 17 Oct 2015 15:59:20 +0000 (17:59 +0200)]
Bug 19026 - Types with same name and different size considered equivalent

This is a second attempt at fixing this bug.  The previous attempt was
on the good path, but a thinko got in the way, oops.  We are not adding
the new binary of that bug report (which got re-opened) to the test
suite because it's too big and it takes too much time and memory to
abidw to analyze it.

* src/abg-ir.cc (type_base::get_canonical_type_for): Really
compare the size of the type to be canonicalized against the size
of the *current* potential canonical type of the same name.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd a script to update the reference output of runtestreaddwarf
Dodji Seketeli [Sat, 17 Oct 2015 13:59:55 +0000 (15:59 +0200)]
Add a script to update the reference output of runtestreaddwarf

This script parses the output of runtestreaddwarf (that output is
non-empty when the reference output *.abi files need updating, but
when there is no ABI change error).  As a result, the script emits a
series of "cp <source-file> <destination-file>" command to issue, to
update the reference output of the runtestreaddwarf test program.

To use this script to update the reference output *.abi files for
runtestreaddwarf,

    <build-dir>/tests/runtestreaddwarf > changed-output.txt
    python update-test-read-dwarf-output.py changed-output.txt > shell-update-commands.sh
    sh shell-update-commands.sh

* tests/update-test-read-dwarf-output.py: New helper python program.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoStyle fixes in the abixml writer.
Dodji Seketeli [Sat, 17 Oct 2015 13:09:43 +0000 (15:09 +0200)]
Style fixes in the abixml writer.

* src/abg-writer.cc (write_var_decl): Use the var_decl_sptr
typedef.
(write_class_decl): Indent.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix typo in test-read-dwarf.cc
Dodji Seketeli [Sat, 17 Oct 2015 13:05:41 +0000 (15:05 +0200)]
Fix typo in test-read-dwarf.cc

* tests/test-read-dwarf.cc (for test test21-pr19092.so.abi): Fix
typo in the output path of that test.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdjust regression tests reference output for the current patch set
Dodji Seketeli [Sat, 17 Oct 2015 13:03:41 +0000 (15:03 +0200)]
Adjust regression tests reference output for the current patch set

This is the last patch of a series of patches which aims at fixing bug
libabigail/19097.  The short titles of the patches of the set are,
including this one:

    Don't canonicalize types not added to their context in abixml reader
    Support updating a class in the abixml reader
    Fix emitting of referenced type in abixml writer
    Use abidw --abidiff in test-read-dwarf.cc
    Adjust regression tests reference output for the current patch set

Below is the cover letter of the last patch of the set.

The current patch set needs big reference output adjustments, that we
are doing at the end, here.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so:
New test input binary.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
New test reference output.
* tests/data/Makefile.am: Add the new test files above to the
source distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add the two new test
files above to the set of test input files.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoUse abidw --abidiff in test-read-dwarf.cc
Dodji Seketeli [Sat, 17 Oct 2015 13:06:57 +0000 (15:06 +0200)]
Use abidw --abidiff in test-read-dwarf.cc

That test was doing several sub-tests that amount to just calling
abidw --abidiff.  So, let's use that, now that we have it.

* tests/test-read-dwarf.cc (handle_in_out_spec): Rather than
calling abilint on the abixml and abidiff-ing the .so file against
its .so.abi, call abidw --abidiff on the .so file and voila.  Ok,
it does one extra save of abixml, but then that won't hurt.  And
things are faster now than what they were anyway :-)

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix emitting of referenced type in abixml writer
Dodji Seketeli [Sat, 17 Oct 2015 12:10:57 +0000 (14:10 +0200)]
Fix emitting of referenced type in abixml writer

There are several issues with the abixml writer in how it handles the
process of emitting referenced types that are not directly reachable
but just walking the scopes (namespaces) of the translation units;
think about member types of a class A that are not necessarily present
in all the declarations of A, in all translation units, for instance.

This patch addresses them all because they are all intermingled.

* Use of canonical pointers in the hash map of referenced types

The abixml writer was using canonical types pointer values to hash
referenced types in a map.  It was doing so "by hand"; and it was thus
messing things up for types without canonical types (like some class
declarations) etc.

This patch changes that by using the generic solution of
abigail::ir::hash_type_or_decl(), which also uses the same canonical
pointer type values.  For types with no canonical types, that
functions knows has to gracefully fallback.  At worst, it will just
make things slower, not wrong.

* Sorting of referenced types

The patch also changes the sorting function used for the hash map of
referenced types.  The previous solution was sorting the pretty
representation of types; but then when two types have the same pretty
representation (think, typedefs, for instance) then their relative
position in the sorted result was random.  This causes some stability
issues, in that emitting the abixml for the same binary several times
can lead to the some types being sorted differently -- they have the
same name, but not necessarily the same type *IDs*, as they are
different types.

The new sorting code handles this better; it also uses the pretty
representations of types, when they are equal, it uses the type IDs to
tell the types apart.  At least this brings stability in the abixml
output, for a given binary.

* Avoiding duplicating declaration-only types when emitting the
  context of referenced member types.

We don't keep track of declaration-only classes that are emitted.
This is because we allow a given class declaration (that carries no
definition) to appear several times in a given ABI corpus.  So when a
referenced type is a class declaration, it always appears as if that
referenced type has not been emitted.  So when we specifically emit
the not-emitted referenced types, it can happen that declaration-only
classes can appear a lot of times.  This is unnecessary duplication,
aka bloat.

This patch thus introduces a new hash map that tracks emitted
declaration-only classes, so that we can allow duplication of class
declarations when they follow what's done in the IR read from DWARF,
and disallow that duplication when it's totally artificial and
useless.

* Better tracking of referenced types

We were blatantly forgetting to mark some referenced types as such.
So those were missing in some abixml output.

This patch fixes the spots where we were forgetting that important
information.

* Better representation of the scopes of the referenced types that
  were specifically emitted.

The previous code was failing at properly representing the class scope
of some referenced types that were specifically emitted, or sometimes,
for member types, representing the scope would be so screwed that the
(referenced) member type itself wouldn't be emitted at all.

This is because I thought that to emit a given member type, just
emitting its parent scope would be enough. I thought that would
automatically trigger emitting the member type itself.  First, that
would emit too much information at times; the other members of the
scope are not necessarily needed.  And second the "duplication
detection code" would sometime refuse to emit the scope class, because
it has already been emitted earlier!  But the incarnation that got
emitted didn't have this member type as member, then.  Yes, in DWARF,
the same class A can be declared several times with different member
types in it.  The complete representation of A would be a union of all
those declarations of A that are seen.

This patch addresses this issue by carefully emitting just the
information that is needed from the scope of the referenced type.
Basically the scope is declared just to declare/define the type we are
interested in; period.  The abixml reader is now properly geared to
re-construct the scope by merging its different parts that are now
scattered around, in the ABI corpus.  That support is part of this
patch set.

instance, a member typedef would be emitted with the information of
its parent class badly formatted.

* src/abg-writer.cc (struct type_ptr_comp_functor): Remove this.
(sort_type_ptr_map): Likewise.
(write_context::record_type_as_referenced): Do not add the
canonical type of the type to record as referenced directly.
(write_context::type_is_referenced): Adjust accordingly.
(struct write_context::type_ptr_cmp): New comparison functor.
(write_context::sort_types): New sorting function.
(write_context::{record_decl_only_type_as_emitted,
decl_only_type_is_emitted}): New member functions.
(write_member_type_opening_tag): Factorize out of ...
(write_member_type): ... here.
(write_class_decl_opening_tag): Factorize out of ...
(write_class_decl): ... here.  Now, keep track also of
declaration-only classes that are emitted.
(write_decl_in_scope): Use the new write_member_type_opening_tag
and write_class_decl_opening_tag.  Now write class scopes
ourselves; they only contain the type declarations that we are
emitting.
(write_translation_unit): Use the new sorting code to sort the
referenced types to emit.  Do not emit referenced types that are
declaration-only classes that have already been emitted.  Handle
the fact that emitting the referenced types might make those
emitted type *reference* other types too! So handle those new
referenced types as such, and emit them too.
(write_qualified_type_def, write_typedef_decl, write_var_decl): Do
not forget to mark referenced types as such.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoSupport updating a class in the abixml reader
Dodji Seketeli [Sat, 17 Oct 2015 11:26:41 +0000 (13:26 +0200)]
Support updating a class in the abixml reader

In DWARF, the same class declaration can be present several times but
with different "views", that is, it can be present in a first
translation unit, but without any member type; then in a subsequent
translation unit, its member types are defined.  In another, it'll be
completely defined, with all its data members and base classes.  The
DWARF reader knows how to amend the class to add new members to it, as
they show up in the debug information.

This patch adds the same functionality to the abixml reader.  The
writer has already started to write class declarations with different
"views" too, since it's started to avoid duplicating full class
definitions in every translation unit that uses them.

Without this patch, abixml misses some class members, and that is a
bug.

* include/abg-ir.h (class_decl::{find_base_class,
find_member_type, find_data_member}): Declare new member functions ..
* src/abg-ir.cc (class_decl::{find_base_class,
find_member_type, find_data_member}): ... and define them.
* src/abg-reader.cc (build_class_decl): Add the ability to update
a class to add new data members, member types and base classes to
it, if necessary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDon't canonicalize types not added to their context in abixml reader
Dodji Seketeli [Sat, 17 Oct 2015 10:48:11 +0000 (12:48 +0200)]
Don't canonicalize types not added to their context in abixml reader

This is the first patch of a series which aims at fixing bug
libabigail/19097.

The problem in that report is a result of several underlying issues.
This patch series address them in isolation.  The patches do not
update the reference output of the regression test as they should,
because they are all needed to get to a sane working state.  The test
reference output are thus adjusted in the last patch of the series.
Here are the short titles of the patches of the set, including this
one:

    Don't canonicalize types not added to their context in abixml reader
    Support updating a class in the abixml reader
    Fix emitting of referenced type in abixml writer
    Use abidw --abidiff in test-read-dwarf.cc
    Adjust regression tests reference output for the current patch set

Below is the cover letter of the first patch of the set.

The abixml reader sometimes (wrongly) canonicalizes types that are not
(yet) added to their context.  This can lead to comparison issues
because some information carried by some types are dependant on their
context (e.g, access specifiers) and can be important for type
comparison.  Right now, access specifiers for member types are no more
taken into account when comparing member types because DWARF emitters
do not necessarily keep a correct track of those; but when they do, we
better be prepared.  And in any case, it's wrong to have type
canonicalization happen on half backed types anyway.

So this patch fixes several spots where type canonicalization happens
on types that are not added to their scope.

* src/abg-reader.cc (read_context::maybe_canonicalize_type):
Assert that a class type that is scheduled for canonicalization
must be in a scope.  We do this only for classes, for now.  The
assert here helped to spot (and fix)  a lot of places where we
were canonicalizing types without scope.
(read_context::build_or_get_type_decl):  Canonicalize types here,
when they are built and (hopefully) added to their scope.  There
might be cases here where we try to canonicalize types that are
not added to their scope.  That should bomb in the assert above,
at least for class types, for now.  We'll then fix the places where
the types are created, to make them properly scoped.
(build_type_decl, build_qualified_type_decl)
(build_pointer_type_def, build_reference_type_def)
(build_array_type_def, build_enum_type_decl, build_typedef_decl):
Do not try to canonicalize the types early, right when they are
created.  Canonicalization should happen at the point where (or
after) they are added to their scope.
(build_class_decl): Likewise.  Also, schedule member types for
canonicalization once they've been added to their scope.
(build_class_tdecl): Schedule the pattern of the class template
for canonicalization once it has been added to its scope.  I am
not sure I should do this, as the pattern is not yet a real type,
but I am taking my bet.
(build_type_composition): Schedule the composed type for
canonicalization once it's been added to its scope.
(handle_type_decl, handle_qualified_type_decl)
(handle_pointer_type_def, handle_reference_type_def)
(handle_function_type, handle_array_type_def)
(handle_enum_type_decl, handle_typedef_decl, handle_class_decl):
At this point, we should know if the type is to be added to a
scope or not.  If it's in a scope, then schedule for
canonicalization.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19092 - abidw aborts on types that violate the ODR
Dodji Seketeli [Thu, 15 Oct 2015 14:06:35 +0000 (16:06 +0200)]
Bug 19092 - abidw aborts on types that violate the ODR

It appears that two different types from two different translation
units might have the same name in a DSO, like in the example of this
bug.  This violates the One Definition Rule, which we rely on to go
fast, and more importantly, it introduces type canonicalization errors.

This patch recognizes more of these ODR violation cases by looking at
the size of the types.  That is, if two types (from the same DSO) with
the same name have different sizes, then they are different.

* src/abg-ir.cc (type_base::get_canonical_type_for): Look at the
size of types with the same name which could be considered
ODR-equal, to spot possible violations that would induce a type
canonicalization error.
* tests/data/test-read-dwarf/test21-pr19092.so: New test input
binary.
* tests/data/test-read-dwarf/test21-pr19092.so.abi: New reference
abixml for the binary above.
* tests/data/Makefile.am: Add the new test input above to source
distribution.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Likewise.
* tests/test-read-dwarf.cc (int_out_specs): Add the two test input
above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix activation of Debian package support
Dodji Seketeli [Thu, 15 Oct 2015 10:51:33 +0000 (12:51 +0200)]
Fix activation of Debian package support

* configure.ac: If we cannot activate Debian package support, then
report it clearly.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMisc style cleanup
Dodji Seketeli [Thu, 15 Oct 2015 10:50:10 +0000 (12:50 +0200)]
Misc style cleanup

* include/abg-fwd.h: Remove unnecessary declaration of class
parameter.
* src/abg-ir.cc: Remove trailing space in a comment.
* src/abg-reader.cc: Fix a comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoEmit statistics about resolved class declarations
Dodji Seketeli [Thu, 15 Oct 2015 10:47:24 +0000 (12:47 +0200)]
Emit statistics about resolved class declarations

This patch makes abidw --stats emit statitics about class declarations
that got resolved, and those that we missed.

* src/abg-dwarf-reader.cc
(read_context::resolve_declaration_only_classes): Emit statistics
about resolved classes and the missed ones.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd a missing xml text reader call
Dodji Seketeli [Thu, 15 Oct 2015 10:44:30 +0000 (12:44 +0200)]
Add a missing xml text reader call

* src/abg-reader.cc (read_corpus_from_input): Add the necessary
call to xmlTextReaderNext call after the xmlTextReaderExpand call.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoPass some more parameters in reference
Dodji Seketeli [Thu, 15 Oct 2015 07:42:54 +0000 (09:42 +0200)]
Pass some more parameters in reference

Profiling as shown that we might gain some precious cycles by passing
some well chosen parameters by reference.

* include/abg-ir.h (operator==): For the type_base_sptr and
decl_base_sptr overloads, pass the parameters by reference.
({var,function}_decl::{set,get}_symbol): Pass the elf_symbol_ptr
by reference.
* src/abg-ir.cc (operator==): For the type_base_sptr and
decl_base_sptr overloads, pass the parameters by reference, now in
the definition.
({var,function}_decl::{set,get}_symbol): Pass the elf_symbol_ptr
by reference, now in the definition.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdjust tests for the patchset
Dodji Seketeli [Thu, 15 Oct 2015 11:08:18 +0000 (13:08 +0200)]
Adjust tests for the patchset

This is the last patch of the series of patches whose titles are
(including this one):

    Force late canonicalizing of function types read from abixml
    Fix strip_typedef issues
    Do not compare access specs for member types & functions
    Fix "is-anonymous" abixml property impact on some tests
    Fix const-ness of a function parameter
    Handle aliased function decls when comparing decls in general
    Make canonicalization non sensitive to struct-ness of subtypes
    Set the corpus of all ABI artifact reads from abixml
    Implement fast type lookup in a corpus
    Accelerate a slow path in hash_type_or_decl()
    A series of small speed optimizations here and there
    Allow only one definition of a given type per corpus in abixml
    Make abidw --abidiff not show definitely harmless changes
    Adjust tests for the patchset

This patch carries the numerous adjustments necessary for the
regresion tests output after this patch set.

* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMake abidw --abidiff not show definitely harmless changes
Dodji Seketeli [Thu, 15 Oct 2015 10:56:06 +0000 (12:56 +0200)]
Make abidw --abidiff not show definitely harmless changes

When comparing the ABI of the input ELF binary with that same ABI
saved to abixml and read back again, there can be some minor and
harmless changes that are seen, because libabigail makes some
approximations for performance reasons.  For instance, if there are
two types that are equivalent, but have different names (because of
typedefs) then libabigail will consider that they are the same type,
and might save them (to abixml) and read them back (from abixml) in
different order.

That can lead to subtle changes that are reported (and filtered out)
by the command "abidw --abixml".

This patch arranges for abidw --abixml to avoid emitting a report
saying that a filtered out change was detected, as those cases are
considered OK.

The patch also fixes a little issue where abidw would abort because
the user forgot to provide the binary to analyze, on the command line.

* tools/abidw.cc (set_diff_context): New function.
(main): Use that new function.  Do not show any output for
--abidiff if only compatible changes were detected.  Also, do not
abort if no input binary was giving.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAllow only one definition of a given type per corpus in abixml
Dodji Seketeli [Thu, 15 Oct 2015 09:13:19 +0000 (11:13 +0200)]
Allow only one definition of a given type per corpus in abixml

In abixml, the same type T can be defined in several translation
units.  This leads to a lot of duplication and, for some big binaries,
to a *lot* of memory use.  For instance, loading the abixml
representing the abi of the r300_dri.so library takes more that 10GB
or ram on a 64 bits system!

This patch addresses the issue by allowing declarations to be
duplicated, but by allowing only one definition per type, per corpus.
With it, loading the abixml of r300_dri.so now takes less than 2GB or
ram.

* src/abg-writer.cc (write_translation_unit): Do not clear some
important per-translation unit maps here.  There are needed to
keep track of the emitted and referenced types through the entire
corpus.  Avoid (wrongly) recording function types twice.
(write_array_type_def, write_function_decl, write_function_type):
Record referenced types.
(write_class_decl): Record referenced types, and, allow only
declarations to be duplicated in a corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoA series of small speed optimizations here and there
Dodji Seketeli [Thu, 15 Oct 2015 09:04:32 +0000 (11:04 +0200)]
A series of small speed optimizations here and there

These are small speed optimizations that are induced by some lesser
hot spot identified by profiling.

* src/abg-comparison.cc (var_diff::has_changes): Just compare the
two var_decl.  It's (way) faster now than using recursive hashing
for that.
* src/abg-ir.cc (elf_symbol::does_alias): Get out early if the two
main symbols are equal.
(equals): In the overload for function_decl, start by comparing
types.  This can be very fast for functions with different types,
as it amounts to a pointer comparison.  In the overload for
class_decl, avoid a map lookup when it's not necessary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAccelerate a slow path in hash_type_or_decl()
Dodji Seketeli [Thu, 15 Oct 2015 08:50:36 +0000 (10:50 +0200)]
Accelerate a slow path in hash_type_or_decl()

Profiling shows that hash_type_or_decl() is very slow when hashing
function parameters and base class specifications.  This is because in
those two cases we use the slow recursive hashing algorithm to hash
types, rather than using the faster one based on using the pointer
values of canonical types when possible.

This was making corpora comparison very slow, as it uses
hash_type_or_decl() to hash diffs of ABI artifacts.

This patch fixes that.

* include/abg-ir.h (is_function_parameter, is_class_base_spec):
Declare new functions.
* src/abg-ir.cc (is_function_parameter, is_class_base_spec):
Define them.
(hash_type_or_decl): Handle hashing of function parameters are
class base specifications with the fast path of type hashing.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoImplement fast type lookup in a corpus
Dodji Seketeli [Thu, 15 Oct 2015 08:14:22 +0000 (10:14 +0200)]
Implement fast type lookup in a corpus

Profiling has shown that on libraries with a lot of class types
declarations (more than 10K types), the phase of resolving those
declarations to their definition was a hot spot.  The lookup of the
type definition inside the entire corpus was the bottleneck.

This patch removes (or loosen) that bottleneck by doing away with the
graph-walking-based type lookup algorithm that was used.  Rather, maps
of name -> types are maintained by each scope, in each translation
unit. Those maps are updated each time a type is added to a scope.
And looking up a type amounts to a lookup in a map.  Way faster.

* include/abg-fwd.h (components_to_type_name): Declare new
function.
* include/abg-ir.h (string_type_base_wptr_map_type): New typedef.
(translation_unit::{get,set}_types): Declare new member functions.
* src/abg-ir.cc (translation_unit::priv::types_): New data member.
(translation_unit::{get,set}_types): Define these member
functions.
(maybe_update_types_lookup_map): Define new static function.
(components_to_type_name): Define new function.
(scope_decl::{add_member_decl, insert_member_decl}): Call the new
maybe_update_types_lookup_map.
(scope_decl::find_iterator_for_member): Fix logic.
(class_decl::set_is_declaration_only): When a class declaration
becomes a definition, update the name -> type map maintained in
the scope of the class.
(lookup_type_in_translation_unit): Use the hash map of qualified
name -> types that is now maintained in the translation unit.
This is way faster than the previous walking algorithm.
* src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir):
When fixing up global variable declarations that need to be
re-added to the translation unit, use the new fast type lookup
function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoSet the corpus of all ABI artifact reads from abixml
Dodji Seketeli [Thu, 15 Oct 2015 07:47:58 +0000 (09:47 +0200)]
Set the corpus of all ABI artifact reads from abixml

It turns out we were not setting the corpus for all ABI artifact read
from abixml.  That was preventing the use of the ODR-based speed
optimization during type canonicalization, for corpora built from abixml.

Fixed thus.

* src/abg-reader.cc (read_translation_unit): Set the current
corpus to the current translation unit being built.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMake canonicalization non sensitive to struct-ness of subtypes
Dodji Seketeli [Wed, 14 Oct 2015 20:40:18 +0000 (22:40 +0200)]
Make canonicalization non sensitive to struct-ness of subtypes

In a previous patch, we made canonicalization independant from
struct-ness of class types.  This was in this commit:

    0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness

But then, that didn't handle the case of composite types which have a
subtype of class type T, where the same T was declared as "struct" and
as "class" in the same binary.

This patch handles that case by passing a flag to the functions that
build the pretty representation of types.  Note that the pretty
representation is used as a key in the hash map that contains
canonical types.  That flag is passed all the way down to the function
that builds the pretty representation for class types, which decides
to use either "struct" or "class" as a previx for the representation.

The type canonicalization code then passes that flag (properly set) to
the pretty representation function.

* include/abg-fwd.h (get_type_name, get_function_type_name)
(get_method_type_name, get_pretty_representation): Add an
"internal" flag to all overoads.
* include/abg-ir.h
({type_or_decl_base, decl_base, type_decl, scope_type_decl,
qualified_type_def, array_type_def, enum_type_decl, typedef_decl,
var_decl, function_decl, function_decl::parameter, function_type,
method_type, class_decl}::get_pretty_representation): Add an
'internal' flag.
({decl_base, qualified_type_def, pointer_type_def,
reference_type_def, array_type_def, enum_type_decl::enumerator,
function_decl::parameter}::get_qualified_name): Likewise.
(qualified_type_def::build_name): Likewise.
* src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def,
reference_type_def, array_type_def, enum_type_decl,
enum_type_decl::enumerator,
function_decl::parameter}::get_qualified_name): Take an "internal"
flag.
(qualified_type_def::build_name): Likewise.
({decl_base, type_decl, namespace_decl, array_type_def,
enum_type_decl, typedef_decl, var_decl, function_type,
method_type, function_decl,
class_decl}::get_pretty_representation): Likewise.
(get_type_name, get_function_type_name, get_method_type_name)
(get_pretty_representation): Likewise.
(type_base::get_canonical_type_for): Call
get_pretty_representation() with the "internal" flag set to
"true", to get a pretty representation that is independant from
the struct-ness of the subtypes of the type being canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoHandle aliased function decls when comparing decls in general
Dodji Seketeli [Wed, 14 Oct 2015 18:49:55 +0000 (20:49 +0200)]
Handle aliased function decls when comparing decls in general

When comparing two declarations, we look at their linkage name. When
the linkage names are different, then we infer that the two decls are
different.

But then, for *function* decls, it can happen that two different
linkage names are actually for different symbols that do alias; the
(ELF) symbols are different but they have the same address; so they
point to the same "thing".  The two functions are not different, then.

And we were not supporting this last case of diffent linkage names
that are aliases of each other.

This patch adds support for that.

* include/abg-ir.h (is_function_decl): Add a const to the
reference parameter, making it comply with the definition.
* src/abg-ir.cc (equals): In the overload for decl_base, when the
two linkage names are different, consider the case of the decls
being aliased functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix const-ness of a function parameter
Dodji Seketeli [Wed, 14 Oct 2015 18:44:18 +0000 (20:44 +0200)]
Fix const-ness of a function parameter

* include/abg-fwd.h (is_function_decl): Add a const to the
parameter to make it comply with the definition in abg-ir.cc.
Woops.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix "is-anonymous" abixml property impact on some tests
Dodji Seketeli [Wed, 14 Oct 2015 12:52:08 +0000 (14:52 +0200)]
Fix "is-anonymous" abixml property impact on some tests

Since we started to rely on ODR for type canonicalization, we needed
to mark anonymous structures (and enums) as being anonymous, hence, a
new "is-anonymous" property was introduced in the abixml format.
While looking at something else, I noticed that some anonymous
structures in test files
tests/data/test-abidiff/test-corpus0-v{0,1}.so.abi were not marked as
anonymous, and that was causing some comparison issues.  This patch
adjusts those abixml files.  I forgot at the time to mention that
those files were coming from the libtirpc.so binary provided in bug
18166, so I am renaming the files now to reflect that.  Also, I am
adding the binary here.  I have thus re-generated a new abixml file
from that *.so file; it now has the proper "is-anonymous" properties.

* tests/data/test-abidiff/test-PR18166-libtirpc.so: New file.
* tests/data/test-abidiff/test-PR18166-libtirpc.so.abi: Likewise.
* tests/data/test-abidiff/test-corpus0-report0.txt: Renamed into
tests/data/test-abidiff/test-PR18166-libtirpc.so.report.txt.
* tests/data/test-abidiff/test-corpus0-v{0,1}.so.abi: Removed.
* tests/data/Makefile.am: Renamed test-corpus0-* files into
test-PR18166-libtirpc.so-* files.
* tests/test-abidiff.cc (specs): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDo not compare access specs for member types & functions
Dodji Seketeli [Wed, 14 Oct 2015 11:49:29 +0000 (13:49 +0200)]
Do not compare access specs for member types & functions

It turns that in some DWARF (e.g, from the r300_dri.so binary in bug
libabigail/19024) the same class Foo can be declared as a struct, and
later defined as a class.  Or the other way around.

In some cases, Foo can be declared as a struct, have a member type
Foo::Type with no access specifier, and later that member type is
still present with no access specifier when Foo is defined as a class.
So when comparing Foo::Type (from struct Foo) against Foo::Type (from
class Foo) we must not consider the access specification of Type,
otherwise, as in the first case it's 'public' and in the second case
it's 'private', the two member types would be considered different.

And something similar happens for member function declarations too.

This patch thus avoids comparing access specifiers for member types
and functions.  Though it can be considered as a regression compared
to what was being done before, access specifiers don't have an impact
on ABI per se.  And they can cause noise in the result, as we are
seeing here.

* include/abg-fwd.h (is_function_decl): Declare a new overload.
* src/abg-ir.cc (is_function_decl): Define a new overload.
(equals): In the overload for decl_base, do not compare access
specifiers when comparing member functions and types.
* tests/data/test-diff-dwarf/test0-report.txt: Adjust.
* tests/data/test-diff-filter/test0-report.txt: Likewise.
* tests/data/test-diff-filter/test01-report.txt: Likewise.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise.
* tests/data/test-diff-filter/test4-report.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix strip_typedef issues
Dodji Seketeli [Wed, 14 Oct 2015 11:34:35 +0000 (13:34 +0200)]
Fix strip_typedef issues

strip_typedef currently has at least two issues.  First, it was
triggering a potentially wrong early canonicalization.  Second, it was
asserting too eagerly that a return type should not be nil; the truth
is that there can be a short period of time where a function has an
empty result type; that is usually during the building of said
function type, before the return type is fully built.

This patch addresses those two issues.

* src/abg-ir.cc (strip_typedef): Do not canonicalize
the return type of the method type to typedef-strip.
Acknowledge that the return type can be nil.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoForce late canonicalizing of function types read from abixml
Dodji Seketeli [Wed, 14 Oct 2015 13:00:27 +0000 (15:00 +0200)]
Force late canonicalizing of function types read from abixml

This is the first patch of a series which aims at fixing:

    Bug 19024 - abidw --abidiff fails and aborts when run against r300_dri.so

The issue reported in that bug is the manifestation of several
problems that different patches in the series address on a case by
case basis.

Suffice it to say abidw --abidiff on my X220 laptop was taking more
than 40 minutes, and north of 11GB or ram.  An rather than yielding
the empty set, it was emitting lots of false postives!

The patchset thus applies a series of optimizations to reduce the time
and memory taken, so that I can at least debug the issues that prevent
abidw --abidiff from yielding the empty set, as it should.  Then, with
those optimizations applied, I came up with a series of fixes.

With the series applies, abidw --abidiff now takes less than 8 minutes
and around of 4.8GB of ram.

The first seven patches are those fixes.  The next five patches are
the time and size optimization that allowed me to work on the first
fixes.  The thirteenth patch applies some needed modification (both
fixes and improvements) to abidw --abidiff itself. The last patch
carries the necessary adjustments to the regression tests output.

Here are the short titles of the patches of the set, including this one:

    Force late canonicalizing of function types read from abixml
    Fix strip_typedef issues
    Do not compare access specs for member types & functions
    Fix "is-anonymous" abixml property impact on some tests
    Fix const-ness of a function parameter
    Handle aliased function decls when comparing decls in general
    Make canonicalization non sensitive to struct-ness of subtypes
    Set the corpus of all ABI artifact reads from abixml
    Implement fast type lookup in a corpus
    Accelerate a slow path in hash_type_or_decl()
    A series of small speed optimizations here and there
    Allow only one definition of a given type per corpus in abixml
    Make abidw --abidiff not show definitely harmless changes
    Adjust tests for the patchset

We do not add the r300_dri.so library to the repository because of the
time it still takes to complete.

And now, here is the cover letter for this first patch.

When reading the abixml format, sometimes, function types can be
early-canonicalized.  This can be wrong especially is the function
type has sub-types that are not canonicalized yet.

So this patch forces those to be late-canonicalized.

* src/abg-reader.cc (build_function_type): Late-canonicalize
function types.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19082 - Recognize suppression spec files
Ondrej Oprala [Tue, 13 Oct 2015 07:19:47 +0000 (09:19 +0200)]
Bug 19082 - Recognize suppression spec files

When abipkgdiff is invoked on a set of packages, the newer (second) one is also
inspected for files matching the pattern '*.abignore', whose contents are read
and interpreted as suppression specifications.

* tests/data/Makefile.am: Add new test material to the build system.
* tests/data/test-diff-pkg/dirpkg-{0-dir1,{1,2}-dir2}/dir.abignore:
A test suppression specification.
* tests/data/test-diff-pkg/dirpkg-{2,3}-dir2/.abignore: Likewise.
* tests/data/test-diff-pkg/dirpkg-3.suppr: Likewise.
* tests/data/test-diff-pkg/dirpkg-{1,2,3}-dir{1,2}/libobj-v0.so: New
binary test inputs.
* tests/data/test-diff-pkg/dirpkg-{1,2,3}-dir{1,2}/obj-v0.cc: New test
source files
* tests/data/test-diff-pkg/dirpkg-{1,2,3}-report-{0,1}.txt: New
reference outputs
* tests/test-diff-pkg.cc: Adjust to run the new tests.
* tools/abipkgdiff.cc (prog_options): New static pointer to struct
opts.
(file_tree_walker_callback_fn): Rename to
first_package_tree_walker_callback_fn.
(second_package_tree_walker_callback_fn): Check for ELF files just
like the previous function but additionally check for files
ending with ".abignore", unless disabled from the command line.
({create_maps_of_package,extract_package_and_map_its}_content):
Add a callback as a new argument.
(main) handle the new "--no-abignore" option, which turns off
the search for suppression files within the new package.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoBug 19024 - Failing to flag underlying type of enums as anonymous
Dodji Seketeli [Thu, 8 Oct 2015 16:15:55 +0000 (18:15 +0200)]
Bug 19024 - Failing to flag underlying type of enums as anonymous

The for now, the underlying type of an enum type is always assumed to
be anonymous by libabigail.  But then, the code of the DWARF reader
was failing to set the "is-anonymous" flag on it.  So type
canonicalizing code was comparing the enum underlying types by looking
at their names; they all have the same name -- as we forget that they
are anonymous; so they (wrongly) all look the same, within the same
ABI corpus.

This patch sets properly sets the is-anonymous flag on enumerator
underlying types again.

* src/abg-dwarf-raeder.cc (build_enum_type): Set the is-anonymous
flag on the underlying type of the enum.
* tests/data/test-read-dwarf/test0.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.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/test17-pr19027.so.abi: Likewise.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19025 - abixml writer forgets to emit some member types
Dodji Seketeli [Thu, 8 Oct 2015 10:57:04 +0000 (12:57 +0200)]
Bug 19025 - abixml writer forgets to emit some member types

When a member type (a type that is a member of a class) M is
referenced by some types emitted by abixml, but the context of M (the
class type which M is a member of) is not itself referenced by any ABI
artifact, then abixml forgets to emit the context of M and thus M
itself.

With this patch, when the abixml writer has emitted almost all ABI
artifacts for the current translation unit, it looks for types that
have been referenced by the emitted ABI artifacts, but that haven't
been emitted themselves.

It then emits those referenced-but-not-emitted types, and makes sure
their contexts are emitted as well.

* include/abg-fwd.h (is_namespace): Fix prototype.
* src/abg-writer.cc (struct type_ptr_comp_functor): New internal
type.
(sort_type_ptr_map): New static function.
(write_context::m_referenced_types_map): Renamed
m_referenced_fntypes_map data member into this.
(write_context::get_referenced_types): New member function.
(write_context::record_type_as_referenced): Renamed
record_fntype_as_referenced member function into this.  Adjust.
(write_context::type_is_referenced): Renamed fntype_is_referenced
into this.
(write_context::clear_referenced_types_map): Renamed
clear_referenced_fntypes_map member function into this.  Adjust.
(write_decl_in_scope): New static function.
(write_translation_unit): Use it here to emit types that are
referenced by other types in the TU, but that are not emitted.
Adjust.
(write_pointer_type_def, write_reference_type_def)
(write_typedef_decl): Record the underlying types referenced by
the emitted types as being, well, referenced.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so:
New test binary input.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
New reference output of the binary input above.
* tests/data/Makefile.am: Add the new test material above to the
source distribution.
* tests/test-read-dwarf.cc (in_out_spec): Add the new test inputs.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoParallelize test read-dwarf.
Ondrej Oprala [Tue, 6 Oct 2015 12:35:14 +0000 (14:35 +0200)]
Parallelize test read-dwarf.

* tests/Makefile.am: Link runtestreaddwarf with libpthread.
* tests/test-read-dwarf.cc (main) Create worker threads corresponding
to the number of CPUs online, add a "--no-parallel" option and move
the main loop...
(handleInOutSpec) ...here.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoBug 19023 - Type canonicalization is sensitive to struct-ness
Dodji Seketeli [Tue, 6 Oct 2015 22:08:46 +0000 (00:08 +0200)]
Bug 19023 - Type canonicalization is sensitive to struct-ness

In some debug info of some shared library, the same type can be
present as a struct in some translation units, and as a class in
others.  As we are using the "pretty representation" of types to hash
types during type canonicalization, a "class foo" and "struct foo"
are (wrongly) considered different, because those pretty
representations are different.

This patch changes the canonicalization code to make it independent
from the struct-ness of the class being canonicalized.

* include/abg-ir.h (class_decl::is_struct): Declare a setter for the
"is-struct" property.
* src/abg-ir.cc (class_decl::is_struct): And define that setter
here.
(type_base::get_canonical_type_for): Temporarily set the
'is-struct' flag of the class type to 'false' before building its
pretty representation.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so:
New test input binary.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
New test reference output.
* tests/data/Makefile.am: Add the new test material above to the
source distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add the two new test
inputs to the list of test inputs to consider.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoStyle adjustment in abg-corpus.cc
Dodji Seketeli [Tue, 6 Oct 2015 11:04:39 +0000 (13:04 +0200)]
Style adjustment in abg-corpus.cc

* src/abg-corpus.cc (corpus::exported_decls_builder::id_var_map_):
Renamed data member vars_map_ into this.
(corpus::exported_decls_builder::id_var_map): Renamed vars_map
into this.
(corpus::exported_decls_builder::var_id_is_in_id_var_map): Renamed
var_is_in_map into this.
(corpus::exported_decls_builder::{add_var_to_map,
add_var_to_exported, maybe_add_var_to_exported_vars}): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19037 - Make ABI corpus support several functions with same symbol
Dodji Seketeli [Tue, 6 Oct 2015 10:01:20 +0000 (12:01 +0200)]
Bug 19037 - Make ABI corpus support several functions with same symbol

It turns out that, in DWARF, there can be function template
instantiations foo<int>(int) and foo<TypedefOfInt>(TypedefOfInt) which
have the same symbol name, if TypedefOfInt is a typedef of int.

An ABI corpus retains only one function declaration per symbol
name.  So in the example of the bug the input DWARF has the two
instantiations, but libabigail is just keeping one of the two; so the
abixml only has one of the two template instantiations.

This patch changes the ABI corpus model so that it represents the fact
that there can be several function declarations for a given symbol.
The patch then adjust the comparison engine to make it know about this
new model.

* include/abg-corpus.h
(corpus::exported_decls_builder::str_{fn,var}_ptr_map_type):
Remove these typedefs from here as they only used internally in
abg-corpus.cc.  So we move them there instead.
* src/abg-corpus.cc (str_fn_ptrs_map_type): New typedef.
(str_var_ptr_map_type): Moved the typedef that was in
corpus::exported_decls_builder here.
(corpus::exported_decls_builder::id_fns_map_): Rename the fns_
data member into this.  Make it have a str_fn_ptrs_map_type as a
type.
(corpus::exported_decls_builder::id_fns_map): Renamed the
fns_map() accessor into this one.
(corpus::exported_decls_builder::{fn_id_is_in_id_fns_map,
fn_is_in_fns}): New member functions.
(corpus::exported_decls_builder::fn_is_in_id_fns_map): Rename
fn_is_in_map into this.
(corpus::exported_decls_builder::add_fn_to_id_fns_map): Rename
add_fn_to_map into this.
(corpus::exported_decls_builder::add_fn_to_exported): Adjust.
(corpus::exported_decls_builder::maybe_add_fn_to_exported_fns):
Adjust.
* src/abg-comparison.cc (function_decl_diff::report): Emit reports
about function name changes (for a given function ID) only if
there are sub-type changes to be reported for the function.  In
that case, do not forget to emit the sub-type changes after the
name changes have been reported.
(corpus_diff::priv::ensure_lookup_tables_populated): Several
functions of the same ID can be removed or added from/to the
corpus.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so:
New test input binary.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
New test output reference.
* tests/data/Makefile.am: Add the new test materials to the source
distribution.
* tests/test-read-dwarf.cc (in_out_specs): Adjust to add the new
test inputs above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDo not imply private access when building a struct from ABIXML.
Ondrej Oprala [Mon, 5 Oct 2015 13:01:04 +0000 (15:01 +0200)]
Do not imply private access when building a struct from ABIXML.

* src/abg-reader.cc (read_context): Abort if we run into an
unsupported access specifier.
(build_class_decl) Default to public access for the children
of a struct.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoFix minor warnings when building documentation.
Ondrej Oprala [Mon, 5 Oct 2015 06:40:20 +0000 (08:40 +0200)]
Fix minor warnings when building documentation.

* manuals/abilint.rst: Fix the "Literal block expected" warning.
* manuals/abipkgdiff.rst: Fix the "Title underline too short" warning.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoFix an "Unknown target name" error during make info.
Ondrej Oprala [Mon, 5 Oct 2015 06:33:46 +0000 (08:33 +0200)]
Fix an "Unknown target name" error during make info.

* doc/manuals/libabigail-overview.rst: Fix the reference to
"ELF symbols".

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoFix a path in doc/Makefile.am
Ondrej Oprala [Mon, 5 Oct 2015 05:47:13 +0000 (07:47 +0200)]
Fix a path in doc/Makefile.am

* doc/Makefile.am: Prefix the path for DOXY_WEBSITE_SRC_CFG and
DOXY_WEBSITE_BLD_{CFG,DIR} with "/doc" to protect it against make
clean.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoMisc style cleanups
Dodji Seketeli [Sun, 4 Oct 2015 11:35:19 +0000 (13:35 +0200)]
Misc style cleanups

* src/abg-reader.cc (read_is_struct): Fix comment.
(build_type_decl): Use type_decl_sptr rather than
shared_ptr<type_decl>.
(build_type_decl): Use typedef_decl_sptr rather than
shared_ptr<typedef_decl>.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoUse the ODR to speed up type canonicalization
Dodji Seketeli [Sun, 4 Oct 2015 10:34:13 +0000 (12:34 +0200)]
Use the ODR to speed up type canonicalization

This is the last patch of the series of 11 patches that started at the
patch with the subject:

    constify is_class_type()

And below starts the cover letter of this patch.

While analyzing some libraries like libmozjs.so[1] it appeared that
type canonicalization takes a significant time to comparing composite
types that are re-defined in each translation units again and again.

The One Definition Rule[2] says that two types with the same name
shall designate the same thing; so when a type T being canonicalized
has the same name of a canonical type C in the same ABI corpus, then
this patch considers C as being the canonical type of T, without
comparing T and C structurally.  This saves us from comparing T and C.

Before this patch, `abidw --noout libmozjs.so` was taking
approximatively 5 minutes; with the patch, it takes 1 minutes and 30
seconds.

To do this, the patch changes ABI artifacts to carry a pointer to the
corpus it belongs to.  Whenever an ABI artifact is added to a given
context, the corpus of that context is propagated to the artifact;
that is now possible as the artifact now carries the property of the
corpus it belongs to.

During type canonicalization the ODR-based optimization outlined above
is performed as we can now compare the corpus of a given type again
the one of another type; it's now possible to know if two types come
from the same corpus.

There are a few cases though were the optimization is not performed:
  - anonymous struct; when a struct is anonymous (it has no name, as
    described in the DWARF), the DWARF reader gives it a name
    nonetheless, so that diagnostics can refer to that anonymous type.
    But then all anonymous types in the system have the same name.  So
    when faced with two anonymous types (with the same name) from the
    same corpus, it's wrong to consider that they name the same thing.
    The patch added an "is_anonymous" property to types created by the
    DWARF reader so that such anonymous types can be detected by the
    type canonicalizer; they are thus not involved in this
    optimization.  Note that the abixml writer and reader have been
    updated to emit and read this property.
  - typedefs.  I have seen in some boost code two typedefs of the same
    name refer to different underlying types.  I believe this is a
    violation of ODR.  I'll need to investigate on this later.  And I
    think we really need to detect these ODR violations as part of
    this enhancement request:
    https://sourceware.org/bugzilla/show_bug.cgi?id=18941.
  - pointers, references, arrays and function types, as they can refer
    to the two exceptions above.

This is the last patch of the series which aimed at speeding up type
canonicalization in the context of types being re-defined a lot in
translation units.

[1]: Instruction to build libmozjs.so from the mongodb sources:
- git clone https://github.com/mongodb/mongo.git
- cd mongo
- scons --link-model=dynamic build/opt/third_party/mozjs-38/libmozjs.so

[2] One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule

* include/abg-fwd.h (class corpus): Forward-declare this.
(is_anonymous_type): Declare this new function.
* include/abg-ir.h (corpus_sptr, corpus_wptr): Declare these
typedefs here too.
(translation_unit::{g,s}et_corpus): Declare new member functions.
(type_or_decl_base::{g,s}et_corpus): Likewise.
* src/abg-ir.cc (translation_unit::priv::corpus): New data member.
(translation_unit::priv::priv): Initialize it.
(translation_unit::{g,s}et_corpus): Define new accessors.
(translation_unit::get_global_scope): Propagate the corpus of the
translation unit to its newly created global scope.
(translation_unit::bind_function_type_life_time): Propagate the
corpus of the translation_unit to the added function type.
(type_or_decl_base::priv::corpus_): Add new data member.
(type_or_decl_base::priv::priv): Initialize it.
(type_or_decl_base::{g,s}et_corpus): Define new accessors.
(scope_decl::{add,insert}_member_decl): Propagate the context's
corpus to the member added to the context.
(decl_base::priv::is_anonymous_): Add new data member.
(decl_base::priv::priv): Initialize it.
(decl_base::{s,g}et_is_anonymous): Define accessors.
(is_anonymous_type): Define a new test function.
(decl_base::set_name): Update the "is_anonymous" property.
(type_base::get_canonical_type_for): Implement the ODR-based
optimization to type canonicalization.
* src/abg-corpus.cc (corpus::add): When a translation unit is
added to a corpus, set the corpus of the translation unit.
* src/abg-dwarf-reader.cc (build_enum_type)
(build_class_type_and_add_to_ir): Set the "is_anonymous" flag on
anonymous enums and classes.
* src/abg-reader.cc (read_is_anonymous): Define new static
function.
(build_type_decl, build_enum_type, build_class_decl): Call the new
read_is_anonymous function and set the "is_anonymous" property on
the built type declaration.
* src/abg-writer.cc (write_is_anonymous): Define new static
function.
(write_type_decl, write_enum_type_decl, write_class_decl): Write
the "is_anonymous" property.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.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/test17-pr19027.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoLate canonicalize all types that reference classes when reading DWARF
Dodji Seketeli [Sun, 4 Oct 2015 10:08:08 +0000 (12:08 +0200)]
Late canonicalize all types that reference classes when reading DWARF

Until now, the DWARF reader would late canonicalize typedefs to
classes, as well as classes.  That is not enough.  Let's also
late-canonicalize pointers, references and array of classes too.  This
is because classes that might not be finished yet might be referenced
by those types, and so we want to wait until they are finished before
we canonicalize them.

* include/abg-fwd.h (peel_array_type): Declare new function.
* src/abg-ir.cc (peel_array_type): Define it.
(peel_typedef_pointer_or_reference_type): Peel arrays too, to get
the type of its element.
* src/abg-dwarf-reader.cc (maybe_canonicalize_type): If a pointer,
reference, array or typedef references a class, then do
late-canonicalize this type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix infinite loop in peel_typedef_pointer_or_reference_type
Dodji Seketeli [Sun, 4 Oct 2015 09:30:57 +0000 (11:30 +0200)]
Fix infinite loop in peel_typedef_pointer_or_reference_type

* src/abg-ir.cc (peel_typedef_pointer_or_reference_type): Make
sure the variable tested in the condition is the one updated by
the loop.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoTry harder to hash_type_or_decl avoid the slow path
Dodji Seketeli [Fri, 2 Oct 2015 17:57:33 +0000 (19:57 +0200)]
Try harder to hash_type_or_decl avoid the slow path

In hash_type_or_decl, when we encounter a declaration-only class
(those have no canonical type), we not trying to get the canonical
type of the definition, when the class had a definition.  We were
instead going straight to the slow path of computing the recursive
hash of the type.

This patch tries to get the canonical type of the class definition,
when it exists.

* src/abg-ir.cc (hash_type_or_decl):  When a declaration-only
class has a definition, then use the canonical type of that
definition as a hash value.  If the class no definition, only
then, use the slow patfh of computing the recursive progressive
hash value of the type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDo not use recursive type hashing when writing out function types
Dodji Seketeli [Fri, 2 Oct 2015 17:42:12 +0000 (19:42 +0200)]
Do not use recursive type hashing when writing out function types

When the abixml writer emits function types, it puts function
types that are referenced by pointers or references into a map on the
side.  Unfortunately, that map hashes types by recursively calculating
a progressive hash value.  That is dog slow and we avoid that
throughout the code base.

This patch changes that to use the numerical values of the canonical
type pointer of the function type as a hash, making abixml fast again,
again on big library as libmozjs.so.

* src/abg-writer.cc (typedef fn_shared_ptr_map): Remove.
(write_context::m_referenced_fntypes_map): Change the type of this
into type_ptr_map.
(write_context::{record_fntype_as_referenced,
fntype_is_referenced}): Use the pointer value of the canonical
type of the referenced type as key for the map.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoPrevent build_function_type from not canonicalizing certain types
Dodji Seketeli [Fri, 2 Oct 2015 16:27:34 +0000 (18:27 +0200)]
Prevent build_function_type from not canonicalizing certain types

I noticed that in some cases in build_function_type, when building the
sub-types of the function type, the construction of a function type
for the same DIE could be triggered.  This happens frequently for
aggregate types that happen to be recursive.  In those cases, we must
arrange for the construction of the function type for the same DIE to
return the same type that is being currently built by
build_function_type; otherwise, several types are going to be built
for the same DIE, and only one of them is going to be canonicalized.
build_function_type was just not prepared for this.

This patch fixes that.

Please note that the patch changes the test output
/home/dodji/git/libabigail.git/merge/build/tests/output/test-read-dwarf/test12-pr18844.so.abi
but it's a later patch that adjust that file because several patches
are going to require an update to that file.  We are going to update
that patch in one go at the end of the patch series.

* src/abg-dwarf-reader.cc (build_function_type): Associate the
type being built with its DIE, before starting to build the
sub-types.  The current type is then amended with the sub-types
that are built later.
(build_ir_node_from_die): In the case for DW_TAG_subroutine_type,
do not associate the type to the DIE here, as it's been done in
build_function_type.
* src/abg-ir.cc (function_type::set_parameters): Adjust the index
of the parameters being set to the function: they start at 1,
unless the first parameter is artificial, in which case its index
starts at zero.  This is just like what is done when the function
type is constructed directly with the parameters passed as an
argument to the constructor.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix detection of changes in pointer diff in the comparison engine
Dodji Seketeli [Fri, 2 Oct 2015 16:21:43 +0000 (18:21 +0200)]
Fix detection of changes in pointer diff in the comparison engine

* src/abg-comparison.cc (pointer_diff::has_changes): Just
comparing the underlying type might not be enough.  Let's just
compare the pointer itself.  Now that we have canonical types,
comparing the pointer itself is not slower.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDo not overly canonicalize types during typedef stripping
Dodji Seketeli [Fri, 2 Oct 2015 15:59:52 +0000 (17:59 +0200)]
Do not overly canonicalize types during typedef stripping

strip_typedef() canonicalizes the stripped typed, even if the input
type was not canonicalized.  This can lead to early canonicalization
that is not warranted.  For instance, is_compatible_with_class_type()
calls strip_typedef() and can be called during DWARF reading on types
that haven't been canonicalized yet; this was triggering a
canonicalization what was happening too early.

With this patch, strip_typedef() does not canonicalize a stripped type
if the input type wasn't itself canonicalized.

* src/abg-ir.cc (strip_typedef): Do not canonicalize the stripped
type if the input one is not canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoCleanup some IR type comparison operators
Dodji Seketeli [Fri, 2 Oct 2015 15:05:23 +0000 (17:05 +0200)]
Cleanup some IR type comparison operators

* include/abg-ir.h (operator==): In the overloads for type_decl,
enum and class_decl, turn the shared_ptr parameter into a const
reference to the shared_ptr.
* src/abg-ir.cc (operator==): Do the same in the definitions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd missing deep equality operator for pointer and reference types
Dodji Seketeli [Fri, 2 Oct 2015 14:50:22 +0000 (16:50 +0200)]
Add missing deep equality operator for pointer and reference types

I noticed that abigail::ir::pointer_type_def_sptr and
abigail::ir::reference_type_def_sptr did not have any free form
operator '==' defined.  So writing a == b with a and b being either
pointer_type_def_sptr or reference_type_def_sptr was using pointer
value comparison, as opposed to deeply comparing the pointer and
reference instances.

This patch adds those two missing operators.

* include/abg-ir.h (pointer_type_def::operator==): Add an overload
for pointer_type_def.
(reference_type_def::operator==) Add an overload for
reference_type_def.
(operator==): Add an overload for pointer_type_def_sptr and
reference_type_def_sptr.
* src/abg-ir.cc (pointer_type_def::operator==): Make the overload
for type_base& use the overload for decl_base&.  Add a new
overload for pointer_type_def& and make is use the overload for
decl_base& too.
(operator==): Add free form overloads for pointer_type_def& and
reference_type_def&.
(reference_type_def::operator==): Add comments. Add an overload
for reference_type_def&.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoconstify is_class_type()
Dodji Seketeli [Fri, 2 Oct 2015 18:08:27 +0000 (20:08 +0200)]
constify is_class_type()

This the first patch of a series of 11 patches which aims at speeding
up the time taken by "abidw --noout libmozjs.so".  That shared library
is built among by the mongodb project, among others.  And abidw is
taking around 5 minutes on my old Lenovo X220 laptop.  After the
series of patches, the same command is taking one minute and a half.

The core of the optimization is to speed up type canonicalization that
happens at the end of DWARF reading, once libabigail has built the IR
or the ABI of the entire elf binary.  The optimization comes from an
insight derived from the One Definition Rule of C++, as explained at
https://en.wikipedia.org/wiki/One_Definition_Rule.

But before being able to perform that optimization, several fixes and
code massaging were necessary.  I have split those changes up in the
first 10 patches of the series.  The last patch thus contains the crux
of the optimization.  Its cover letter also contains instructions on
how to build libmozjs.so, from mongodb, for those who want to
replicate the results I have seen.

Note that some of the first 10 patches incur adjustment in the test
suite, but don't carry those necessary adjustments.  All test suite
adjustments are carried by the last, 11Th patch.

The short description of the patches of the series are:

    constify is_class_type()
    Add missing deep equality operator for pointer and reference types
    Cleanup some IR type comparison operators
    Do not overly canonicalize types during typedef stripping
    Fix detection of changes in pointer diff in the comparison engine
    Prevent build_function_type from not canonicalizing certain types
    Do not use recursive type hashing when writing out function types
    Try harder to hash_type_or_decl avoid the slow path
    Fix infinite loop in peel_typedef_pointer_or_reference_type
    Late canonicalize all types that reference classes when reading DWARF
    Use the ODR to speed up type canonicalization

And below is the ChangeLog of this first patch.

* include/abg-fwd.h (is_class_type): Take a pointer to const.
* src/abg-ir.cc (is_class_type): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 19027 - ABI asymmetry with enums over INT_MAX
Ondrej Oprala [Thu, 1 Oct 2015 09:06:15 +0000 (11:06 +0200)]
Bug 19027 - ABI asymmetry with enums over INT_MAX

* src/abg-reader.cc (build_enum_type_decl): Use strtol
instead of atoi to parse the values and check for overflow.
* tests/data/Makefile.am: Add the new test material to the build
system.
* tests/data/test-read-dwarf/test17-pr19027.so: New test file.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
* tests/test-read-dwarf.cc: Adjust to launch the new test.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoEncourage people to use autoreconf -i
Dodji Seketeli [Thu, 1 Oct 2015 08:40:51 +0000 (10:40 +0200)]
Encourage people to use autoreconf -i

This lets autoreconf add stuff that might be missing, rather than just
bailing out.

* COMPILING: Mention autoreconf -i, rather than just autoreconf.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 17340 - Support pointers and references to functions
Ondrej Oprala [Wed, 23 Sep 2015 06:44:00 +0000 (08:44 +0200)]
Bug 17340 - Support pointers and references to functions

* include/abg-comparison.h (compute_diff_for_distinct_kinds): Take the
first two arguments of type const type_or_decl_base_sptr instead.
* include/abg-ir.h (translation_unit::get_function_types): Declare new
method.
(function_types): Declare new typedef.
* src/abg-comparison.cc (compute_diff_for_types): Take the first two
arguments of type const type_or_decl_base_sptr instead of a const
decl_base_sptr.
(try_to_diff): Likewise.
(try_to_diff<class_decl>): Likewise.
(try_to_diff_distinct_kinds): Likewise.
(compute_diff_for_distinct_kinds): Likewise. Also remove a variant
accepting arguments of type const type_base_sptr.
* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Skip
building a pointer if it points to the beginning of a vptr.
(build_pointer_type_def): Declare utype_decl of type
type_or_decl_base_sptr and adjust assignments to it accordingly.
(build_function_type): New function definition.
(build_function_decl): Call build_function_type instead of building
an ftype manually.
(build_ir_node_from_die): Amend case DW_TAG_subroutine_type with
appropriate calls to build a function type.
* src/abg-ir.cc (translation_unit::get_function_types): New method
definition.
({pointer,reference}_type_def::pointer_type_def): Expect that
pointed_to might not have an accompanying declaration and set a type's
name in this case as well.
({pointer,reference}_type_def::get_qualified_name): Generate a
qualified name even if the pointed-to type has no declaration.
* src/abg-reader.cc (build_function_type): New function definition.
(handle_element_node): Return a type_or_decl_base_sptr instead and
try calling handle_function_type in addition to others.
(handle_function_type): New function definition that calls
build_function_type.
(build_type): Try calling build_function_type as well.
* src/abg-writer.cc (fn_shared_ptr_map): Declare new typedef.
(write_context::{clear_referenced_fntypes_map,fntype_is_referenced,
record_fntype_as_referenced}): New member functions.
(write_translation_unit): Call the new clear_referenced_fntypes_map.
* tests/data/Makefile.am: Add the new test material to the build
        system.
(write_translation_unit): Separately write function types that have
been recorded to emit by write_{pointer,reference}_type_def.
(write_{pointer,reference}_type_def): Record the type pointed to as
a type to be emitted if type == function type.
(write_function_type): Write the details of a function type in the
abixml format and unmark the type.
* tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: New
test reference report.
* tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.cc: New test
source files.
* tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.o: New binary
test inputs.
* tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: New
test reference report.
* tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.cc: New test
source files.
* tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.o: New binary
test inputs.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
Adjust.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
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/test9-pr18818-clang.so.abi: Likewise.
* tests/data/test-read-write/test27.xml: New test source file.
* tests/test-diff-dwarf.cc: Adjust to launch the new tests.
* tests/test-read-write.cc: Likewise.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoGeneralize some dwarf-reader functions to generate and return
Ondrej Oprala [Wed, 9 Sep 2015 08:12:03 +0000 (10:12 +0200)]
Generalize some dwarf-reader functions to generate and return
instances of type_or_decl_base_stpr to be able to propagate
types occurring without an accompanying declaration.

* src/abg-dwarf-reader.cc (build_ir_node_from_die): Return
a type_or_decl_base_sptr instead.
  (get_scope_for_die): Likewise.
(build_class_type_and_add_to_ir): Typecast the assignment from
build_ir_node_from_die properly.
(build_{qualified,reference,array,typedef}_type): Likewise.
(build_pointer_type_def): Likewise.
(build_{var,function}_decl): Likewise.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoMove a constructor declaration
Ondrej Oprala [Tue, 29 Sep 2015 09:05:51 +0000 (11:05 +0200)]
Move a constructor declaration

* include/abg-ir.h (decl_base): Change the decl_base() declaration's
visibility to private.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
9 years agoBug 18535 - abidiff reports false positive ABI difference for libstdc++
Dodji Seketeli [Thu, 24 Sep 2015 09:00:12 +0000 (11:00 +0200)]
Bug 18535 - abidiff reports false positive ABI difference for libstdc++

When the DWARF reader of libabigail sees a data member for a given
class flagged as being a declaration, it considers the declaration as
being a definition.  The reason why it doesn't strictly trust the
"is_declaration" flag of DWARF is that some DWARF producers sometimes
wrongly emit that flag.

But then, it turns out that a class declaration can have a *static*
data member without loosing its declaration-only property.  This patch
thus changes the behaviour of the DWARF reader to make it consider the
class declaration as being a definition when the class has a
*non-static* data member; a static data member only is not enough to
make the class declaration become a definition.

* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): The
presence of a data member shouldn't make a declaration-only class
loose its declaration-only-ness; the presence of a enon-static*
data member should.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-4.8.3.so:
New binary test input.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-4.9.2.so:
Likewise.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
New test reference output.
* tests/data/Makefile.am: Add the new test material to the build
system.
* tests/test-diff-filter.cc (in_out_specs): Add the new test
inputs to the set of inputs to consider.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoRemove duplicated runtestreaddwarf test
Dodji Seketeli [Mon, 21 Sep 2015 13:23:14 +0000 (15:23 +0200)]
Remove duplicated runtestreaddwarf test

* tests/Makefile.am: Remove one copy of the runtestreaddwarf test
that is present twice.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd a missing function declaration
Dodji Seketeli [Mon, 21 Sep 2015 13:22:35 +0000 (15:22 +0200)]
Add a missing function declaration

* include/abg-tools-utils.h (dir_name): Add missing function
declaration.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoRemove some dead code in abilint
Dodji Seketeli [Mon, 21 Sep 2015 13:20:10 +0000 (15:20 +0200)]
Remove some dead code in abilint

* tools/abilint.cc (options::bidiff): Remove.
(options::options): Adjust.
(display_usage): Remove usage string for --bidiff
(parse_command_line): Remove parsing of un-implemented option
--bidiff.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd a new --abidiff option to abidw
Dodji Seketeli [Mon, 21 Sep 2015 13:14:26 +0000 (15:14 +0200)]
Add a new --abidiff option to abidw

This is a debugging and sanity check option.  It saves the abi of the
ELF binary to a temporary file, reads it back and compares the abis of
the temporary file against the abi of the input ELF binary.

* tools/abidw.cc (options::abidiff): New data member.
(options::options): Initialize it.
(display_usage): Add a usage string for the new --abidiff option.
(parse_command): Parse the new --abidiff options.
(main): Save the abi of the input elf in a temporary abixml file;
read it back and compare both.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMisc style fixes
Dodji Seketeli [Mon, 21 Sep 2015 12:49:29 +0000 (14:49 +0200)]
Misc style fixes

* src/abg-hash.cc (class_decl::hash::operator()): Use a temporary
variable to ease debugging.
* src/abg-reader.cc (read_context::is_wip_type): Make this
function const.
* src/abg-writer.cc (write_context): Move data members at the top.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoSpeed up type canonicalization by avoiding recursive hashing
Dodji Seketeli [Mon, 21 Sep 2015 11:51:31 +0000 (13:51 +0200)]
Speed up type canonicalization by avoiding recursive hashing

Recursive type hashing was showing up as the major hot spot of
performance profiles.  After spending a few days on trying to speed it
up, I have officially declared recursive tree node hashing as a slow
process and I am giving up.

I have thus decided to not use that at type canonicalization time.

Rather, I am proposing a new type canonicalization routine where types
are first hashed by hashing their pretty representation string.

Basically, if T is the total number of types in the system and C the
number of classes of equivalences (or the number of canonical types),
the number of type comparisons done by a naive type canonicalization
routine is N x C.  With the worse C being equal to N itself, that
worse number of comparisons is N*N.

By using a hash table to store the canonical types, keyed by a hash of
their pretty representation string, the number of type comparisons can
be brought down to N*P, where P is a the greater number of which
pretty representation string hash collide.  That number P is usually
small; my measurements show that N usually goes from 1 to 3.  And
moreover, computing the hash of the pretty representation string of
the function is way faster than using the recursive type hash!

As a result, running abidw on the libcilkrts.so library, from GCC goes
from 12 minutes to 0.4 seconds!

Incidentally, now that we are not trying to speed up the recursive
type hashing process, all the complicated business we had around
caching the result of the hashing is gone!  I was thinking that hash
cashing was inherently a bad idea, especially for recursive types --
that refer to themselves directly or indirectly, because in those
case, depending on when you cached the hash value, the value of the
hashing can be different.

The abixml writer's code doesn't use the recursive type hash anymore
either; it uses the pointer value of the canonical type as hash.
Super fast too!

The patch had to fix pieces here and there to comply with the fact
that canonical types are now used across the board in a mandatory
fashion.

* include/abg-ir.h (canonical_types_map_type): Adjust this typedef
to make it point to an unordered_map which the key is now a string
and the value is a vector of types.
(type_or_decl_base::{get_cached_hash_value, set_cached_hash_value,
cached_hash}): Remove these member functions and type.
(struct type_base::cached_hash): Remove.
* src/abg-ir.cc (struct type_or_decl_base::priv::hash_): Remove.
(type_or_decl_base::priv::priv): Adjust.
(type_or_decl_base::{g,s}et_cached_hash_value): Remove.
(type_base::get_canonical_type_for): For declaration-only classes,
look at their definition for the canonical_type.  Do not use
recursive type hashing anymore.  Rather, use the pretty
representation string, and hash that.
(class_decl::base_spec::get_hash): Do away with hash value caching
here.
(class_decl::operator==): For decl-only classes, look at their
definitions for canonical types.
(hash_type_or_decl): Adjust comment.  Use the canonical type
pointer value for type hash.  That's the fast path.  Otherwise, if
not available, fall back to a slow path which is the recursive
type hash we were using before.
* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Schedule all
classes and typedef to classes for late canonicalization.
* src/abg-hash.cc (type_base::dynamic_hash::operator()): There is
no hash value cashing anymore.
(type_base::cached_hash::operator()): Remove.
* src/abg-reader.cc (read_context::get_type): Slight style
adjustment.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer): Do not forget to canonicalize
types when reading just one translation unit.
(build_type_tparameter, build_template_tparameter): Canonicalize
the type.
* src/abg-writer.cc (struct type_hasher): New hasher type.
(type_ptr_map): Use a deep pointer comparison equal operator
functor, and canonical types as type hash values.
(write_class_decl): Do not write size and alignment on decl-only
classes.  Do not record decl-only classes as being emitted.  Their
definition must be emitted before.
* tests/test-read-write.cc (main): Do not do abi testing on
translation units (as opposed to doing it on abi corpora) as that
code is not wet yet.  We need to know how to diff namespaces.
* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
* tests/data/test-read-dwarf/test10-pr18818-gcc.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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoUpdate qualified name of a decl when it's added to its context
Dodji Seketeli [Mon, 21 Sep 2015 09:11:05 +0000 (11:11 +0200)]
Update qualified name of a decl when it's added to its context

The building of the qualified name of a declaration is showing up in
performance profile as a hot spot.  This patch addresses that
performance issue by updating the qualified name of a declaration
whenever the declaration is added to its context and saving the
result.  Getting the qualified name later is just a matter of a string
copy.  I guess we can do something about those string copies later as
they don't show up high performance profiles at the moment.

* include/abg-ir.h (decl_base::priv_): Make this be public, so
that the qualified name updater function can access it.
(class class_decl): Make set_member_is_static() a friend function.
* src/abg-ir.cc (class ::qualified_name_setter): New tree walking
type.
(decl_base::get_qualified_parent_name): Do not do any computation
here.  Just return the pre-computed qualified parent name string.
(decl_base::get_qualified_name): Likewise, for qualified name.
(scope_decl::{add,insert}_member_decl): Update the qualified name of the
newly added member.  Set the scope of the member here.  It's not
going to be set elsewhere, from now on.
(add_decl_to_scope): Do not set the scope here anymore.  Just call
scope_decl::add_member_decl and let it do the work.
(insert_decl_into_scope): Likewise, just call
scope_decl::insert_member_decl and let it do the work.
(class_decl::{add_data_member, add_member_function}): Do not
handle details of context setting at this point.  Let
scope_decl::add_member_decl do it.  Adjust the properties of the
context relation afterwards.  In add_data_member, when a data
member changes its static-ness, move the data member into the
class_decl::priv::non_static_data_members_ or out of it, as
necessary.
(class_decl::insert_member_decl): By default, a data member is
considered static.
(set_member_is_static): Move this definition after the definitions
of class_decl, so that this function can see those.  Also, when a
data member changes its static-ness, move the data member into the
class_decl::priv::non_static_data_members_ or out of it, as
necessary.
(class_decl::add_member_function_template):  As we the
underlying function template decl to the context, do not do any
scope adding for it here.
(::qualified_name_setter::{do_update, visit_begin}): Define new
member functions.
(update_qualified_name): Define new static function.
* src/abg-reader.cc (build_class_decl): Make build_function_decl,
build_var_decl, build_function_tdecl and build_class_tdecl
automatically add the created decl to their context, and then
update the properties of the resulting member decl later, just
like what we do in the DWARF reader.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd new test functions
Dodji Seketeli [Mon, 21 Sep 2015 08:53:33 +0000 (10:53 +0200)]
Add new test functions

This patch adds a new set of test functions that are going to be used
in subsequent patches to come.

* include/abg-fwd.h (is_function_decl, is_decl, is_namespace)
(is_scope_decl): Declare new function overloads.
* src/abg-ir.cc (is_function_decl, is_decl, is_namespace)
(is_scope_decl): Define them.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoConstify some diff-utils functor operators
Dodji Seketeli [Mon, 21 Sep 2015 08:46:06 +0000 (10:46 +0200)]
Constify some diff-utils functor operators

* include/abg-diff-utils.h (deep_ptr_eq_functor::operator()): Make
the overloads be const.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoSupport source_location_not_in and source_location_not_regexp suppressions
Dodji Seketeli [Wed, 16 Sep 2015 09:37:22 +0000 (11:37 +0200)]
Support source_location_not_in and source_location_not_regexp suppressions

This patch adds support for properties source_location_not_in and
source_location_not_regexp in the [suppress_type] section of
suppression specifications.  So the suppression specification:

  [suppress_type]
    source_location_not_in = foo1.h, foo2.h bar1.h bar2.h

suppresses ABI change reports about types that are *NOT* defined in
files foo{1,2}.h and bar{1,2}.h.  The intended use of this construct is to
constrain abi change reports to types that are part of the API of a
given shared library.  The API of the library is supposed to be
defined in foo.h and bar.h only.

Similarly, the suppression specification:

  [suppress_type]
    source_location_not_regexp = (foo|bar){1,2}\\.h

suppresses ABI change reports about types that are not defined in the
same set of files foo1.h, foo2.h, bar1.h and bar2.h.

* include/abg-ini.h (enum property_value::value_kind): Add a
LIST_PROPERTY_VALUE kind.
(class {list_property_value, list_property}): Declare new types.
(is_list_property, is_list_property_value): Declare new functions.
* src/abg-ini.cc (struct list_property_value::priv): Define new
type.
(list_property_value::{list_property_value, get_content,
set_content, as_string}): Define new member functions.
(is_list_property_value): Define new function.
(struct list_property::priv): Define new type.
(list_property::{list_property, get_value, set_value,
handle_escape}): Define new member functions.
(is_list_property): Define new function.
(read_context::buf_): New data member.
(read_context::{peek, get, put_back, good, eof, read_string,
read_list_property_value}): New member functions.
(read_context::read_next_char): Use the new read_context::{get,
good, eof} member function, rather than using the input stream
directly.
(read_context::{skip_white_spaces, skip_comments,
skip_white_spaces_or_comments, read_property_name,
read_function_name, read_function_argument,
read_function_call_expr, read_property_value,
read_tuple_property_value, read_section_name, read_section}):
Adjust to use the new member functions of read_context rather than
using the input stream directly.
(read_context::read_string_property_value): Likewise.  Use the new
read_context::read_string() method.
(read_context::{read, write}_property): Support reading list_property.
* include/abg-comparison.h
(type_suppression::{get_source_locations_to_keep,
set_source_locations_to_keep,
set_source_location_to_keep_regex_str,
get_source_location_to_keep_regex_str}): Add new member functions.
* src/abg-comparison.cc
(type_suppression::priv::{source_location_to_keep_,
source_location_to_keep_regex_str_,
source_location_to_keep_regex_}): Add new data members.
(type_suppression::priv::{g,s}et_source_location_to_keep_regex):
Define new member functions.
(type_suppression::{g,s}et_source_locations_to_keep): Define new
member functions.
(type_suppression::{g,s}et_source_location_to_keep_regex_str):
Likewise.
(type_suppression::suppresses_type): Support
"source_location_not_regexp" and "source_location_not_in"
properties of suppression specifications.
(read_type_suppression): Likewise. Also adjust to the fact that
ta tuple property value that is a list of strings is not a list
property value.
* doc/manuals/libabigail-concepts.rst: Add documentation for
source_location_not_in and source_location_not_regexp.
* tests/data/test-diff-suppr/libtest26-loc-suppr-v{0,1}.so: New
binary test inputs.
* tests/data/test-diff-suppr/test26-loc-suppr-{0,1,2}.suppr: New
suppression specification test inputs.
* tests/data/test-diff-suppr/test26-loc-suppr-report-{0,1,2,3}.txt:
New test reference reports.
* tests/data/test-diff-suppr/test26-loc-suppr-v{0,1}.cc: Source
code of the test binary input above.
* tests/data/test-diff-suppr/test26-loc-suppr.h: Likewise.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-diff-suppr.cc (in_out_specs): Add the new test inputs above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoPass simple property data by reference
Dodji Seketeli [Wed, 16 Sep 2015 09:16:25 +0000 (11:16 +0200)]
Pass simple property data by reference

* include/abg-ini.h (simple_property::{simple_property,
set_value}): Pass the value shared pointer by reference.
* src/abg-ini.cc (simple_property::{simple_property, set_value):
Pass the value shared pointer by reference.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMake string_ends_with() allow long suffixes
Dodji Seketeli [Tue, 15 Sep 2015 09:02:55 +0000 (11:02 +0200)]
Make string_ends_with() allow long suffixes

Make string_ends_with() allow suffixes that are as long as the string we are
looking at.

* src/abg-tools-utils.cc (string_ends_with): Allow suffixes of the
same size as the input string.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdd missing 'break' keyword in e_machine_to_string()
Dodji Seketeli [Sun, 13 Sep 2015 13:47:10 +0000 (15:47 +0200)]
Add missing 'break' keyword in e_machine_to_string()

* src/abg-dwarf-reader.cc (e_machine_to_string): Add missing
'break' keywords in switch/case statement.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix compilation warnings in abipkgdiff.cc
Dodji Seketeli [Wed, 9 Sep 2015 11:56:02 +0000 (13:56 +0200)]
Fix compilation warnings in abipkgdiff.cc

* tools/abipkgdiff.cc (package::erase_extraction_directory)
(extract_rpm, extract_deb, extract_tar)
(erase_created_temporary_directories_parent): Check the return
value of the system() function.
(extract_package): Add necessary white space.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix spurious errors in the install-man-and-info-doc target
Dodji Seketeli [Wed, 9 Sep 2015 07:19:10 +0000 (09:19 +0200)]
Fix spurious errors in the install-man-and-info-doc target

* doc/manuals/Makefile.am (install-man-and-info-doc): Don't check
for abidiff.info, that thing doesn't exist.  Rather, check for
abigail.info.  Use gzip -f in case the zipped file exists already.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoCompare qualified name in decl_base comparison operator
Dodji Seketeli [Wed, 9 Sep 2015 06:17:27 +0000 (08:17 +0200)]
Compare qualified name in decl_base comparison operator

* src/abg-ir.cc (equals): In the overload for decl_base, compare
qualified names, not just names.
* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix a stupid typo in function sorting code
Dodji Seketeli [Tue, 8 Sep 2015 13:48:13 +0000 (15:48 +0200)]
Fix a stupid typo in function sorting code

* src/abg-comparison.cc (function_comp::operator()): Fix a typo
preventing the proper sorting of function name when their
declarator names are equal.  Oops.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoUpdate manual for abipkgdiff
Dodji Seketeli [Tue, 8 Sep 2015 08:11:34 +0000 (10:11 +0200)]
Update manual for abipkgdiff

* doc/manuals/abipkgdiff.rst: Say we support tarballs and plain
directories.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdjust {s,g}et_show_stats() to use a reference
Dodji Seketeli [Mon, 7 Sep 2015 21:42:17 +0000 (23:42 +0200)]
Adjust {s,g}et_show_stats() to use a reference

* include/abg-dwarf-reader.h ({s,g}et_show_stats): Use a reference
to the reader.
* tools/abidiff.cc (main): Adjust.
* tools/abidw.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoUse cache type hash values only after type canonicalization is done
Dodji Seketeli [Mon, 7 Sep 2015 21:23:51 +0000 (23:23 +0200)]
Use cache type hash values only after type canonicalization is done

Look at this code:

    struct list;

    struct payload
    {
     int value;
     list* parent_list; //<-- the hash value of struct list when looking
                        //    through this pointer is the non-zero
                        //    value as computed on the struct list
                        //    type below.

    };

    struct list
    {
     payload* p; // <-- While walking the struct list type, the hash
                 // value of the 'struct list' sub-tree node when
 // looking through this pointer is zero, because we
 // are still computing the hash value of struct list.
 // we do it this way to break the otherwise infinite
                 // recursion that might occur here.

     list* next; // <-- likewise here.
     list* prev; // <-- likewise here.
    }; // <-- when we reach this point the hash value of struct list
       // is computed and is different from zero.

Basically, when a type refers to itself in one of its sub-type (like
struct list here, where list::p refers to struct list, because its
type contains a pointer to struct list), then we need to devise a way
to break the infinite recursion we might fall into when computing its
hash value.

So, when computing the hash value of struct list, when we look at the
type of list::prev, which is "list*", we say that the hash value of the type
pointed to by the type of list::next (which is struct list itself) is
zero.  This allows us to break the possibly infinite recursion here.

But then, this means that the hash value of "struct list" depends on
*when* we request that hash value.  If we are computing the hash value
of struct list itself, then the temporary value of "struct list" is
zero.  But then once we are done computing the hash value of "struct
list", that value becomes non-zero.

Hence, the hash value of a type depends on when that value is
computed.

But then if we want to cache that hash value and re-use it later,
which value should we cache?  Definitely not the zero value!

So in other words, we can use (and thus cache) the hash value of a
given type T only after the hash values of all types which use T have
been computed.

To satisfy that condition, we decide to use the (cached) hash value of
each type only after we've computed all the hash values of all types
of the system.

So, during type canonicalization, when a type T is canonicalized, this
patch stores the hash value of T.  But then it's only when all types
are canonicalized that the hashing code is allowed to re-use the
cached value of types.

This fixes the issues of spurious type differences introduced when the
same type was read either from DWARF or from abixml.  Those
differences where introduced by differences in the order of hashing
types which sub-types refer to themselves. The patch also updates
regression tests accordingly.

* src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Before we
read debug info and build the IR, set a flag in the environment
saying that type canonicalization isn't finished yet.  But then,
after type canonicalization is done, flip that flag to say that
type canonicalization is done.
* src/abg-reader.cc (read_corpus_from_input): Likewise.
* src/abg-ir.cc (type_base::get_canonical_type_for): Once a type
has been canonicalized, cache its hash value.
* src/abg-hash.cc (type_base::dynamic_hash::operator()): If type
canonicalization has been done and if the type has a cached value,
use that one.
* tests/data/test-read-dwarf/test2.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
* tests/data/test-read-dwarf/test10-pr18818-gcc.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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoIntroduce the concept of environment
Dodji Seketeli [Mon, 7 Sep 2015 20:27:50 +0000 (22:27 +0200)]
Introduce the concept of environment

There are resources needed by the type system and other artifacts of
libabigail.  Today, when the life time of those resources need to be
greater than all of artifacts of Abigail, then said resources are made
global.

But then global resources are not great, if anything because they
complicate the future use of the library in concurrent computing
setups.

As I was in the need to add one resource to be used by the type
system, I decided to sit down and first overhaul how these long lived
resources needed to be handled.

And here comes the concept of "environment".  An environment is a
place where one can put resources that need to live longer than all
the other artifacts of the Abigail system.  And so, the code that
creates Abigail artifacts needs and environment of for said artifacts
to use.  In other words, artifacts now use an environment.

This has interesting and strong implications.  We can only compare two
artifacts if they use the same environment.  This is quite a strong
requirement.

But then when this requirement is fulfilled, comparing two types
amounts to just comparing two pointer values; hash values for types
can also be cached.  Now *that* is great for speed of comparison, is
it not?

This patch introduce the concept environment (which is basically a new
abigail::ir::environment type), removes the global variables and uses
the environment instead.  Each ABI artifact (either type or decl) now
has a ::get_environment() member function to get its environment.

This patch also disables the caching of hash values because the
caching must happen only *after* all types have been canonicalized.
We were not respecting that requirement until now, and that introduces
wrong hash values.  A subsequent patch is going to re-introduce hash
value caching again, once the infrastructure is in place to set a flag
in the environment (hah!) once type canonicalization is done, and then
later read that flag when some client code requests a hash value, to
know if we should look in the hash value cache or not.

The patch obviously changes the output of numerous regression tests
(if anything b/c it disables hash value caching) so 'make check'
yields regressions.  But then, it's only the subsequent patch that
updates the tests.

* include/abg-ir.h: Adjust note about memory management.
(class environment): Declare new class.
(translation_unit::translation_unit): Take an environment in
parameter.
(translation_unit::{g,s}et_environment): Declare new member
functions.
(type_or_decl_base::{g,s}et_environment): Likewise.
(type_or_decl_base::{get_cached_hash_value,
set_cached_hash_value}): Change the name of
decl_base::peek_hash_value() and decl_base::set_hash() here into
these and move them here.
(type_or_decl_base::hashing_started): Move
decl_base::hashing_started() here.
({g,s}et_environment_for_artifact): Declare new functions.
(class decl_base): Move member functions hashing_started(),
peek_hash_value() and set_hash() on to the type_or_decl_base base
class.
(scope_decl::scope_decl): Initialize the virtual member
type_or_decl_base().
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove these static member
functions.  They are now non-static member functions of the new
environment type.
* src/abg-ir.cc (class environment_setter): New internal class.
(get_canonical_types_map): Remove.  This now becomes a member
function of the environment type.
(class usage_watchdog): Remove.
(usage_watchdog_{s,w}ptr): Remove these typedefs.
(get_usage_watchdog_wptr, ref_usage_watchdog)
(maybe_cleanup_type_system_data): Remove these functions.
(translation_unit::priv::usage_watchdog_): Remove data member.
(translation_unit::priv::env_): New data member.
(translation_unit::priv::priv): Take an environment and initialize
the new env_ data member.  Do not initialize the removed
usage_watchdog_.
(translation_unit::translation_unit): Take an environment
parameter.
(translation_unit::get_global_scope): Set the environment of a new
global scope.
(translation_unit::{g,s}et_environment): New accessors.
(translation_unit::bind_function_type_life_time): Set the
environment of the function type.
(struct environment::priv): New class.
(environment::{environment, ~environment, get_canonical_types_map,
get_variadic_parameter_type_decl, canonicalization_is_done}): New
member functions.
(struct type_or_decl_base::priv): New class.
(type_or_decl_base::{type_or_decl_base, hashing_started,
get_cached_hash_value, set_cached_hash_value, set_environment,
get_environment, traverse}): New member functions.
({s,g}get_environment_for_artifact): New functions.
(decl_base::priv::{hash_, hashing_started}): Remove.
(decl_base::priv::priv): Adjust.
(decl_base::decl_base): In the copy constructor, initialize the
virtual base type_or_decl_base.  Do not initialize hash_ and
hashing_started data member that got removed.
(decl_base::{hashing_started, peek_hash_value, set_hash}): Remove
member functions.
(strip_typedef): Set the environment of the new type which has its
typedefs stripped off.  Adjust the call to type_or_void().
(scope_decl::{add, insert}_member_decl): Set the environment of
the new member decl to the environment of its scope.
(synthesize_type_from_translation_unit)
(synthesize_function_type_from_translation_unit): Set the
environment for the newly synthesized type. Adjust calls to
type_or_void().
(type_or_void): Take an environment in parameter.  Get the void
type from the environment.
(get_canonical_types_map): Remove.
(type_base::get_canonical_type_for): Get the canonical types map
from the environment, not from a global variable.
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove.
(pointer_type_def::pointer_type_def): Adjust call to type_or_void.
(reference_type_def::reference_type_def): Likewise.
(function_decl::parameter::get_pretty_representation): Get the
variadic parameter type decl from the environment.
(class_decl::priv::classes_being_compared_): Remove static data
member.
(class_decl::priv::{mark_as_being_compared,
unmark_as_being_compared, comparison_started): Use the "classes
being compared" map from the environment.
(class_decl::base_spec::get_hash): Adjust.
(keep_type_alive): Get the alive types array from the environment)
not from a global variable anymore.
(get_next_string): Put the counter in thread-local storage.
* src/abg-hash.cc (scope_decl::hash::operator())
(function_decl::hash::operator()): Do not handle caching (here).
* include/abg-corpus.h (corpus::{g,s}et_environment): Declare new
accessors.
* src/abg-corpus.cc (corpus::priv::env): New data member.
(corpus::priv::priv): Initialize it.
(corpus::corpus):  Take an environment in parameter.
(corpus::{g,s}et_environment): Define new member functions
(corpus::add): Set the environment of the newly added translation
unit, if it's not set already set.  In any case, assert that the
translation unit must use the same environment as the corpus.
* include/abg-dwarf-reader.h (create_read_context)
(read_corpus_from_elf): Take an environment parameter.
({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new
functions.
* src/abg-dwarf-reader.cc (read_context::{env_,
offline_callbacks_}): New data members.
(read_context::read_context): Initialize them.
(read_context::clear_per_translation_unit_data): Do not touch the
void type declaration, it doesn't belong to the translation unit.
(read_context::{env, offline_callbacks}): New accessors.
(read_context::{create_default_dwfl}): New member function.
(read_context::dwfl_handle): Add a setter overload.
({s,g}et_debug_info_root_path): Define new accessors.
(create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr):
Remove these.
(build_translation_unit_and_add_to_ir): Adjust to pass the
environment to the newly created translation unit.
(build_function_decl): Adjust to pass the environment to the
created function and parameter types.  Get variadic parameter type
node from the current environment, not from a global variable.
And do not try to canonicalize function types here.
(read_debug_info_into_corpus): Set the environment of the newly
created corpus.
(build_ir_node_for_void_type): Get the void type node from the
current environment, rather than from a global variable.
(create_read_context): Take the environment in parameter.
Create the default dwarf front end library handle using the new
member function of the read context.  Set the current environment
used by the reader.
(read_corpus_from_elf): Take an environment in
parameter. Overhaul.  This is now simpler.
(has_alt_debug_info): Adjust the call to create_read_context() to
make it pass an empty environment.
* include/abg-fwd.h (class environment): Forward declare.
* include/abg-reader.h (read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream)
(read_corpus_from_native_xml): Take an environment in parameter.
* src/abg-reader.cc (read_context::m_env): New data member.
(read_context::read_context): Initialize it.
(read_context::{get_environment, set_environment}): New data
member.
(read_translation_unit): Set environment of the new translation
unit.
(read_corpus_from_input): Set the environment of the new corpus.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream, read_corpus_from_native_xml):
Take an environment in parameter.
(build_function_parameter): Get variadic parameter type from the environment.
* src/abg-comparison.cc (compute_diff): Add asserts in all the
overloads to ensure that the artifact being compared come from the
same environment.
* tests/print-diff-tree.cc (main): Create an env for the ABI
artifacts to use.
* tests/test-abidiff.cc (main): Likewise.
* tests/test-diff-dwarf.cc (main): Likewise.
* tests/test-ir-walker.cc (main): Likewise.
* tests/test-read-dwarf.cc (main): Likewise.
* tests/test-read-write.cc (main): Likewise.
* tools/abicompat.cc (main): Likewise.
* tools/abidiff.cc (main): Likewise.
* tools/abidw.cc (main): Likewise.
* tools/abilint.cc (main): Likewise.
* tools/abipkgdiff.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix redundant const qualifier stripping
Dodji Seketeli [Mon, 7 Sep 2015 20:37:53 +0000 (22:37 +0200)]
Fix redundant const qualifier stripping

In the DWARF reader, we strip the const qualifier when it applies to
reference types because a reference is always const.  Those redundant
const qualifiers can later introduce spurious changes in type
comparison.

But then we were forgetting to add the stripped type to the IR, in
some cases.  This patch fixes that.

* include/abg-ir.h (operator&, operator~): Add overloaded bitwise
operators for qualified_type_def::CV.
* src/abg-ir.cc (operator&, operator~): Define them.
* src/abg-dwarf-reader.cc (maybe_strip_qualification): Fix
comment.  If there are multiple qualifiers, only strip the const
one.
(build_ir_node_from_die): Once we've built a qualified type, if
the 'const' qualifier is stripped, then add the new (stripped)
type to the set of new types.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix wording in README
Dodji Seketeli [Sat, 5 Sep 2015 08:29:00 +0000 (10:29 +0200)]
Fix wording in README

* README: Fix wording.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMisc style fixes
Dodji Seketeli [Wed, 2 Sep 2015 13:35:17 +0000 (15:35 +0200)]
Misc style fixes

* src/abg-hash.cc (class_decl::hash::operator()): Remove some dead
code.
* src/abg-ir.cc (equals): In the overload for class_decl,
re-indent.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoRe-arrange some regression tests order
Dodji Seketeli [Wed, 2 Sep 2015 13:33:27 +0000 (15:33 +0200)]
Re-arrange some regression tests order

runtestreaddwarf and runtestcanonicalizetypes.sh are now the tests
which takes the most time.  Run them at the beginning.

* tests/Makefile.am: Run runtestreaddwarf and
runtestcanonicalizetypes at the beginning.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 18904 - Fix support for C++ rvalue references
Dodji Seketeli [Wed, 2 Sep 2015 12:28:41 +0000 (14:28 +0200)]
Bug 18904 - Fix support for C++ rvalue references

* src/abg-comparison.cc (reference_diff::has_changes): Just
compare the references, rather than assuming that the change can
only be on underlying types.
(reference_diff::report): Describe lvalue/rvalue changes for
references.
* src/abg-ir.cc (reference_type_def::reference_type_def): Properly
set the name for an rvalue reference.
(equals): For references, compare lvalue-ness too.
(reference_type_def::get_qualified_name): Properly set rvalue
reference names.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-liba.so:
New test input.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-libb.so:
New test input.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
New test reference output.
* tests/data/Makefile.am: Add the new files to source
distribution.
* tests/test-diff-filter.cc (in_out_specs): Run the new tests.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMore type degradation fixes (from DWARF to abixml)
Dodji Seketeli [Wed, 2 Sep 2015 11:41:34 +0000 (13:41 +0200)]
More type degradation fixes (from DWARF to abixml)

The series of fixes to make

 "abidw foo > foo.abi && abidiff foo foo.abi"
work continues.

On a binary submitted as part of bug 18904, I am still seeing type
degradation.  This patch addresses the different cases of degradation
that are happening.

* include/abg-fwd.h (get_type_scope): Declare new function.
* src/abg-hash.cc (var_decl::hash::operator()): Do not cache the
hash because that can alter the hash computing of a larger type
which embeds a var decl as a member declaration.  This is
especially true if the var decl indirectly references the larger
type.  The only way to cache the value of a var decl would be to
wait after all canonical types have been computed.  We'd then seal
all types.  After that sealing happens, we can cache var decls
starting from the top-level ones.
(function_decl::hash::operator()): Likewise.
* src/abg-ir.cc (get_type_scope): Define new functions.
* src/abg-reader.cc (read_is_declaration_only): Declare this
function earlier.
(typedef const_types_map_it): Adjust this to make it point to a
map of string and vector of types, as opposed to a map to string
and type as it was before.
(typedef types_map_it): New typedef.
(read_context::map_id_and_node): Map a type id to the last
xmlNodePtr that represent a *declaration*.  That gives more leeway
to the declaration resolution code to choose the right definition
later.  Otherwise, there are cases where the wrong definition.  By
wrong definition, I mean a definition that is different from the
one chosen by the DWARF reading code, for a given declaration.
Basically for a given ABI corpus, a type declaration resolve to
the first definition seen in the corpus.
(read_context::get_all_type_decls): Define new member function.
(read_context::types_equal): Use qualified names only if both
types have a scope.
(read_context::key_type_decl): Now a given ID is associated to
*all* the declarations and definition that have that ID.
(read_translation_unit_from_input): Make sure the current corpus
node points to the right node.
(build_class_decl): Resolve class declarations to the first
definition seen in the corpus.  Key a type decl before reading its
members as a reading a member can request the current decl.  No
need to try and canonicalize a member type, as build_class_decl()
does that already.
* tests/data/test-read-dwarf/test16-pr18904.so: New test binary
input.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: New test
output reference.
* tests/test-read-dwarf.cc: Run the test above.
* tests/data/Makefile.am: Add the new test input to source
distribution.
* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
* 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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 18892 - type degradation from DWARF to abixml on libtsan.so
Dodji Seketeli [Sun, 30 Aug 2015 15:56:19 +0000 (17:56 +0200)]
Bug 18892 - type degradation from DWARF to abixml on libtsan.so

abidiff-ing libtsan.so again the output of abidw libtsan.so does not
yield the empty set.  This is because some types, especially an enum (in
certain cases) when read (de-serialized) from DWARF doesn't hash the
same as when de-serialized from abixml.

This is because an enum type can have a linkage name, referred to by
the DW_AT_linkage_name DWARF attribute.  This linkage_name was being
read from DWARF but wasn't serialized to abixml.  At de-serialization
time, well, the linkage_name information was lost.  Oops.

Also, I have seen that in some case we can canonicalize enum types too
early, when we de-serialize them from abixml, before we are done
building them.

This patch addresses these issues.

* src/abg-reader.cc (read_context::maybe_canonicalize_type): Late
canonicalize enum types.
(build_enum_type_decl): Read the linkage name of the enum type.
* src/abg-writer.cc (write_enum_type_decl): Emit the linkage name
of the enum type.
* tests/data/test-read-dwarf/test15-pr18892.so: New binary test
input.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: New test
output reference.
* tests/data/Makefile.am: Add the new test inputs above to source
distribution.
* tests/test-read-dwarf.cc (in_out_specs): Run the two tests above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 18893 - type degradation from dwarf to abixml on libGLU.so
Dodji Seketeli [Sun, 30 Aug 2015 14:19:50 +0000 (16:19 +0200)]
Bug 18893 - type degradation from dwarf to abixml on libGLU.so

abidiff-ing libGLU.so against the result of 'abidw libGLU.so' does not
yield the empty set.  This is because hashing certain types when they
are read (de-serialized) from DWARF doesn't give the same result as
when they are de-serialized from abixml.  I call this type
degradation.  And it leads to spurious comparison differences.

This is due to several issues.

  1/ The logical link between a class declaration and its definition
  -- that is built when reading types from DWARF is not preserved in
  abixml.  So, for example, when a class S refers to itself via a
  pointer to its declaration, that type might hash differently when
  read from DWARF and when read from abixml.  When read from abixml
  it's a pointer to S itself.  But then that 'self' can be a copy of S
  that is defined in another file because abixml doesn't enforce the
  One Definition Rule from C++ either.

  2/ As the result of hashing is kept in a cache for var_decl and
  function_decl, hashing those decl before their types are completely
  built caches a value that becomes wrong when their type become
  completely built.

  3/ In DWARF, a class which has a virtual member function can still
  be considered as being declaration-only.  And its definition can
  come later in the DWARF info.  Our DWARF reader removes the
  "declaration-only" flag from a class as soon as it sees virtual
  member functions in that class; that makes us consider that class as
  a definition.  And then later when we read the real definition of
  the class we have two classes of the same name, with different
  layouts/size in the system.  This leads to spurious comparison
  differences too.

This patch addresses issues 1, 2 and 3.

* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Do not
consider that virtual member functions disqualify a class from
being declaration-only.
* src/abg-hash.cc (var_decl::hash::operator()): Do not cache the
result of hashing before we are done building the type of the
var_decl.
(function_decl::hash::operator()): Likewise, do not cache the
result of hashing before we are done building the type of the
function_decl.
* src/abg-reader.cc (build_class_decl): Build the link between a
class declaration and its definition.  If there are several
definitions of a class in the corpus, keep just one.
* src/abg-writer.cc (write_class_is_declaration_only): Emit the
link between a class declaration and its definition.
(write_class_decl): Emit a class declaration even if it has a
definition.  The definition is going to be emitted
separately.
* tests/data/test-read-dwarf/test14-pr18893.so: New binary test
input.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: New test
reference output.
* tests/data/Makefile.am: Add the new test input files to source
distribution.
* tests/test-read-dwarf.cc (in_out_specs): Run the new tests.
* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoUse common canonicalization oracle when reading class type from dwarf
Dodji Seketeli [Sun, 30 Aug 2015 13:41:55 +0000 (15:41 +0200)]
Use common canonicalization oracle when reading class type from dwarf

When building a class type from DWARF, we were locally trying to
figure out if we should early canonicalize the resulting class type or
not.  We should rather use the common code that knows how to decide
that.  And this is what this patch does.

* src/abg-dwarf-reader.cc (build_ir_node_from_die):
(maybe_canonicalize_type): Move the specific logic that was in
build_ir_node_from_die (for class types) here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoFix crash in file type guessing
Dodji Seketeli [Sun, 30 Aug 2015 15:10:43 +0000 (17:10 +0200)]
Fix crash in file type guessing

* src/abg-tools-utils.cc (string_ends_with): Handle the case where
the string suffix is longer than the string itself.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoBug 18894 - Fix representation of enumerators in abixml format
Dodji Seketeli [Sat, 29 Aug 2015 15:17:48 +0000 (17:17 +0200)]
Bug 18894 - Fix representation of enumerators in abixml format

It turns out that using a size_t to serialize an enumerator is not
enough to represent things like enum foo {value = -3}; We need to
represent it using ssize_t.

Also, the patch avoids early canonicalization (when reading DWARF) of
types that refer to themselves.  This was leading to type degradation
(serializing the type from IR to abixml and de-serializing it back to
IR leads to a different type).

* include/abg-ir.h (enum_type_decl::enumerator::get_value()):
Change the type of this from size_t to ssize_t.
* src/abg-ir.cc (enum_type_decl::enumerator::get_value): Do the
same on the definition side.
(non_canonicalized_subtype_detector::visit_begin): If a type
refers to itself, late canonicalize it to have a similar hashing
result as what the abixml reader does.
* src/abg-reader.cc (build_enum_type_decl): Use ssize_t to read
the value of enumerators.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: New test input.
* tests/data/Makefile.am: Add the new test inputs above to source
distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add new test inputs.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* 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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDetect vtable changes from member function changes
Dodji Seketeli [Sat, 29 Aug 2015 13:59:14 +0000 (15:59 +0200)]
Detect vtable changes from member function changes

This patch adds vtable changes detection based on the detection of
virtual member function changes.  That is, when a member function
changes, if that member function is virtual, then infer if the change
implies changes to the vtable of the containing class.

Before that patch, we were doing the vtable change detection when we
were comparing two classes; we were then comparing their virtual
member functions.  But as for a given class all its virtual member
functions are not necessarily emitted in the DWARF debug info (only
the virtual member functions that are used in a given translation unit
are emitted in that translation unit) it's not reliable to compare
virtual member functions as part of comparing a given class.  We thus
decided some patches ago to stop comparing virtual member functions
when we compare two classes.

So with this patch now, we still detect changes to the vtable and emit
an appropriate message to the user.

* include/abg-ir.h (class_decl::{has_virtual_base, has_vtable}):
Declare new member functions.
* src/abg-comp-filter.cc (has_virtual_mem_fn_change): New overload
for function_decl_diff.
(has_virtual_mem_fn_change): In the overload for diff*, support
virtual member function changes detection for function_decl_diff*.
* src/abg-comparison.cc (function_decl_diff::report): Detect and
report changes to a vtable by looking a changes that can happen to
a given member function.
(corpus_diff::report): Detect and report changes to vtables by
looking at changes change to member functions.
* tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt:
New text input.
* tests/data/test-diff-dwarf/test29-vtable-changes-v{0,1}.cc: Source
code of new test input binaries.
* tests/data/test-diff-dwarf/test29-vtable-changes-v{0,1}.o: New
test input binaries.
* tests/data/test-diff-dwarf/test30-vtable-changes-report-0.txt:
New text input.
* tests/data/test-diff-dwarf/test30-vtable-changes-v{0,1}.cc: New
test input.
* tests/data/test-diff-dwarf/test30-vtable-changes-v{0,1}.o: New
test input binaries.
* tests/data/test-diff-dwarf/test31-vtable-changes-report-0.txt:
New test input.
* tests/data/test-diff-dwarf/test31-vtable-changes-v{0,1}.cc:
Source code of new test input binary.
* tests/data/test-diff-dwarf/test31-vtable-changes-v{0,1}.o: New
test input binary.
* tests/data/Makefile.am: Add the new test input files above to
source distribution.
* tests/test-diff-dwarf.cc (in_out_specs): Consume the new test
inputs above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoDo not hash or compare virtual member functions as par of classes
Dodji Seketeli [Sat, 29 Aug 2015 11:38:06 +0000 (13:38 +0200)]
Do not hash or compare virtual member functions as par of classes

When comparing two classes, do not compare their virtual member
functions anymore, because DWARF might not represent all the virtual
member functions of a class, in a given translation unit.

We still detect changes to virtual member functions (adding or
removing) because the index of a given member function in a vtable is
a property of the member function itself.  So if a vtable index
changes on a function, we detect it as part of comparing the exported
member functions themselves.  Likewise, if a member function is added
or removed, we detect it; and so if it's a virtual member function
then we detect it too.  In a subsequent patch, we'll add a dedicated
section to the report emitted by abidiff for changes to the vtable of
classes, I guess.

For now, this patch fixes some crashes we were having due to
discrepancies in hash values of classes, due to the fact that not all
of their virtual member functions were present in the debug info,
depending on the translation unit of the classes in question.

* src/abg-ir.cc (equals): When comparing two classes, do not
compare their virtual member functions.
* src/abg-hash.cc (class_decl::hash::operator()): Do not hash
virtual member functions when hashing a class.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMisc style fixes
Dodji Seketeli [Sat, 29 Aug 2015 11:23:17 +0000 (13:23 +0200)]
Misc style fixes

* src/abg-ir.cc (qualified_type_def::get_qualified_name): Fix
typos in comments.
(class_decl::member_class_template::operator==): Add comments.
(operator==): Add comment for the overload of
class_decl::member_class_template_sptr.
(function_tdecl::operator==): Add comments.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoAdjust many reference output for the non-regression test suite
Dodji Seketeli [Sat, 29 Aug 2015 11:20:29 +0000 (13:20 +0200)]
Adjust many reference output for the non-regression test suite

So the last series of patches have changed the test output a lot.
This patch adjusts the reference output to have "make check" work
again.  There is still one test that fails:
./build/tests/runtestreaddwarf.  It'll be addressed in subsequent
patches from now.

* tests/data/test-abidiff/test-enum0-report.txt: Adjust.
* tests/data/test-abidiff/test-enum1-report.txt: Adjust.
* tests/data/test-abidiff/test-qual-type0-report.txt: Adjust.
* tests/data/test-abidiff/test-struct0-report.txt: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-write/test17.xml: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
9 years agoMake test-read-dwarf.cc and test-read-write.cc abidiff the ABIs
Dodji Seketeli [Sat, 29 Aug 2015 11:10:25 +0000 (13:10 +0200)]
Make test-read-dwarf.cc and test-read-write.cc abidiff the ABIs

use abidiff to compare the ABI of the input ABI against the result of
writing that input back into an XML format.  It should yield the empty
set.  I wonder why I haven't done this since the beginning.  It turned
out we had to fix many things to make it work now.  Just using "GNU
diff" to compare the output against a reference output is definitely
not enough.

* tests/test-read-dwarf.cc (main): Use abidiff to compare the
input elf file with the XML emitted.  That should yield the empty
set.
* tests/test-read-write.cc (main): Likewise, use abidiff to
compare the input abixml file with the one that is emitted.

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