Commit Graph

1558 Commits

Author SHA1 Message Date
Dodji Seketeli
9135d990f5 [abixml writer] Store pointers to emitted types rather than type-ids
To record the emitted types, the abixml writer records the emitted
type *ID*s.  So to lookup an emitted type, it needs to lookup the ID
of the type first, and then lookup that type-id in the set of emitted
type IDs.  We are doing twice as much work as we should and profiling
the writting of a big abixml showed that it's quite taxing.

This patch makes the write records the set of emitted types directly.
No need to go through the emitted type *ID*s anymore.  So we save one
map lookup.  This incurs a 16% speedup when writting an abixml file
for a big (3GB) vmlinux file.

	* src/abg-writer.cc (type_ptr_set_type): Declare new typedef.
	(writer_context::m_emitted_type_id_map): Remove this data member.
	(writer_context::m_emitted_type_set): Add a new data member.
	(writer_context::{record_type_id_as_emitted, type_id_is_emitted,
	clear_emitted_types_map}): Remove these member functions.
	(writer_context::{record_type_as_emitted, type_is_emitted}): Use
	the new m_emitted_type_set data member above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-10-02 14:06:19 +02:00
Dodji Seketeli
91680cc597 Use an unordered map for canonical DIE offsets
Until now, the canonical DIE offsets map (the map that associates a
canonical DIE offset to a given DIE offset) was implemented in the
DWARF reader by using vectors.  This proves to use a lot of memory
(more than 25GB!!) for huge vmlinux binaries.  So much that the thing
was too slow (hey, yeah, because it was swapping out!) on vmlinux
kernel binary of 3GB of size, just to abidw it out.

This patch changes that to use an unordered map for this.  It now uses
~ 4GB of peak RAM memory, so I can actually abidw the vmlinux of 3GB
of size on my laptop.  It's still taking 16 minutes (!!) to complete,
but at least it's progress, as it's completed at least, without
swapping out.

And it doesn't see to noticeably slowdown the test suite.

	* src/abg-dwarf-reader.cc
	(read_context::canonical_type_die_offsets_): Renamed the
	canonical_type_die_vecs_ data member into this.
	(read_context::canonical_decl_die_offsets_): Renamed the
	canonical_decl_die_vecs_ data member into this.
	(read_context::{initialize, compute_canonical_die_offset,
	compute_canonical_die, get_canonical_die,
	get_or_compute_canonical_die, set_canonical_die_offset,
	get_canonical_die_offset}): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-27 16:00:14 +02:00
Dodji Seketeli
8d0ce10305 Bug 22190 - crash in read_context::get_or_compute_canonical_die
When computing a canonical DIE while reading DWARF, we crash in
get_or_compute_canonical_die basically because we loop over a vector
using an iterator which gets invalidated during the walk because some
code in the loop can increase the size of the vector (by adding
elements at its end) during the loop.

This patch fixes the issue by looping over the vector without using an
iterator that can be invalidated.  The code now properly expects the
vector to grow during the walk.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-27 16:00:14 +02:00
Dodji Seketeli
b91b8a280d Remove redundant (useless) typedef declaration
* src/abg-dwarf-reader.cc (dwarf_offsets_type): There are two
	instances of this typedef declaration, remove one.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-27 16:00:14 +02:00
Dodji Seketeli
866535fbfd Renamed offset_offset_map type name into offset_offset_map_type
While looking into something else, I realized that for consistency,
the name of the offset_offset_map type should be
offset_offset_map_type.  So I just did the change.

	* src/abg-dwarf-reader.cc (offset_offset_map_type): Renamed
	offset_offset_map into this.
	(read_context::{primary_die_parent_map_,
	alternate_die_parent_map_, type_section_die_parent_map_}): Adjust
	the type of these data members.
	(read_context::{die_parent_map, type_section_die_parent_map}):
	Adjust the type of these member functions.
	(read_context::{build_die_parent_relations_under,
	get_parent_die}): Adjust for the type name in these functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-27 16:00:14 +02:00
Dodji Seketeli
0f24a446d0 Add missing newlines to kmidiff's usage strings
* tools/kmidiff.cc (display_usage): Add newlines after the lines
	for --vmlinux1 and --vmlinux2.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-27 16:00:14 +02:00
Dodji Seketeli
8edaadb5f6 22160 - Annotate state flag unitialized in abidw
This patch initializes the annotate state flag in abidw.  Oops.

	* tools/abidw.cc (options::options): Initialize the annotate data
	member.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-21 09:46:32 +02:00
Dodji Seketeli
f344f92b25 Don't crash on classes that differ in their virtual member fn count
When comparing classes that differ in their number of virtual member
functions, it can happen that we crash because we should have got out
earlier.

This patch fixes that.  That problem happens on the test provided in
PR libabigail/17948 -- which is too big to be included in the test
suite.

	* src/abg-ir.cc (equals): In the overload for class_decl, when we
	detect that the virtual member function counts are different, get
	out, even when we are being asked about the kind of the change.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-18 17:45:30 +02:00
Dodji Seketeli
445567c42f Avoid adding the same data member twice in the DWARF reader
When we face two equivalent highly recursive structs/classes, it can
happen that a given data member be added twice to the type.  When
comparing two versions of a binary in which the data member happens to
have been removed from the second version, we thus trigger an assert
because a given data member has been "removed twice".

This happens on the example provided in PR libabigail/17948 -- which
is too big to be added to the test suite.

This patch hopefully fixes the issue by looking harder at the data
structure to make sure that we don't add the same data member twice.

	* src/abg-dwarf-reader.cc (add_or_update_class_type): After a we
	try to create a data member type, look *again* if the data member
	wasn't added recursively by the creation of the data member type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-18 17:45:30 +02:00
Mark Wielaard
60a4743af4 Bug 22075 - data_member_diff_comp forgets data members names
This patch makes the data_member_diff_comp comparison functor consider
all the properties local to the data member: that is, its offset and
its name.

It used to only take the offset into account.

This makes sure that offset change reports have a stable ordering and
thus makes the runtestdiffpkg testcase succeeds on debian-i386.

	* src/abg-comparison.cc (data_member_diff_comp): Make the
	comparison take the qualified name of the data member into
	account.  Also, if the initial offset and qualified names of the
	data members of the diff nodes are equal, consider the offset and
	qualified names of the new data members.

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-18 17:14:35 +02:00
Dodji Seketeli
74105ff84b Bug 22122 - Fail to represent 'const array'
When computing canonical DIEs, the DWARF reader mistakenly represents
'array of const' and 'const array' the same.

This patch fixes that.

	* src/abg-dwarf-reader.cc (die_is_array_type): Define new static
	function.
	(die_is_pointer_or_reference_type): Also test that the DIE can be
	an array.
	* tests/data/test-read-dwarf/PR22122-libftdc.so: New binary test input.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: New reference output.
	* tests/data/Makefile.am: Add the two new test files above to
	source distribution.
	* tests/test-read-dwarf.cc (in_out_specs): Run this test harness
	over the new test input.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-11 18:07:02 +02:00
Dodji Seketeli
3e4c5cafe2 Finer detection of local changes of var_decl type
When the size of a var_decl changes, we want the 'equals' function for
var_decl to report that change as being a local one, not a subtype
one.

This patch fixes that.

	* src/abg-ir.cc (equals): In the var_decl overload detect size
	changes of type as being a local change.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-08 10:17:48 +02:00
Dodji Seketeli
2bbfc662d2 Misc style fixes
* include/abg-fwd.h (get_pretty_representation): Add missing white
	space.
	* src/abg-ir.cc (get_name): Fix typo in comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-09-08 10:15:09 +02:00
Mark Wielaard
b74fa3437c readdir_r() is deprecated, use readdir().
Since glibc 2.24 readdir_r() is deprecated.
Applications are recommended to use readdir which is thread-safe when
using different directory streams (we explicitly create a new one here).

	* src/abg-tools-utils.cc (dir_is_empty): Use readdir() instead
	of readdir_r().

Signed-off-by: Mark Wielaard <mark@klomp.org>
2017-09-04 10:00:01 +02:00
Mark Wielaard
b920ae1c53 Declare eval_last_constant_dwarf_sub_expr with [u]int64_t not [s]size_t.
On 32bit platforms [s]size_t isn't the same as [u]int64_t causing:

abg-dwarf-reader.cc:358:1: warning: ‘bool abigail::dwarf_reader::eval_last_constant_dwarf_sub_expr(Dwarf_Op*, size_t, ssize_t&, bool&)’ declared ‘static’ but never defined [-Wunused-function]

	* src/abg-dwarf-reader.cc (eval_last_constant_dwarf_sub_expr):
	Declare expr_len as uint64_t and value as int64_t.

Signed-off-by: Mark Wielaard <mark@klomp.org>
2017-09-04 09:49:01 +02:00
Dodji Seketeli
f42817a78a Bug 22015 - Failing to return global scope of a DIE in certain cases
During DWARF reading, it can happen that we want to get the global
scope of a DIE which translation unit hasn't yet been constructed.

In that case, use the global scope of the current translation unit.

	* src/abg-dwarf-reader.cc (get_scope_for_die): If the translation
	unit of the parent die hasn't yet been constructed, then return
	the global scope of the current translation unit.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so: New
	binary test input.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	New reference test output.
	* tests/data/Makefile.am: Add the new test materials above to
	source distribution.
	* tests/test-read-dwarf.cc (in_out_specs): Add the new test input
	to the test suite.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-08-28 12:13:32 +02:00
Dodji Seketeli
bd863916ab Fix some make distcheck failures
Apparently we forgot to add some test input files to the source
distribution.

Fixed thus.

	* tests/data/Makefile.am: Add
	test-diff-dwarf/test42-PR21296-libgcc.so,
	test-diff-dwarf/test42-PR21296-libclang.so,
	test-diff-dwarf/test42-PR21296-clanggcc-report0.txt to the source
	distribution.  Also look for test-diff-filter/test39* tests inputs
	in the test-diff-filter/test39/ directory.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-17 17:12:53 +02:00
Dodji Seketeli
a742becf00 Avoid crashing when the elf file could not be read
When for a reason the ELF file could not be read and yet the user
keeps going with the elf reader context, it can happen that we crash.
This patch fixes that.

	* src/abg-dwarf-reader.cc
	(read_context::elf_architecture_is_ppc64): Do not crash if the elf
	handle is nil.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-17 17:12:45 +02:00
Dodji Seketeli
a1b6a3d351 Bug 21730 - Make abipkgdiff compare Linux Kernel packages as expected
This is the initial patch that makes abipkgdiff recognize Linux kernel
packages passed in argument and do the right thing.

abipkgdiff gets the vmlinux binary from the debug info package,
considers the union of that vmlinux binary and the thousands of kernel
modules that we shall name "the Kernel".  It then compares ABI
(actually Kernel/Module Interface, a.k.a KMI) of the Kernel of the
first package against the KMI of the Kernel of the second package.

	* include/abg-tools-utils.h (get_vmlinux_path_from_kernel_dist):
	Declare new function.
	(get_binary_paths_from_kernel_dist): Re-organize order of
	parameters.
	(file_is_kernel_package, file_is_kernel_debuginfo_package): Make
	the file_path parameter be const.
	(build_corpus_group_from_kernel_dist_under): Take an additional
	debug_info_root parameter.
	* src/abg-tools-utils.cc (file_is_kernel_package)
	(file_is_kernel_debuginfo_package): Const-ify the file_name
	parameter.
	(find_vmlinux_path): Define new static function.
	(get_binary_paths_from_kernel_dist): Re-organize the order of
	parameters.  The debug_info_root_path parameter is now an input
	parameter.
	(get_vmlinux_path_from_kernel_dist): Define new function.
	(get_binary_paths_from_kernel_dist): Adjust invocation of
	get_binary_paths_from_kernel_dist.
	(build_corpus_group_from_kernel_dist_under): Take an additional
	debug_info_root parameter.
	* tools/abidw.cc (load_kernel_corpus_group_and_write_abixml):
	Adjust invocation to build_corpus_group_from_kernel_dist_under.
	* tools/abipkgdiff.cc (create_maps_of_package_content):  Don't map
	the content of a Linux Kernel package.
	(compare_prepared_userspace_packages)
	(compare_prepared_linux_kernel_packages, compare_prepared): Define
	new functions.
	(compare): Use the new functions above here.
	* tools/kmidiff.cc (print_kernel_dist_binary_paths_under): Adjust
	the invocation of get_binary_paths_from_kernel_dist.
	(main): Adjust the invocation of
	build_corpus_group_from_kernel_dist_under.  Make sure that a
	kernel package is accompanied by a debug info package.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-17 16:41:07 +02:00
Dodji Seketeli
63acb64bcf Support up to two --wp options for abipkgdiff
The user should be able to specify one white list package per kernel
package on the command line.  That means the user should be able to
say:

    --wp whitelist-pkg1 --wp whitelist-pkg2

on the command line.

This patch adds support for that.

	* doc/manuals/abipkgdiff.rst: Update the documentation to say that
	--wp can be provided twice, but not more than that.
	* tools/abipkgdiff.cc (options::kabi_whitelist_packages): Rename
	kabi_whitelist_package to this, and make be of vector<string>
	type.
	(package::erase_extraction_directories): Erase the white list
	package extracted data.
	(maybe_handle_kabi_whitelist_pkg, parse_command_line): Adjust.
	(main): Make sure there is no more than 2 --wp on the command
	line.  Associate a white list package to each kernel package on
	the command line.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-12 10:40:15 +02:00
Dodji Seketeli
514a617621 Fix support of the --wp option of abipkgdiff
The package passed to the --wp option was not found because we were
not considering the absolute path of that package.  Fixed thus.

	* tools/abipkgdiff.cc (parse_command_line): Consider the absolute
	path of the package given in argument to --wp.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-11 17:14:18 +02:00
Dodji Seketeli
e84e0d218a Use shorter lines in abipkgdiff.cc
* tools/abipkgdiff.cc (parse_command_line): Use shorter lines
	here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-11 17:14:18 +02:00
Dodji Seketeli
8a7e966b66 Add missing space in abipkgdiff error message
* tools/abipkgdiff.cc (extract_package): Add missing space here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-11 17:14:18 +02:00
Dodji Seketeli
6cf8f0b21f Replace --lkaw with -w and --lkaw-pkg with --wp
Make these short options be shorter.

	* doc/manuals/abipkgdiff.rst: Adjust the documentation.
	* tools/abipkgdiff.cc (display_usage): Adjust the usage string.
	(parse_command_line): Parse -w instead of --lkaw and --wp
	insteadof --lkaw-pkg.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-11 17:14:18 +02:00
Dodji Seketeli
893a171d71 speed up class type lookup in a corpus
When a class type lookup fails in a the type map of a corpus, the code
goes look the class up in the type maps of a every single translation
unit.

This design dates back from the time where there could be only one
type of a given name present in in the type map of a corpus.  When
several types with the same were found, then each type would be
present in the type map of its translation unit, but then no type with
that name would be present in the type map of the corpus.

As a result, when a type was not found in the type map of the corpus,
we were looking for it in the type maps of the translation units.

Now that the type map of the corpus can carry several types with the
same name, we don't need to look in the translation unit anymore.

This patch implements that adjustment.

	* src/abg-ir.cc (lookup_class_type): In the overload that looks
	for a class name denoted by an interned_string in the corpus, do
	not look for the class in the translation units when the type
	wasn't found in the type map of the corpus.
	(maybe_update_types_lookup_map): Remove the
	erase_if_exists_already parameter and the code that uses it.
	(lookup_class_type_through_translation_units): Remove this
	function that is now useless.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-11 12:29:38 +02:00
Dodji Seketeli
4f87248d05 Bug 21644 - abipkgdiff does not emit diagnostics about comparison errors
When abipkgdiff compares binaries of a package, it doesn't report
errors like debug info or symbol not found.

This patch fixes that.

	* include/abg-dwarf-reader.h (status_to_diagnostic_string):
	Declare new function.
	* src/abg-dwarf-reader.cc (status_to_diagnostic_string): Define
	new function.
	* tools/abipkgdiff.cc (compare): Take a new detailed_error_status
	parameter.
	(compare_task::perform): Get the details of the error, in case the
	status of the comparison is ABIDIFF_ERROR.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-06 15:20:47 +02:00
Dodji Seketeli
2e2c5ff1cb Bug 21153 - abipkgdiff reports undetermined interface subtype changes
When a type has a noop qualifier and that noop qualifier disapears in
a subsequent version of that type, the two versions of the type have
different internal pretty representations.  And that leads to the type
canonicalization code ending up with two different canonical types for
the two versions, even if they should be considered equivalent.

This patch makes a noop-qualified type have the same internal pretty
representation as its non-qualified variant.

	* src/abg-ir.cc (get_name_of_qualified_type): A noop-qualified
	type has an empty string as reprsentation for its qualifier.
	* src/abg-dwarf-reader.cc (die_qualified_type_name): Adjust to
	comply with what is done in get_name_of_qualified_type.  Adjust
	comment too.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
	* tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt:
	New reference test output.
	* tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64.rpm: New
	test binary input.
	* tests/data/test-diff-pkg/libcdio-0.94-2.fc26.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/libcdio-debuginfo-0.94-1.fc26.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/libcdio-debuginfo-0.94-2.fc26.x86_64.rpm Likewise.
	* tests/data/Makefile.am: Add the new test inputs to source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Make this test harness run on
	the new test inputs above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-05 18:04:28 +02:00
Dodji Seketeli
ac1fb9f58c Fix typo in comments
* src/abg-ir.cc (type_base::get_canonical_type_for): Fix a typo in
	a command.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:47:44 +02:00
Dodji Seketeli
c47fa9c2ce Fix a typo when reporting size change wrt a decl-only class
When a class is compared to its decl-only counterpart, if the user
doesn't want to see decl-only class related change, then do not report
any size change that might result from it.

This was already meant to be implemented but there was a typo.  Fixed
thus.

	* src/abg-comparison.cc (report_size_and_alignment_changes): Fix
	typo.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:47:43 +02:00
Dodji Seketeli
6f7d84e508 Better handle decl-only classes being different from their definition
Sincea little while, libabigail can now handle the presence of several
different class types definition that have the same name.

To handle that, we settled that for types originating from C, a
decl-only class would be considered different from a definition of
that class.  Especially during type canonicalization.

Now it seems that it's wrong to consider this only for C types.  That
is because the same class type foo, defined in a C header, can be
compile either into a C++ compilation unit, or a C one, in the same
binary.  That is, in the same binary, a struct type foo can be seen
defined in a C compilation unit *and* in a C++ compilation unit.

So rigth now, the C++ struct type foo would compare equal to a
decl-only struct foo, but the C struct type foo would compare
different to a decl-only struct foo.  This leads to spurious change
reports, especiall in the nmap and mariadb package from Fedora 25,
when we run selfcheck.py on fc25 critpath packages.

This patch makes libabigail always consider -- during type
canonicalization -- that a decl-only class is different from a
definition of that class.  Not only for C.

	* src/abg-comparison.cc (function_decl_diff::report): Don't report
	possible vtable changes between a decl-only class and its
	definition.
	* src/abg-ir.cc (type_base::get_canonical_type_for): Consider that
	a decl-only class is different from its definition when comparing
	types for the purpose of type canonicalization.
	(equals): In the class_or_union overload, only consider the global
	decl_only_class_equals_definition() property to know when to
	consider that a decl-only class is different from its definition
	when comparing two classes.
	* src/abg-reader.cc (build_class_decl): Read the size property of
	a class, even if it's a decl-only class.
	* src/abg-writer.cc (write_class_decl_opening_tag): Write size
	property of types even if the types are decl-only classes.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-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/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:47:43 +02:00
Dodji Seketeli
91e3240231 Don't add empty translation unit to corpus
In debug info, some translation units are known to be empty because
they don't carry any DIE.  It's thus useless to add those translation
units to the ABI corpus.

Note that in some packages like gcc and glibc (in Fedora 25) the same
empty translation unit can be present in the debug info more than
once.  This violates a Libabigail invariant that asserts that a given
translation unit (designated by its path) shall be present only once
in the debug info.

	* src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir):
	A translation unit DIE that has no child DIE shall not be added to
	the current ABI corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:47:38 +02:00
Dodji Seketeli
122b95daff Bug 21631 - Forgot a "break" statement in stv_to_elf_symbol_visibility
This seems to be a typo where I forgot to add a "break" statement in
the stv_to_elf_symbol_visibility function.  Oops.

This patch fixes that.

	* src/abg-dwarf-reader.cc (stv_to_elf_symbol_visibility): Add a
	missing break statement.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:45:31 +02:00
Dodji Seketeli
9c7585c700 Bug 21630 - A this pointer DIE can be const
From what I have usually seen emitted by GCC, a "this pointer" is
represented by a DW_TAG_pointer_type.  If the "this pointer" is for a
const method, then it points to a const class type DIE.

But in, in this problem report, I am seeing a "this pointer"
represented by a DW_TAG_const_type that points to a
DW_TAG_pointer_type, which is itself points to a class type DIE.

The code of die_this_pointer_is_const needs to be adjusted so that it
doesn't expect only a DW_TAG_pointer_type.

This is what this patch does.

	* src/abg-dwarf-reader.cc (die_this_pointer_is_const): If the DIE
	is not a DW_TAG_pointer_type then don't crash.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:45:31 +02:00
Dodji Seketeli
98139caf68 Bug 21629 - equivalent DIEs must be of the same DIE source
A prerequisite to represent the relationship "DIE 'D' has canonical
DIE C", is that D and C come from the same DIE source.  A DIE source
being either the main debug info file, the alternate debug info file
(both having DIEs in their .debug_info section), or a .debug_type
section.

This prerequisite is a result of the design of the current
libabigail's DWARF reader.

Unfortunately the code that compares DIEs and that updates the
canonical DIEs of the compared DIEs (in case the two DIEs are
equivalent) sometimes fails to honour that prerequisite, causing other
troubles down the road.

This patch fixes that by ensuring that equivalent DIEs must be of the
same DIE source.

The patch doesn't embed a regression test as this problem was
discovered using the
https://pagure.io/libabigail-selfcheck/blob/master/f/selfcheck.py
testing framework

	* src/abg-dwarf-reader.cc (compare_dies): Don't propagate
	a canonical DIE to a DIE that comes from a different source.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:45:31 +02:00
Dodji Seketeli
90919fceeb Bug 21627 - Libabigail doesn't consider translation unit compile dir
The path of a translation unit is relative to the directory where that
translation unit was compiled.

So there can be several different translation units (in the same
binary) that have the same (relative) paths.  To tell them apart, one
needs to consider the compile directory of those translation units.

But then Libabigail ignores the compilation directory of translation
units.  It just considers their (relative) path.  That leads to
different translation units having the same path.

Furthermore, there can be a translation unit with full path (one that
takes into account the file name and its compile directory) named "P"
that contains function definitions f1 and f2, as described by the
debug info.  Further down the road, there can be *another* translation
unit which also has "P" as its full path, and that cotnains function
definitions f3 and f4.  A way to understand is to consider that the
translation unit of full path "P" contains f1, f2, f3 and f4.

This patch introduces the concept of the compile dir of a given
translation unit, and the concept of the absolute path of the
translation unit which would then be a concatenation of the compile
dir and relative paths of the translation unit.

The patch also tries to reuse a translation unit with a given path,
*if* that translation unit has already been seen in the current
binary, instead of creating a new one altogether.

This patch doesn't carry a regression test as the problem was found
while running the
https://pagure.io/libabigail-selfcheck/blob/master/f/selfcheck.py
script over the Fedora 25 critpath packages.

The patch does however update existing reference outputs of existings
tests where appropriate.

	* include/abg-ir.h (translation_unit::{get_compilation_dir_path,
	set_compilation_dir_path, get_absolute_path}):
	* src/abg-corpus.cc (corpus::add): Use the new
	translation_unit::get_absolute_path() as the key for the tu path
	-> tu map.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes):  Use the new
	translation_unit::get_absolute_path().
	(build_translation_unit_and_add_to_ir): Set the compilation
	directory of the translation unit.
	* src/abg-ir-priv.h (translation_unit::priv::{comp_dir_path_,
	abs_path_}):
	* src/abg-ir.cc (translation_unit::set_path): Update comment.
	(translation_unit::{get_compilation_dir_path,
	set_compilation_dir_path, get_absolute_path}): Define new member
	functions.
	* src/abg-reader.cc (read_translation_unit): Take the new
	'comp-dir-path' attribute into account.
	* src/abg-writer.cc (write_translation_unit): Emit the new
	'comp-dir-path' attribute.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-annotate/test0.abi: Adjust.
	* tests/data/test-annotate/test1.abi: Adjust.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-annotate/test2.so.abi: Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-annotate/test3.so.abi: Adjust.
	* tests/data/test-annotate/test4.so.abi: Adjust.
	* tests/data/test-annotate/test5.o.abi: Adjust.
	* tests/data/test-annotate/test6.so.abi: Adjust.
	* tests/data/test-annotate/test7.so.abi: Adjust.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test0.abi: Adjust.
	* tests/data/test-read-dwarf/test1.abi: 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/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/test2.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/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test3.so.abi: Adjust.
	* tests/data/test-read-dwarf/test4.so.abi: Adjust.
	* tests/data/test-read-dwarf/test5.o.abi: Adjust.
	* tests/data/test-read-dwarf/test6.so.abi: Adjust.
	* tests/data/test-read-dwarf/test7.so.abi: Adjust.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:35:35 +02:00
Dodji Seketeli
229bdba7e4 Misc style fixes
* src/abg-dwarf-reader.cc (read_context::{die_wip_classes_map,
	die_wip_function_types_map, types_to_canonicalize,
	tu_die_imported_unit_points_map, die_parent_map,
	load_kernel_symbol_table}): Add missing space to statement.
	(get_parent_die): Likewise.
	(build_enum_type): Fix typo in comment.
	(e_machine_to_string, get_version_definition_for_versym)
	(lookup_public_function_symbol_from_elf)
	(lookup_public_variable_symbol_from_elf)
	(lookup_data_tag_from_dynamic_segment, die_is_declaration_only)
	(die_is_reference_type, die_function_type_is_method_type): Fix
	indentation.
	(read_context::{resolve_declaration_only_classes,
	fixup_functions_with_no_symbols,
	load_symbol_maps_from_symtab_section, load_dt_soname_and_needed,
	load_elf_architecture, load_elf_properties,
	maybe_adjust_address_for_exec_or_dyn, maybe_adjust_fn_sym_address,
	address_is_in_opd_section, load_elf_architecture,
	build_die_parent_maps}): Likewise.
	(op_pushes_constant_value, op_manipulates_stack): Use the
	dwarf_expr_eval_context::push method.
	(op_is_control_flow, die_return_and_parm_names_from_fn_type_die)
	(die_function_signature, die_pretty_print_type)
	(get_default_array_lower_bound)
	(build_translation_unit_and_add_to_ir, build_enum_type)
	(add_or_update_class_type, build_function_type)
	(build_function_decl, build_ir_node_from_die)
	(lookup_public_function_symbol_from_elf): Fix indentation.
	* src/abg-ir.cc (maybe_update_types_lookup_map): Remove useless space.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:49 +02:00
Dodji Seketeli
41496eae52 Fix doc glitch in abidiff.rst
* doc/manuals/abidiff.rst: Fix glitch.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:49 +02:00
Dodji Seketeli
bb0c1c322d Symbols with the same zero value are not aliases
When looking at ELF file of the ET_REL kind (i.e, relocatable object
files), several kinds of symbols (for instance weak symbols) can have
the symbol value zero.  Although they have the same value, the fact
that that value is zero prevents us from considering those symbols as
being aliases.

Libabigail was wrongly considering those symbols with value zero as
being aliases.  So, in practice, it was considering all WEAK symbols
as being aliases, because the value of a weak symbols is zero.

When comparing two binaries originating from the same source code, one
compiled with g++ and the other one compiled with clang++, abidiff was
thus reporting spurious function aliases changes due to this issue.

Note that the two binaries in question come from the bug PR21486.
Comparing them using abidiff exhibits several other issues that were
fixed in previous commits, such as

 - Reporting changes about top cv qualifier changes on function
 parameter types.
 - Not supporting ELF symbol visibility

	* src/abg-dwarf-reader.cc (load_symbol_maps_from_symtab_section):
	Do not consider symbols with zero value as being aliases.
	* tests/data/test-diff-filter/test20-inline-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test20-inline-report-1.txt:
	Likewise.
	* test-diff-filter/test41-PR21486-abg-writer.gcc.o: New test
	binary input.
	* tests/data/test-diff-filter/test41-PR21486-abg-writer.llvm.o:
	Likewise.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-filter.cc (in_out_specs): Run the test harness
	on the new test input above.
	* tests/data/test-diff-dwarf/test5-report.txt: Adjust.
	* tests/data/test-diff-filter/test9-report.txt: Adjust.
	* tests/data/test-diff-filter/test20-inline-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test20-inline-report-1.txt: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:49 +02:00
Dodji Seketeli
a7492fea56 Support ELF symbol visibility property
This patch models the ELF symbol visibility property and support
ignoring function and variable symbols that are HIDDEN and INTERNAL,
even if they have default binding.

	* include/abg-ir.h (enum elf_symbol::visibility): Define new enum.
	(elf_symbol::{elf_symbol, create}): Take a visibility parameter.
	(elf_symbol::{set, get}_visibility): Declare new accessors.
	(string_to_elf_symbol_binding): Declare new function.
	* src/abg-ir.cc (elf_symbol::priv::visibility_): New data member.
	(elf_symbol::priv::priv): Adjust.
	(elf_symbol::elf_symbol): Take a visibility parameter.
	(elf_symbol::create): Likewise
	(elf_symbol::{s,g}et_visibility): Define new accessors.
	(elf_symbol::is_public): Adjust.
	(operator<<(std::ostream&, elf_symbol::visibility)): Define new
	operator.
	(string_to_elf_symbol_visibility): Define new function.
	* src/abg-dwarf-reader.cc (stv_to_elf_symbol_visibility): Define
	new static function.
	(lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab)
	(create_default_var_sym, create_default_fn_sym): Adjust.
	* src/abg-reader.cc (read_elf_symbol_binding): Define new
	function.
	(build_elf_symbol): Adjust.
	* src/abg-writer.cc (write_elf_symbol_visibility): Define new
	function.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-annotate/test0.abi: Adjust.
	* tests/data/test-annotate/test1.abi: Adjust.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-annotate/test2.so.abi: Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-annotate/test3.so.abi: Adjust.
	* tests/data/test-annotate/test4.so.abi: Adjust.
	* tests/data/test-annotate/test5.o.abi: Adjust.
	* tests/data/test-annotate/test6.so.abi: Adjust.
	* tests/data/test-annotate/test7.so.abi: Adjust.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test0.abi: Adjust.
	* tests/data/test-read-dwarf/test1.abi: 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/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/test2.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/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test3.so.abi: Adjust.
	* tests/data/test-read-dwarf/test4.so.abi: Adjust.
	* tests/data/test-read-dwarf/test5.o.abi: Adjust.
	* tests/data/test-read-dwarf/test6.so.abi: Adjust.
	* tests/data/test-read-dwarf/test7.so.abi: Adjust.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
	* tests/data/test-read-write/test26.xml: Adjust.
	* tests/data/test-read-write/test27.xml: Adjust.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Adjust.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:47 +02:00
Dodji Seketeli
c0bfc403dc Filter top cv qualifier changes on function parameter types
When the type of a function parameter sees its top CV qualifier
change, that should never negatively affect ABI compliance.

So this patch filters out top cv qualifier changes on function
parameter types, by default.

	* include/abg-comparison.h (enum diff_category): Add a new
	FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY enumerator.  "Or" the
	enumerator to the EVERYTHING_CATEGORY enumerator.
	* src/abg-comp-filter.cc (has_fn_parm_type_cv_qual_change): Define
	new static function.
	(categorize_harmless_diff_node): Categorize changes to top cv
	qualifiers on function parameter types into the new
	FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY.
	* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
	Add the new FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY category to the
	set of harmless categories.
	(operator<<(ostream&, diff_category)): Adjust to serialize
	the new FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY.
	* tests/data/test-diff-filter/libtest40-v0.so: New test input binary.
	* tests/data/test-diff-filter/libtest40-v1.so: Likewise.
	* tests/data/test-diff-filter/test40-report-0.txt: New test
	reference output.
	* tests/data/test-diff-filter/test40-v0.cc: Source code of the
	test binary above.
	* tests/data/test-diff-filter/test40-v1.cc: Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-filter.cc (in_out_specs): Add new binaries to
	compare.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:47 +02:00
Dodji Seketeli
698f405740 Do not report about voffset when it's not set in debug info
Sometimes some virtual member functions don't have any virtual offset
set in the debug info.  This happens for virtual destructors
sometimes.  In that case, the ABI change report should not refer to
that unset virtual offset as being '0'.  Rather, it shouldn't refer to
it at all.

This is what this patch does.

	* include/abg-ir.h (mem_fn_context_rel::mem_fn_context_rel):
	Initialize the virtual offset to -1.
	* src/abg-comparison.cc (represent): In the overload to represent
	a method_decl, do not represent the vofffset if it's not set.
	* src/abg-writer.cc (write_voffset): The virtual offset is signed
	because if it's -1, it means no offset is set.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Adjust.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.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/test14-pr18893.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/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:47 +02:00
Dodji Seketeli
6eb2b268f8 Allow selective resolution of class declaration
When a class is forward-declared, resolving it to a definition that
appears later in the same translation unit or in another translation
is an interesting problem.

Until now, the declaration would be resolved to the definition of that
class found in the binary.  The problem is that there can be different
such definitions, especially in C where there is no "One Definition
Rule".  In that case, the definition chosen is random.

This patch resolves that randomness.

For a given class declaration, if there is just one possible
definition in the binary, then the declaration is resolved to that
definition.  If there is one definition for that declaration in the
same translation unit, then the declaration is resolved to that
definition.  If there are more than one definitions in translation
units that are not the one of the declaration, then the declaration is
left unresolved.  This is what I call "selective class declaration resolution".

Note that an unresolved class declaration now compares different to a
definition of a class of the same name.  This is so that we can have
an unresolved class be present in the resulting .abi file, alongside
an (incompatible) definition of the same class.  The change from a class
declaration to its definition is filtered out by default, though.

	* include/abg-fwd.h (type_base_wptrs_type)
	(istring_type_base_wptrs_map_type): Define new typedefs.
	(lookup_class_types): Declare new functions.
	* include/abg-ir.h
	(environment::decl_only_class_equals_definition): Declare new
	accessor.
	(type_maps::{*_types}): Make these accessors return
	istring_type_base_wptrs_map_type& instead of
	istring_type_base_wptr_map_type&.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes): Implement the
	new selective declaration resolution scheme.
	* src/abg-ir.cc (type_maps::priv::{*_types_}): Change the type of
	these data members from istring_type_base_wptr_map_type to
	istring_type_base_wptrs_map_type.
	(type_maps::{*_types}): Make these accessors definitions return
	istring_type_base_wptrs_map_type& instead of
	istring_type_base_wptr_map_type&.
	(translation_unit::bind_function_type_life_time): Adjust.
	(environment::priv::decl_only_class_equals_definition_): New data
	member.
	(environment::priv::priv): Initialize it.  By default, a decl-only
	class is now considered different from its definition.
	(environment::decl_only_class_equals_definition): Define new
	accessor.
	(lookup_types_in_map, lookup_class_types): Define new functions.
	(lookup_type_in_map, lookup_union_type_per_location)
	(lookup_basic_type, lookup_basic_type_per_location)
	(lookup_class_type, lookup_class_type_per_location)
	(lookup_union_type, lookup_enum_type)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, lookup_qualified_type)
	(lookup_pointer_type, lookup_reference_type, lookup_array_type)
	(lookup_function_type, maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Adjust.
	(type_base::get_canonical_type_for): When doing type comparison
	here, we can now consider that an unresolved class declaration
	compares different to an incompatible class definition of the same
	name.  So no need to look through decl-only classes in that case.
	(equals): In the overload for class_or_union, if
	environment::decl_only_class_equals_definition() is false, then an
	unresolved class declaration of name "N" compares different to a
	class definition named "N".
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Adjust.
	* tests/data/test-diff-filter/test38/Makefile: New test material.
	* tests/data/test-diff-filter/test38/test38-a.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-b.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-c.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test38/test38-v0: Likewise.
	* tests/data/test-diff-filter/test38/test38-v1: Likewise.
	* tests/data/test-diff-filter/test38/test38.h: Likewise.
	* tests/data/test-diff-filter/test39/Makefile: Likewise.
	* tests/data/test-diff-filter/test39/test39-a-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-a-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-b-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-b-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-c-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-c-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-main.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test39/test39-v0: Likewise.
	* tests/data/test-diff-filter/test39/test39-v1: Likewise.
	* tests/data/test-diff-filter/test39/test39.h: Likewise.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-diff-filter.cc (in_out_specs): Add the new test
	inputs above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:46 +02:00
Dodji Seketeli
8bf7b7d26b Add documentation for the kmidiff tool
* doc/manuals/kmidiff.rst: New doc file.
	* doc/manuals/Makefile.am: Add the above file to source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:45 +02:00
Dodji Seketeli
077b977ce5 Allow re-using the ELF/DWARF read_context when loading a corpus group
Right now, when loading each corpus of a group, a new read_context is
created and destroyed.  That makes thousands of corpora that are
created and destroyed.  Profiling seems to argue that we'd gain in
performance by re-using the first read_context that was created
instead, and re-set it before loading a new corpus.

This is what this patch does.

	* include/abg-dwarf-reader.h (reset_read_context): Declare new
	function.
	* src/abg-dwarf-reader.cc (read_context::elf_paths_): Make this to
	be non const.
	(read_context::initialize): New function to initialize all data
	members.
	(read_context::read_context): Use the new read_context::initialize
	function, rather than initializing data members 'inline' here.
	(reset_read_context): Define a new function to reset a
	read_context so that it can be re-used to load a new corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:45 +02:00
Dodji Seketeli
b9a7e99dda Add --vmlinux{1,2} option to abidw and kmidiff
When using abidw to generate an abixml for a Linux Kernel build tree,
usually, people have to copy the vmlinux binary into the directory
where modules are, so that the tool can find it.  This --vmlinux
option helps to avoid doing that copy.

Simarly, when comparing two Linux Kernel build trees, --vmlinux1 and
--vmlinux2 are there to make the tool find the vmlinux binaries to
compare, independantly from the directories under which the modules
are to be found.

	* include/abg-tools-utils.h
	(build_corpus_group_from_kernel_dist_under): Add a new
	vmlinux_path parameter.
	* src/abg-tools-utils.cc (find_vmlinux_and_module_paths): Do not
	try to find a vmlinux binary if we already have the path to one.
	(build_corpus_group_from_kernel_dist_under): Add a new
	vmlinux_path parameter.
	* tools/abidw.cc (options::vmlinux): New data member.
	(display_usage): Add a usage string for --vmlinux
	(parse_command_line): Parse the new --vmlinux option.
	(load_kernel_corpus_group_and_write_abixml): Fix some return code
	when the function fails.  Verify the presence of the vmlinux
	binary that was given.  Adjust.
	* tools/kmidiff.cc (options::{vmlinux1, vmlinux2}): New data
	members.
	(display_usage): Add a usage string for --vmlinux1 and --vmlinux2.
	(parse_command_line):  Parse the --vmlinux1 and --vmlinux2
	options.
	(main): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:45 +02:00
Dodji Seketeli
0b2e8ae156 Cache function type name computation results
get_type_name can be called over and over again on function types.
This patch caches the result of the computation of function type names
in those cases.

This is a speed optimization.

	* src/abg-ir.cc (get_type_name): Cache function type names.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:45 +02:00
Dodji Seketeli
5119f66b02 Fix innacurate test condition when reading an enum type from abixml
* src/abg-reader.cc (build_enum_type_decl): Do not check for
	errno which might have been set earlier by something else.
	Rather, check the returned value for overflow or underflow.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:45 +02:00
Dodji Seketeli
5529a51a96 Do not report about voffset when it's not set in debug info
Sometimes some virtual member functions don't have any virtual offset
set in the debug info.  This happens for virtual destructors
sometimes.  In that case, the ABI change report should not refer to
that unset virtual offset as being '0'.  Rather, it shouldn't refer to
it at all.

This is what this patch does.

	* include/abg-ir.h (mem_fn_context_rel::mem_fn_context_rel):
	Initialize the virtual offset to -1.
	* src/abg-comparison.cc (represent): In the overload to represent
	a method_decl, do not represent the vofffset if it's not set.
	* src/abg-writer.cc (write_voffset): The virtual offset is signed
	because if it's -1, it means no offset is set.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Adjust.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.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/test14-pr18893.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/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:44 +02:00
Dodji Seketeli
4672ba4f4c Speedup DIE representation computing esp function signature in C
For DIE originating from C, we now compute canonical DIEs.  We then
use that to compare DIEs to see if they are equal or not.  So string
representation of DIEs are now used only to reduce the number of DIEs
comparisons that is performed during DIE canonicalization.

We can thus just use function names (rather than a full
die_function_signature) as a way to reduce the number of structural
comparisons of DIEs during canonicalization.

This patch does just that.

Note that in the future when we perform DIEs canonicalization and comparison for
C++, we can avoid computing full function DIE signatures for C++ too.

	* src/abg-dwarf-reader.cc (die_function_signature): For C DIEs,
	just return the (linkage) name of the function.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:43 +02:00
Dodji Seketeli
76d832115d Allow selective resolution of class declaration
When a class is forward-declared, resolving it to a definition that
appears later in the same translation unit or in another translation
is an interesting problem.

Until now, the declaration would be resolved to the definition of that
class found in the binary.  The problem is that there can be different
such definitions, especially in C where there is no "One Definition
Rule".  In that case, the definition chosen is random.

This patch resolves that randomness.

For a given class declaration, if there is just one possible
definition in the binary, then the declaration is resolved to that
definition.  If there is one definition for that declaration in the
same translation unit, then the declaration is resolved to that
definition.  If there are more than one definitions in translation
units that are not the one of the declaration, then the declaration is
left unresolved.  This is what I call "selective class declaration resolution".

Note that an unresolved class declaration now compares different to a
definition of a class of the same name.  This is so that we can have
an unresolved class be present in the resulting .abi file, alongside
an (incompatible) definition of the same class.  The change from a class
declaration to its definition is filtered out by default, though.

	* include/abg-fwd.h (type_base_wptrs_type)
	(istring_type_base_wptrs_map_type): Define new typedefs.
	(lookup_class_types): Declare new functions.
	* include/abg-ir.h
	(environment::decl_only_class_equals_definition): Declare new
	accessor.
	(type_maps::{*_types}): Make these accessors return
	istring_type_base_wptrs_map_type& instead of
	istring_type_base_wptr_map_type&.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes): Implement the
	new selective declaration resolution scheme.
	* src/abg-ir.cc (type_maps::priv::{*_types_}): Change the type of
	these data members from istring_type_base_wptr_map_type to
	istring_type_base_wptrs_map_type.
	(type_maps::{*_types}): Make these accessors definitions return
	istring_type_base_wptrs_map_type& instead of
	istring_type_base_wptr_map_type&.
	(translation_unit::bind_function_type_life_time): Adjust.
	(environment::priv::decl_only_class_equals_definition_): New data
	member.
	(environment::priv::priv): Initialize it.  By default, a decl-only
	class is now considered different from its definition.
	(environment::decl_only_class_equals_definition): Define new
	accessor.
	(lookup_types_in_map, lookup_class_types): Define new functions.
	(lookup_type_in_map, lookup_union_type_per_location)
	(lookup_basic_type, lookup_basic_type_per_location)
	(lookup_class_type, lookup_class_type_per_location)
	(lookup_union_type, lookup_enum_type)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, lookup_qualified_type)
	(lookup_pointer_type, lookup_reference_type, lookup_array_type)
	(lookup_function_type, maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Adjust.
	(type_base::get_canonical_type_for): When doing type comparison
	here, we can now consider that an unresolved class declaration
	compares different to an incompatible class definition of the same
	name.  So no need to look through decl-only classes in that case.
	(equals): In the overload for class_or_union, if
	environment::decl_only_class_equals_definition() is false, then an
	unresolved class declaration of name "N" compares different to a
	class definition named "N".
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Adjust.
	* tests/data/test-diff-filter/test38/Makefile: New test material.
	* tests/data/test-diff-filter/test38/test38-a.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-b.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-c.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test38/test38-v0: Likewise.
	* tests/data/test-diff-filter/test38/test38-v1: Likewise.
	* tests/data/test-diff-filter/test38/test38.h: Likewise.
	* tests/data/test-diff-filter/test39/Makefile: Likewise.
	* tests/data/test-diff-filter/test39/test39-a-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-a-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-b-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-b-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-c-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-c-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-main.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test39/test39-v0: Likewise.
	* tests/data/test-diff-filter/test39/test39-v1: Likewise.
	* tests/data/test-diff-filter/test39/test39.h: Likewise.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-diff-filter.cc (in_out_specs): Add the new test
	inputs above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:43 +02:00