Commit Graph

593 Commits

Author SHA1 Message Date
Dodji Seketeli
3001e78a4f Fix symlinks paths handling in abipkgdiff
When elements of an RPMs are referred to using a path that contains
symlinks, we need to resolve the symlinks in order to be able to
compare those paths.  We are not doing this fully and so we are
hitting corner cases where things break down in subtle ways.

This patch fixes that.

	* include/abg-tools-utils.h (real_path): Declare new function.
	* src/abg-tools-utils.cc (real_path): Define it.
	* tools/abipkgdiff.cc (package::convert_path_to_relative): Use the
	new real_path function to consider real path (where symlinks are
	resolved) of the extraction directory of the package.
	(get_interesting_files_under_dir): Similarly, use the new
	real_path function to consider the real path of the directory we
	are exploring.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-01-12 13:38:01 +01:00
Dodji Seketeli
6909dcb43c Bug 22692 - Consider Java as a language that supports the ODR
While comparing libgcj.so, it turned out that we are trying to
canonicalize a DW_TAG_class_type DIE expressing a Java type.

Right now, we don't canonicalize DW_TAG_class_type yet because
languages that emit those DIEs (like C++) do respect the One
Definition Rule.  So in theory, we do not need to canonicalize the
DW_TAG_class_type by using structural comparison.  We only perform DIE
canonicalization of DIEs originating from the C language as that
language does not respect the ODR.

We were assuming that only C++ actually respects the ODR.  In
practise, Java does also, so this patch now assumes that C++ and Java
respect the ODR.  So when facing DIEs originating from those
languages, we don't try (yet) to canonicalize their DIEs.

In the future though, we need to canonicalize all DIEs, irrespective
of the language they originated from.  And for that, we need to
support structural comparison of DW_TAG_class_type DIEs, among others.

	* include/abg-ir.h (is_java_language): Declare new function.
	* src/abg-dwarf-reader.cc (odr_is_relevant): Adjust to consider
	that Java also respects the ODR.
	* src/abg-ir.cc (is_java_language): Define new function.
	(odr_is_relevant): Adjust to consider that Java also respects the
	ODR.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-01-10 12:45:51 +01:00
Dodji Seketeli
2df84dd767 Fix version revision number printing in tools --help option
The revision number of the version string is junk since 1.0.  This
patch fixes that.

The patch also comes up with a function that returns a version string,
rather than having client code constructing the version string on
their own.

	* configure.ac: Properly set the VERSION_REVISION macro.
	* include/abg-tools-utils.h (get_library_version_string): Declare
	new function.
	* src/abg-tools-utils.cc (get_library_version_string): Define the
	new function.
	(gen_suppr_spec_from_kernel_abi_whitelist): Dis-ambiguate the use
	of the 'config' type.
	* tools/abicompat.cc (main): Use the new
	abigail::tools_utils::get_library_version_string function.
	* tools/abidiff.cc (main): Likewise.
	* tools/abidw.cc (main): Likewise.
	* tools/abilint.cc (main): Likewise.
	* tools/abipkgdiff.cc (main): Likewise.
	* tools/abisym.cc (main): Likewise.
	* tools/kmidiff.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-01-09 18:27:09 +01:00
Dodji Seketeli
b3c3049fdd Update copyright notice for all source files
Happy New Year 2018, I guess :-)

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-01-08 18:24:26 +01:00
Dodji Seketeli
8028cdd236 Bug 22488 - Make abipkgdiff handle different binaries with same basename
Some packages might have different binaries with the same soname and
basename, but at different paths.  In that case, abipkgdiff messes
things up because it only either consider the soname or the basename
of the binary.

This patch makes abipkgdiff to always consider the full path of the
binary inside the package.

	* include/abg-tools-utils.h (string_suffix)
	(sorted_strings_common_prefix): Declare new functions.
	(dir_name): Take a new keep_separator_at_end parameter at the end.
	* src/abg-tools-utils.cc (dir_name): Take a new
	keep_separator_at_end parameter at the end.  Add a comment for it
	and update.
	(string_suffix, sorted_strings_common_prefix): Define new
	functions.
	(common_prefix): Define new static function.
	* tools/abipkgdiff.cc (get_interesting_files_under_dir): Forward
	declare this pre-existing static function.
	(package::{common_paths_prefix_, elf_file_paths_}): New data
	members.
	(package::{common_paths_prefix, elf_file_paths,
	convert_path_to_relative, convert_path_to_unique_suffix,
	load_elf_file_paths}): New member functions.
	(create_maps_of_package_content): Use the new
	package::{load_elf_file_paths, convert_path_to_unique_suffix}
	functions.
	(compare_prepared_userspace_packages): Show relative paths of
	package elements in reported.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-report-0.txt:
	Update test ouptut.
	* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64-self-report-0.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-12-06 16:01:55 +01:00
Dodji Seketeli
eead00efb0 Bug 22436 - make abipkgdiff accept several debuginfo packages
Sometimes, the debug information for one given package P can have been
split into several packages.  In that case, we need abipkgdiff to
consider several debug info packages for a given input binary package.

This patch makes abipkgdiff to accept several --d{1,2} <debug-info-package>
option, for a given input package.

	* doc/manuals/abipkgdiff.rst: Document the fact that --d{1,2} can
	be provided several times on the command line.
	* tools/abipkgdiff.cc (options::debug_packages{1,2}): Rename the
	debug_package{1,2} data members into this, and make them be vector
	of strings, rather than just strings.
	(package::debug_info_packages_): Renamed
	package::debug_info_package_ into this and make it be a vector of
	package_sptr, rather than just a package_sptr.
	(package::debug_info_packages): Renamed the method
	package::debug_info_package into this and -- for the getter
	overload -- make it return a vector of package_sptr, rather than
	just a package_sptr.  Likewise for the setter overload.  Add a
	non-const getter overload.
	(package::erase_extraction_directories)
	(extract_package_and_map_its_content): Adjust.
	(extract_rpm, extract_deb): Do not erase the content of the
	extraction directory (if it was pre-existing) prior to extracting
	the RPM/deb into it.
	(pkg_extraction::pkgs): Renamed pkg_extraction::pkg into this and
	make it be a vector of packages, rather than just a package.
	(pkg_extraction::pkg_extraction): Adjust to take a package_sptr
	rather than just a package.  Add an overload to take a vector of
	packages_sptr.
	(pkg_extraction::perform): Extract the vector of package that the
	task is not responsible for, not just one random package.
	(extract_package_and_map_its_content): Adjust.
	(prepare_packages): Take smart pointers to package rather than
	just packages.  Adjust accordingly.
	(compare_prepared_package): Make the overload that takes two
	packages to take two smart pointers of packages.
	(compare): Make the overload that takes two package take two
	package_sptr.
	(parse_command_line): Parse having --d{1,2} several times for a
	given input package.
	(main): Take several debug info packages for one input file.
	* include/abg-tools-utils.h (split_string): Declare ...
	* src/abg-tools-utils.cc (split_string): ... new function.
	* tests/data/test-diff-pkg/libxfce4ui-debuginfo-4.12.1-8.fc27.ppc64.rpm:
	Add a new RPM test input file.
	* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64-self-report-ok-0.txt:
	new reference output file.
	* tests/data/Makefile.am: Add the new test input files above to source
	distribution.
	* tests/test-diff-pkg.cc (in_out_spec): Add new test entry to
	specify two debug info packages for one input package.
	(test_task::perform): Support having several debug info package
	paths in the IntOutSpec::{first,second}_in_debug_package_path data
	member.  The debug info packages paths are separated by either a
	white space or commas.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-11-27 17:15:20 +01:00
Dodji Seketeli
933c744034 Bug 22438 - Emit a clear message when debug info is not found
The alternate debug info file referred to a binary can be missing,
even though the rest of the debug info is not.  In that case,
libabigail starts loading the debug info and then it crashes when
trying to get DIEs that are part of the missing alternate debug info.

This patch detects when the alternate debug info is missing, so that
abidiff and abipkgdiff can gracefully bail out, yielding a meaningful
error message.

	* include/abg-dwarf-reader.h (enum abigail::dwarf_reader::status):
	Add a new STATUS_ALT_DEBUG_INFO_NOT_FOUND enumerator there.
	(refers_to_alt_debug_info): Declare new function.
	* src/abg-dwarf-reader.cc (read_corpus_from_elf): Detect when the
	referred-to alternate debug info file is not found and flip the
	STATUS_ALT_DEBUG_INFO_NOT_FOUND bit of the status accordingly.  If
	the debug info was found but not the alternate debug info, then do
	not try to read the debug info at all.
	(refers_to_alt_debug_info): Define new function.
	* tools/abidiff.cc (handle_error): Define new static function.
	(main): Use it, rather than handling errors preventing libabigail
	from reading the corpus on a case by case basis.
	tools/abipkgdiff.cc (compare): Handle the case where no alternate
	debug info was found.
	* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64-self-report-0.txt:
	New test output reference.
	* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64.rpm:
	New test input RPM.
	* tests/data/test-diff-pkg/libxfce4ui-devel-debuginfo-4.12.1-8.fc27.ppc64.rpm:
	Likewise.
	* tests/data/Makefile.am: Add the new test files above to source
	distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add a new test case from
	the new input files above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-11-21 11:09:00 +01:00
Dodji Seketeli
b438c0648e Allow setting options to instances of xml_writer::write_context
Up to know, it wasn't possible to set options to instances of
xml_writer::write_context.  So it wasn't possible to, say, make abidw
stop emitting source locations in the abixml.

This patch does the work necessary to set two options: annotate and
show locations.  Note that the patch doesn't yet enable abidw to stop
emitting source locations.  That will be done in a subsequent patch.

	* include/abg-writer.h (create_write_context, set_show_locs)
	(set_annotate): Declare new functions.
	(write_corpus, write_corpus_group): Remove the output stream and
	the annotate parameters as these can be retrieved from the
	context.
	* src/abg-writer.cc (write_context::m_show_locs): New data member.
	(write_context::write_context): Initialize it.
	(write_context::{get_show_locs, set_show_locs}): Add new member
	functions.
	(write_location): Take a write_context, rather than an output
	stream.  From the context, we detect if the user did set the "show
	loc" option and act accordingly.  Write the second overload in
	terms of the first one.
	(create_write_context, set_show_locs, set_annotate): Define new
	functions.
	(write_type_decl, write_qualified_type_def)
	(write_pointer_type_def, write_reference_type_def)
	(write_array_type_def, write_enum_type_decl, write_typedef_decl)
	(write_var_decl, write_function_decl)
	(write_class_decl_opening_tag, write_union_decl_opening_tag)
	(write_type_tparameter, write_non_type_tparameter)
	(write_function_tdecl, write_class_tdecl): Adjust the invocation
	of write_location.
	(write_corpus, write_corpus_group): Remove the output stream and
	the annotate parameters as these can be retrieved from the
	context.  Adjust.
	* tools/abidw.c: (load_corpus_and_write_abixml): Create a
	write_context object, set the 'annotate' option to it and use that
	object to actually write out the corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-11-02 12:54:34 +01:00
Dodji Seketeli
108a6074a5 Initial implementation of a --leaf-changes-only option to abidiff
This patch allows abidiff to take the --leaf-changes-only option and
then to display only the changes that are local to any given type.
That means the reporting agent won't follow pointers when displaying
changes.  That gives less context to the ABI change reports but then
they are less cluttered.

To do this, the patch introduces a new reporting agent to libabigail:
abigail::comparison::leaf_reporter.  When given a graph of diff nodes,
this agent only reports about the leaf (local) changes.  That is, it
will *NOT* follow pointers, references, underlying types of qualified
and typedef types and things like that. It will just report about
changes that are local to a given type.

This reporting agent is then used (in lieu of the default
abigail::comparison::default_reporter agent) when the
--leaf-changes-only option is provided by the user on the command line
of abidiff.

Note that abidiff also takes the --impacted-interfaces option to so
that the leaf reporter shows the set of interfaces impacted
by each leaf change.

	* doc/manuals/abidiff.rst: Add documentation the new
	--leaf-changes-only and --impacted-interfaces options.
	* src/abg-leaf-reporter.cc: New file.
	* src/Makefile.am: Add the new src/abg-leaf-reporter.cc file to
	source distribution.
	* include/abg-fwd.h (get_var_size_in_bits)
	(function_decl_is_less_than): Declare new functions.
	(get_name): Add new overload for type_or_decl_base*.
	* include/abg-ir.h (struct type_or_decl_hash, type_or_decl_equal)
	(type_or_decl_base_comp): Define new types.
	(artifact_sptr_set_type, artifact_ptr_set_type): Define new
	typedefs.
	* include/abg-comp-filter.h: Update copyright year.
	(has_basic_type_name_change): Add new function declaration.
	* src/abg-comp-filter.cc (decl_name_changed): Take a
	type_or_decl_base rather than just a decl.  Add an overload for
	diff*.
	(has_basic_type_name_change): Define new function.
	* include/abg-comparison.h: Update copyright year.
	(string_diff_ptr_map): Define this new typedef.
	(class diff_maps): Define this new class.
	(diff_context::{set_corpora}): Remove this member function.
	(diff_context::{set_corpus_diff, get_corpus_diff,
	show_leaf_changes_only, show_impacted_interfaces,
	forbid_visiting_a_node_twice_per_interface}): Declare these new
	member functions.
	(diff_node_visitor::priv_): Add a new pimpl data member.
	(diff_node_visitor::{diff_node_visitor, get_visiting_kind,
	set_visiting_kind}): Turn these into out-of-line member functions.
	(diff_node_visitor::{set,get}_current_topmost_iface_diff): Add new
	member functions.
	(class {scope_diff, function_type_diff, corpus_diff}): Add class
	leaf_reporter as a friend.
	(corpus_diff::mark_leaf_diff_nodes, get_leaf_diffs): Declare new
	member functions.
	(diff::{visiting_a_node_twice_is_forbidden_per_interface,
	parent_interface_node}): Define new member functions.
	(is_diff_of_basic_type): Return a type_decl_diff* rather than just
	a bool.
	(is_enum_diff, is_array_diff, is_function_type, is_typedef_diff)
	(is_corpus_diff): Declare new functions.
	(corpus_diff::diff_stats::{num_leaf_changes,
	num_leaf_changes_filtered_out, net_num_leaf_changes}): Add new
	member functions.
	(is_distinct_diff): Declare new function.
	* include/abg-reporter.h: Forward-declare "class diff_maps".
	(reporter_base::diff_to_be_reported): Declare a new virtual member
	function.
	(reporter_base::{report_local_typedef_changes,
	report_local_reference_type_changes,
	report_local_function_type_changes}): Declare new member
	functions.
	(class leaf_reporter): Define new type.
	* src/abg-comparison-priv.h (struct diff_hash, diff_equal): Define
	new types.
	(diff_artifact_set_map_type): Define new typedef.
	(diff_context::priv::{first_corpus_, second_corpus_}): Remove
	these data members.
	(diff_context::priv::{corpus_diff_, leaf_changes_only_,
	reset_visited_diffs_for_each_interface_,
	show_impacted_interfaces_}): Add new data members.
	(diff_context::priv::priv): Adjust.
	(corpus_diff::priv::{leaf_diffs_, parent_interface_}): Add new
	data member.
	(corpus_diff::diff_stats::priv::{num_leaf_changes,
	num_leaf_changes_filtered_out}): Add new data members.
	(corpus_diff::priv::count_leaf_changes): Define new member
	function.
	(sort_artifacts_set, get_fn_decl_or_var_decl_diff_ancestor)
	(is_diff_of_global_decls): Declare new functions.
	(function_comp::operator()): Factorize this out into the new
	function abigail::ir::function_decl_is_less_than.
	* src/abg-ir.cc (get_var_size_in_bits)
	(function_decl_is_less_than): Define new functions.
	(get_name): Define new overload for type_or_decl_base*.
	* src/abg-comparison.cc (is_enum_diff, is_typedef_diff)
	(is_array_diff, is_function_type_diff, is_corpus_diff)
	(is_distinct_diff, sort_artifacts_set, is_diff_of_global_decls):
	Define new functions.
	(is_union_diff): Fix comment.
	(diff_context::forbid_visiting_a_node_twice_per_interface): Define
	new member functions.
	(diff_context::set_corpus_diff, get_corpus_diff)
	(diff_context::show_leaf_changes_only)
	(diff_context::visiting_a_node_twice_is_forbidden_per_interface)
	(diff_context::show_impacted_interfaces): Define new member
	functions.
	(diff_context::get_reporter): Create the reporter that matches
	what diff_context::show_leaf_changes_only says.
	(diff_node_visitor::priv): Define a new type.
	(diff_node_visitor::{diff_node_visitor, get_visiting_kind,
	set_visiting_kind, or_visiting_kind,
	set_current_topmost_iface_diff, get_current_topmost_iface_diff}):
	Define new out-of-line member functions.
	(struct diff_maps::priv): Define new type.
	(diff_maps::{diff_maps, get_type_decl_diff_map,
	get_type_decl_diff_map, get_enum_diff_map, get_class_diff_map,
	get_union_diff_map, get_typedef_diff_map, get_array_diff_map,
	get_function_type_diff_map, get_function_decl_diff_map,
	get_var_decl_diff_map, get_reference_diff_map,
	get_fn_parm_diff_map, get_distinct_diff_map, insert_diff_node,
	lookup_impacted_interfaces}): Define member functions.
	(corpus_diff::{mark_leaf_diff_nodes, get_leaf_diffs}): Define new
	member functions.
	(struct leaf_diff_node_marker_visitor): Define new type.
	(corpus_diff::apply_filters_and_suppressions_before_reporting):
	Mark diff nodes in here.
	(corpus_diff::traverse): Appropriately set the current topmost
	interface into the visitor before visiting a diff node.
	(compute_diff): In the overload for corpus_sptr, adjust to reflect
	that we are now storing the corpus_diff in the diff context.
	(is_diff_of_basic_type): Return a type_decl_diff*, not just a
	bool.
	(corpus_diff::priv::count_leaf_changes): Define a new member
	function.
	(corpus_diff::diff_stats::{num_leaf_changes,
	num_leaf_changes_filtered_out, net_num_leaf_changes}): Define new
	member functions.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the
	new corpus_diff::priv::count_leaf_changes to compute the number of
	leaf changes.
	(corpus_diff::priv::emit_diff_stats): Emit the report about leaf
	type changes when necessary.
	* src/abg-reporter-priv.h (report_mem_header): Declare new
	overload.
	(maybe_show_relative_offset_change,): Pass the var_diff_sptr
	parameter by const reference.
	(represent): Pass the var_diff_sptr parameter by const reference
	and take a new "local-only" flag.
	(maybe_show_relative_size_change)
	(maybe_report_interfaces_impacted_by_diff): Declare new functions.
	* src/abg-default-reporter.cc: Adjust copyright year.
	(default_reporter::{report_local_typedef_changes,
	report_local_qualified_type_changes,
	report_local_reference_type_changes,
	report_local_function_type_changes}): Define new member functions.
	(default_reporter::report): Adjust.  Add an overload for
	function_type_diff&. In the overload for qualified_type_diff, if
	the name of the underlying type changed, do not detail the changes
	any further.  In the overload for function_decl_diff, Adjust to
	use the new diff_context::get_{first, second}_corpus member
	function.  In the overload for enum_diff, call the new
	maybe_report_interfaces_impacted_by_diff that is advertised below.
	* src/abg-reporter-priv.cc (represent): Adjust the overload for
	var_diff_sptr.
	(report_mem_header): Define new overload.
	(maybe_show_relative_size_change)
	(maybe_report_interfaces_impacted_by_diff): Define new functions.
	(reporter_base::diff_to_be_reported): Define new member function.
	(maybe_show_relative_offset_change): Pass the var_diff_sptr
	parameter by const reference.
	(represent): In the overload for var_diff_sptr, pass the
	var_diff_sptr parameter by reference.  Take a 'local_only' flag.
	Iisplay type changes only if we are not displaying "local changes
	only".  Display size changes of data members too, when in
	"local-only" mode.
	* src/abg-suppression.cc (sonames_of_binaries_match)
	(names_of_binaries_match): Adjust.
	* tools/abidiff.cc (options::{leaf_changes_only,
	show_impacted_interfaces}): Add new data members.
	(display_usage): Emit usage string for the new --leaf-changes-only
	and --impacted-interfaces options.
	(parse_command_line): Parse the new --leaf-changes-only and the
	--impacted-interfaces options.
	(set_diff_context_from_opts): Set the 'show-leaf-changes' and the
	'show-impacted-interfaces' flags.
	* tests/data/test-diff-filter/libtest42-leaf-report-v{0,1}.so: New
	test input.
	* tests/data/test-diff-filter/test42-leaf-report-output-0.txt: New
	test reference output.
	* tests/data/test-diff-filter/test42-leaf-report-v{0,1}.cc: Source
	code of the new test inputs.
	* tests/test-diff-filter.cc (in_out_specs): Use the new test
	inputs above in this harness.
	* tests/data/test-diff-suppr/libtest35-leaf-v0.so: New test input.
	* tests/data/test-diff-suppr/test35-leaf-report-0.txt: New test
	reference output.
	* tests/data/test-diff-suppr/test35-leaf-v{0,1}.cc: Source code of
	the new test inputs.
	* tests/data/test-diff-suppr/test35-leaf.suppr: Suppression
	specification to use for the test35 test.
	* tests/data/test-diff-suppr/libtest36-leaf-v0.so: New test input.
	* tests/data/test-diff-suppr/libtest36-leaf-v1.so: Likewise.
	* tests/data/test-diff-suppr/test36-leaf-report-0.txt: New
	reference test output.
	* tests/data/test-diff-suppr/test36-leaf-v0.cc: Source code of
	test input above.
	* tests/data/test-diff-suppr/test36-leaf-v1.cc: Likewise.
	* tests/test-diff-suppr.cc (in_out_specs): Use the new test inputs
	above in this harness.
	* tests/data/Makefile.am: Add the new test inputs above to source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-10-08 18:51:35 +02:00
Dodji Seketeli
3824d8f3c2 Allow several kinds of reports to be emitted
Right now, the reporting functionnality is implemented directly in the
comparison engine.  Being able to emit several kinds of reports is
really not practical with the current design.

This patch improves that situation by introducing an indirection
between the comparison engine and the code that emits the report.

A new abigail::comparison::reporter_base type is introduced.  That
type several contains virtual methods that knows how to implement
reporting.  Each virtual method reports about changes carried by a
kind of diff node.  In other words, abigail::comparison::reporter_base
is the interface of reporter objects.

The current reporting using the current format is thus implemented by
the new abigail::comparison::default_reporter type, which implements
the abigail::comparison::reporter_base interface.

The diff::report methods now "just" get the reporter object from the
context of the diff and invoke its right reporting interface.

So whenever someone needs to implement a new reporting format, she
needs to provide a new implementation of the
abigail::comparison::reporter_base interface and set it to the
diff_context prior to invoking the
abigail::comparison::corpus_diff::report() method.

	* include/Makefile.am: Add the new abg-reporter.h header file to
	source distribution.
	* include/abg-comparison.h: Include the new abg-reporter.h header
	file.
	(diff_context::{g,s}et_reporter): Declare new accessors.
	({type_diff_base, decl_diff_base, corpus_diff}::priv): Make this
	be a struct rather than a class.
	({decl_diff_base, class_diff, scope_diff, function_type_diff,
	corpus_diff}): Declare default_reporter a friend class of these.
	* include/abg-reporter.h: New file.
	* src/Makefile.am: Add abg-comparison-priv.h,
	abg-reporter-priv.{h,cc} and abg-default-reporter.cc files to
	source distribution.
	* src/abg-comparison-priv.h: New file.
	* src/abg-comparison.cc (sort_enumerators)
	(sort_changed_enumerators, sort_data_members)
	(sort_string_function_ptr_map)
	(sort_string_function_decl_diff_sptr_map)
	(sort_string_var_diff_sptr_map, sort_string_elf_symbol_map)
	(sort_string_var_ptr_map, sort_string_data_member_diff_sptr_map)
	(sort_unsigned_data_member_diff_sptr_map)
	(sort_string_diff_sptr_map, sort_string_base_diff_sptr_map)
	(sort_string_base_sptr_map, sort_string_fn_parm_diff_sptr_map)
	(sort_string_parm_map, get_leaf_type, sort_enumerators)
	(sort_changed_enumerators): Make these functions non-static and
	move them at the beginning of the file.  These functions are now
	declared in abg-compared-priv.h so they can be shared privately
	with other files in src/.
	(diff_context::{g,s}et_reporter): Define new accessors.
	({diff_context, diff, type_diff_base, decl_diff_base,
	distinct_diff, pointer_diff, array_diff, reference_diff,
	qualified_type_diff, enum_diff, class_or_union_diff, class_diff,
	base_diff, scope_diff, fn_parm_diff, function_type_diff,
	function_decl_diff, type_decl_diff, typedef_diff,
	translation_unit_diff, corpus_diff::diff_stats,
	corpus_diff}::priv)
	(diff_less_than_functor, enumerator_value_comp)
	(changed_enumerator_comp, base_spec_comp, base_diff_comp)
	(data_member_diff_comp, diff_comp, fn_parm_diff_comp, parm_comp)
	(elf_symbol_comp, function_comp, function_decl_diff_comp)
	(var_diff_sptr_comp): Move these type definitions to
	abg-comparison-priv.h
	(report_size_and_alignment_changes, report_loc_info)
	(maybe_report_diff_for_member, maybe_report_diff_for_symbol)
	(represent, represent_data_member)
	(maybe_show_relative_offset_change, represent)
	(report_size_and_alignment_changes, report_loc_info)
	(report_name_size_and_alignment_changes, report_mem_header)
	(maybe_report_diff_for_member, maybe_report_diff_for_symbol)
	(show_linkage_name_and_aliases): Move these definitions to
	abg-reporter-priv.cc.
	({distinct_diff, var_diff, pointer_diff, array_diff,
	reference_diff, qualified_type_diff, enum_diff,
	class_or_union_diff, class_diff, base_diff, union_diff,
	scope_diff, fn_parm_diff, function_type_diff, type_decl_diff,
	typedef_diff, corpus_diff}::report): Use the reporter object to
	report about the changes carried by the the current diff node.
	* src/abg-default-reporter.cc: New file.
	* src/abg-reporter-priv.h: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-10-06 12:33:50 +02:00
Dodji Seketeli
3f8c1cfae3 Add missing comment to type declaration
* include/abg-comparison.h (struct diff_sptr_hasher): Add missing
	comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-10-06 12:27:03 +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
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
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
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
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
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
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
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
Dodji Seketeli
e09fc8c9e2 Initial support of de-serializing the KMI of a Linux Kernel Tree
With this patch, kmidiff knows how to compare a serialized
corpus_group that represents a Kernel Module Interface (a .kmi file)
against either another serialized .kmi file, or against a kernel tree.

The patch extends the abixml reader to make it parse an
'abi-corpus-group' element.  To do that, the patch modifies
read_corpus_from_input to make it be capable of parsing several
'abi-corpus' in a row.  That modified function is then used by a new
read_corpus_group_from_input, which is itself used by the new public
entry points read_corpus_group_from_native_xml_file and
read_corpus_group_from_native_xml.

With that read_corpus_group_from_native_xml_file building block
function, the kmidiff program is modified so that it can take either
two directory trees, two .kmi files or one directory tree and one .kmi
file.

	* include/abg-libxml-utils.h (advance_to_next_sibling_element):
	Declare new function.
	* src/abg-libxml-utils.cc (go_to_next_sibling_element_or_stay)
	(advance_to_next_sibling_element): Define new functions.
	* include/abg-reader.h (read_corpus_group_from_input)
	(read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file): Declare new functions.
	* src/abg-reader.cc (read_context::m_corpus_group): New data
	member.
	(read_context::{get_corpus_group, set_corpus_group}): Define new
	member functions.
	(read_translation_unit_from_input): Cleanup logic.
	(read_corpus_from_input): Don't assume that the document is
	starting with an 'abi-corpus' element.  Support the mode where a
	caller called the xmlTextReaderExpand function (and so we are
	given an expanded xmlNodePtr) and the mode where we need to use
	the xmlTextReader API to walk through the 'abi-corpus' element.
	Also, if we are building a corpus group, do not clear what used to
	be 'per-corpus' data.  That data must be shared by all the corpora
	of a given abi-corpus-group.
	(read_corpus_group_from_input, read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file): Define new functions.
	* include/abg-tools-utils.h (FILE_TYPE_XML_CORPUS_GROUP): New
	enumerator of the file_type enum.
	* src/abg-tools-utils.cc (operator<<): In the overload for
	file_type, add a case for the new FILE_TYPE_XML_CORPUS_GROUP.
	(guess_file_type): Dectect abi-corpus-group xml element.
	* tools/abidiff.cc (adjust_diff_context_for_kmidiff): Define new
	static function.
	(main): Adjust to handle the new FILE_TYPE_XML_CORPUS_GROUP.  That
	is, compare two FILE_TYPE_XML_CORPUS_GROUP if they are present.
	* tools/abilint.cc (main): Likewise.
	* tools/kmidiff.cc (main): Detect that one of two .kmi files are
	passed.  In that case, load the .kmi file(s), build a corpus_group
	of it and use it in the comparison.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:41 +02:00
Dodji Seketeli
adb656cc76 Initial support of the serialization of the KMI of a Linux Kernel Tree
We have the kmidiff program that takes two Linux Kernel trees
containing the vmlinux binary and its modules and compare their Kernel
Module Interface, aka KMI.

We need to be able to serialize (save in a file) a representation of
that KMI.  We need to load that KMI back, and compare two serialized
KMIs.

This patch implements the serialization of the KMI of a Linux Kernel
tree.  It actually serializes an instance of abigail::ir::corpus_group
that is a collection of instances of abigail::ir::corpus.  The KMI of
each individual binary (vmlinux or kernel module) is represented by
one abigail::ir::corpus.  All the corpora share the same definitions
of types and decls, whenever that makes sense.

The patch thus factorizes the routines used to walk a Linux kernel out
of the kmidiff program.  These routines are then re-used in the abidw
program to make it walk a Linux kernel tree (when the --linux-tree
option is provided), load the vmlinux and module binaries as an
instance of abigail::corpus_group and serialize it out into an output
stream.

	* include/abg-tools-utils.h (check_dir)
	(get_binary_paths_from_kernel_dist)
	(build_corpus_group_from_kernel_dist_under): Declare new
	functions.  The last two functions are being moved from
	tools/kmidiff.cc so that they can be re-used.
	* include/abg-writer.h (write_corpus): Declare one overload that
	takes a write_context parameter.
	(write_corpus_group): Declare three overloads of this new function.
	* src/abg-tools-utils.cc (check_dir): Define new function.
	(load_generate_apply_suppressions, is_vmlinux, is_kernel_module)
	(find_vmlinux_and_module_paths)
	(get_binary_paths_from_kernel_dist)
	(build_corpus_group_from_kernel_dist_under): Define new functions.
	* src/abg-writer.cc (write_context::set_annotate): Define new
	member function.
	(write_corpus): Add an overload that takes a write_context.  Adapt
	the existing overload to make it use this new one.
	(write_corpus_group): Define this new function and two additional
	overloads for it.
	* tools/kmidiff.cc (set_suppressions, is_vmlinux)
	(is_kernel_module, find_vmlinux_and_module_paths)
	(get_binary_paths_from_kernel_dist)
	(build_corpus_group_from_kernel_dist_under): Remove.
	(main): Adjust the call to
	build_corpus_group_from_kernel_dist_under as its arguments are now
	adapted since it's been factorized out into abg-tools-utils.h.
	* tools/abidw.cc (options::corpus_group_for_linux): Define new
	data member.
	(options::options): Adjust.
	(display_usage): Add help strings for the new --linux-tree option.
	(load_corpus_and_write_abixml): Factorize this function out of the
	main function.
	(load_kernel_corpus_group_and_write_abixml): Define new function.
	(main): Use the factorized load_corpus_and_write_abixml and the
	new load_corpus_and_write_abixml functions.
	* tests/test-read-write.cc: Adjust.
	* doc/manuals/abidw.rst: Add documentation for the new
	--linux-tree option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:41 +02:00
Dodji Seketeli
56f36edcde Rename write_corpus_to_native_xml into write_corpus
Rename write_corpus_to_native_xml into write_corpus because it's a
better name.

	* include/abg-writer.h (write_corpus): Rename
	write_corpus_to_native_xml to this.
	* src/abg-writer.cc (write_corpus): Rename
	write_corpus_to_native_xml to this.
	* tests/test-read-dwarf.cc (test_task::perform): Adjust.
	* tests/test-read-write.cc: Remove a useless "using
	abigail::xml_writer::write_corpus_to_native_xml".
	* tools/abidw.cc (main): Adjust.
	* tools/abilint.cc (main): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:39 +02:00
Dodji Seketeli
5f92a183bb Make abipkgdiff compare two kernel packages
This patch makes abipkgdiff compare two kernel packages.  At the
moment the comparison is done by comparing each binary from the first
package to its counterpart in the second package.  No optimization is
done do represent a vmlinux binary and its modules as one single
entity.  So this is different from what kmidiff does.

	* include/abg-suppression.h
	(variable_suppression::variable_suppression): Add default arguments
	to the parameters.
	* include/abg-tools-utils.h (dir_exists, dir_is_empty)
	(string_begins_with, get_rpm_name, get_rpm_arch, get_deb_name)
	(file_is_kernel_package, file_is_kernel_debuginfo_package):
	Declare new functions.
	* src/abg-tools-utils.cc (dir_exists, dir_is_empty)
	(string_begins_with, get_deb_name, get_rpm_name, get_rpm_arch)
	(file_is_kernel_package, file_is_kernel_debuginfo_package): Define
	new functions.
	(gen_suppr_spec_from_kernel_abi_whitelist): The kernel ABI
	whitelist is made of ELF symbols names that ought to match
	functions *and* variables that have ELF symbols with those names.
	So generate variable suppression specifications as well.  Not just
	function suppression specifications.
	* tools/abipkgdiff.cc (options::{kabi_whitelist_package,
	show_symbols_not_referenced_by_debug_info, kabi_whitelist_paths,
	kabi_suppressions}): New data members.
	(options::options): Adjust.
	(package::KIND_KABI_WHITELISTS): New enumerator in the
	package::kind enum.
	(package::kabi_whitelist_package_): New data member.
	(package::{base_name, kabi_whitelist_package, }): New member
	functions.
	(display_usage): Add a help string to the new
	--linux-kernel-abi-whitelist and --no-unreferenced-symbols
	options.
	(parse_command_line): Parse the new --no-unreferenced-symbols,
	--linux-kernel-abi-whitelist and --lkaw-pkg options.
	(maybe_check_suppression_files): Check the presence of kabi
	whitelist files.
	(set_diff_context_from_opts): Consider (not) showing symbols not
	referenced by debug info.
	(compare): If we are looking at linux kernel packages, take the
	kernel abi whitelist into account, apply the suppressions
	resulting from the kabi whitelists to the ELF read context.
	(maybe_collect_kabi_whitelists)
	(get_kabi_whitelists_from_arch_under_dir)
	(maybe_handle_kabi_whitelist_pkg, maybe_collect_kabi_whitelists)
	(get_interesting_files_under_dir): Define new functions.
	(maybe_update_vector_of_package_content): Take a new
	file_name_to_look_for parameter.
	(create_maps_of_package_content)
	(extract_package_and_map_its_content): Consider the case of the
	package being a linux kernel package.
	(main): Take the potential --lkaw-pkg into account.
	* doc/manuals/abipkgdiff.rst: Add documentation for options
	--linux-kernel-abi-whitelist, --lkaw-pkg and
	--no-unreferenced-symbols.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:36 +02:00
Dodji Seketeli
8e8de9c3f5 Support loading and comparing two kernel trees
* include/abg-dwarf-reader.h (set_read_context_corpus_group)
	(read_and_add_corpus_to_group_from_elf, set_ignore_symbol_table)
	(get_ignore_symbol_table): Declare new functions.
	* abg-dwarf-reader.cc (read_context::options_type): Define new
	type.
	(die_dependant_container_set::clear): Define new member function.
	(read_context::{bss, tesxt, rodata, data, data1}_section_): Add
	new data members.
	(read_context::{symbol_versionning_sections_loaded_,
	symbol_versionning_sections_found_}): Likewise.
	(read_context::corpus_group_): Likewise.
	(read_context::{load_in_linux_kernel_mode, load_all_types,
	show_stats, do_log_}): Replace these options by ..
	(read_context::options_): ... this instance of the new
	read_context:options_type.
	(read_context::read_context): Adjust.
	(read_context::{clear_alt_debug_info_data, clear_per_corpus_data,
	env, get_data_section_for_variable_address, load_all_types,
	load_in_linux_kernel_mode, show_stats, do_log}): Adjust.
	(create_read_context): Adjust.
	(read_context::~read_context): Define destructor.
	(read_context::{options, bss_section, text_section,
	rodata_section, data_section, data1_section, current_corpus_group,
	has_corpus_group, main_corpus_from_current_group,
	main_corpus_from_current_group,
	current_corpus_is_main_corpus_from_current_group,
	should_reuse_type_from_corpus_group}): Define new member
	functions.
	(read_context::get_die_qualified_type_name): Handle the name of
	the current translation unit.
	(read_context::load_symbol_maps): Really don't load (linux kernel
	specific) symbol maps if we were told to ignore the ELF symbol
	table.
	(set_ignore_symbol_table, get_ignore_symbol_table)
	(create_default_var_sym, create_default_fn_sym, add_symbol_to_map)
	(set_read_context_corpus_group)
	(read_and_add_corpus_to_group_from_elf): Define new functions.
	(build_type_decl, build_typedef_type, build_enum_type)
	(add_or_update_class_type)
	(add_or_update_union_type): Reuse the type being built, from the
	main corpus of the corpus group.
	(build_qualified_type): Cleanup logic.
	(build_var_decl, build_function_decl): Create a default symbol for
	the variable or function if we are supposed to ignore the symbol
	table of the current binary.  Add that symbol to the symbol table
	that is created in the read context.
	(read_debug_info_into_corpus): Don't load the ELF symbol table
	information if we are asked to ignore the symbol table.  But set
	the symbol table that we built artificially while loading
	functions and variables, into the ABI corpus being built.
	(read_context::maybe_adjust_var_sym_address): Adjust.
	(build_ir_node_from_die): Add ir node to its logical scope.  For
	the C language, the scope of a type is the global scope.
	(read_corpus_from_elf): Don't load ELF properties if we were asked
	to avoid the ELF symbol table.
	* include/abg-comparison.h (compute_diff): Declare ...
	* src/abg-comparison.cc (compute_diff): ... an overload to compare
	corpus_group.
	* tools/kmidiff.cc: New tool.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:36 +02:00
Dodji Seketeli
c99addc245 Initial support to lookup types per location
This patch adds support to associate a type to its source location.
The location being a string of the form "filepath:line:column".  The
association is done by a per-translation unit map which associates a
location to a type.

For the moment this only associates one type to a given location.  For
the general case, though, we need to associate a vector or types to a
given location.  We'll add that support later.

The patch provides lookup functions, each of which looking up a
particular kind of type by its location.

	* include/abg-fwd.h (get_name_of_qualified_type)
	(get_name_of_reference_to_type, lookup_basic_type_per_location)
	(lookup_class_type_per_location, lookup_union_type_per_location)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, lookup_pointer_type)
	(lookup_reference_type, lookup_type_per_location)
	(lookup_type_through_translation_units)
	(lookup_type_from_translation_unit, odr_is_relevant): Declare new
	functions or new function overloads.
	* include/abg-ir.h (location::expand): Declare new member
	function.
	(type_maps::empty): Likewise.
	(operator|=): Declare an overload for qualified_type_def::CV.
	(get_string_representation_of_cv_quals)
	(get_name_of_qualified_type, lookup_qualified_type): Declare new functions.
	* src/abg-ir.cc (location::expand): Define new member function.
	(type_maps::empty): Likewise.
	(odr_is_relevant): Likewise.
	(get_string_representation_of_cv_quals)
	(get_name_of_reference_to_type, get_name_of_qualified_type)
	(lookup_union_type_per_location): Define new functions or overloads.
	(lookup_basic_type, lookup_enum_type, lookup_typedef_type)
	(lookup_qualified_type, lookup_pointer_type)
	(lookup_reference_type, lookup_type_from_translation_unit)
	(lookup_basic_type_per_location, lookup_basic_type_per_location)
	(lookup_class_type_per_location, lookup_class_type_per_location)
	(lookup_enum_type_per_location, lookup_enum_type_per_location)
	(lookup_typedef_type_per_location)
	(lookup_typedef_type_per_location, lookup_type_per_location):
	Define new overloads.
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Add a new
	use_type_name_as_key parameter.  If it's false, then associates
	the type to its location rather than to its name.
	(maybe_update_types_lookup_map): In the overloads for type_decl,
	class_decl, union_decl, enum_type, typedef_decl, array_type_def,
	record the type in the lookup map per location, in addition to the
	per-name recording.
	(qualified_type_def::build_name): Use the new
	get_name_of_qualified_type.
	(qualified_type_def::get_cv_quals_string_prefix): Use the new
	get_string_representation_of_cv_quals.
	(operator|=): Define a new overload for qualified_type_def::CV.
	(pointer_type_def::get_qualified_name): Use the new
	get_name_of_pointer_to_type.
	(reference_type_def::get_qualified_name): Use the new
	get_name_of_reference_to_type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:36 +02:00
Dodji Seketeli
50231b5537 Create a Corpus Group API extension
To support the upcomping analysis of the Linux kernel and its modules,
we need a way to represent a union of corpora.  The first corpus
loaded would be the one representing the vmlinux binary.  Subsequent
corpora loaded would be those representing the modules.

This patch provides the new abigail::ir::corpus_group type that
represents such a corpus group.

	* include/abg-corpus.h (corpus::{find_translation_unit,
	get_type_per_loc_map}): Declare new member functions.
	(corpus::{get_architecture_name, is_empty}): Make these member functions
	const.
	(corpus::{get_sorted_fun_symbols, get_functions, get_variables,
	get_unreferenced_function_symbols,
	get_unreferenced_variable_symbols}): Make these member functions
	virtual.
	(class corpus_group): Declare a new type.
	* include/abg-fwd.h (corpus_sptr, corpus_group_sptr)
	(string_tu_map_type, istring_var_decl_ptr_map_type)
	(istring_function_decl_ptr_map_type): Define new typedefs.
	* src/abg-corpus-priv.h (corpus_priv::{path_tu_map,
	type_per_loc_map_}): Add new data members.
	* src/abg-corpus.cc (corpus_add): Complete the function comment.
	Assert that at most one translation unit of a given path can be
	added to the corpus.
	(corpus::{find_translation_unit, get_type_per_loc_map}): Define
	new member functions.
	(corpus::{get_architecture_name}): Make this member function
	const.
	(struct corpus_group::priv): Define new type.
	(corpus_group::{corpus_group, ~corpus_group, add_corpus,
	get_corpora, is_empty, get_functions, get_variables,
	get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols,
	get_sorted_var_symbols, get_unreferenced_function_symbols,
	get_unreferenced_variable_symbols}): Define member functions of
	the new corpus_group type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:36 +02:00
Ben Woodard
3011d2ac8d Fix more clang build warnings
* include/abg-ini.h (config::section::priv): Make this be a class,
	not a struct.
	* src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir)
	(build_ir_node_from_die): Add parenthesis around assignment
	expressions inside conditional expression.
	* src/abg-suppression.cc (read_function_suppression): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-06-02 23:12:14 +02:00
Ben Woodard
b8a629f4a1 Fix some clang compile problems
* include/abg-comp-filter.h (class filter_base): Declare this as a
	struct.
	* include/abg-comparison.h (class filtering::filter_base):
	Likewise.
	(struct diff_traversable_base): Declare this as a class.
	* include/abg-ir.h (function_decl::parameter): Declare this before
	using it.
	* src/abg-corpus.cc
	(corpus::priv::build_unreferenced_symbols_tables): Add missing
	parenthesis around assignment expressions inside conditional
	expressions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-06-02 22:50:06 +02:00
Dodji Seketeli
d8f09c9e89 Avoid building DIE -> parent DIE map when analyzing a C binary
The C language doesn't support namespaces.  So, in that language, the
context of a type is always the global scope.  Hence, the context of a
type DIE is always the global context associated to the current
translation unit.

Thus, when we are analyzing a C binary, we can do away with building
the DIE -> DIE parent map that we later use to get the parent of a
type DIE when we need to determine the context of a given type DIE.

This can save significant time and space.

This patch implements this optimization.

	* include/abg-ir.h (global_scope_sptr): Make this be a share_ptr
	of scope_decl, not of global_scope.
	(translation_unit::get_global_scope): Return a reference to
	scope_decl_sptr.
	* src/abg-ir.cc (translation_unit::get_global_scope): Return a
	scope_decl not a global_scope.
	* src/abg-dwarf-reader.cc (read_context::nil_scope_): Add new data
	member.
	(read_context::{global_scope, nil_scope}): Define new member functions.
	(read_context::build_die_parent_maps): Do not build the map if we
	are looking at a C (or asm) translation unit.
	(get_scope_die, get_scope_for_die): If we are looking at a C
	translation unit then do return the global scope.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:50:54 +02:00
Dodji Seketeli
12b80d0770 Speed up access to the definition of a class declaration-only type
While emitting an abixml output for a corpus_group representing the
KMI of a Linux kernel tree, profiling shows that during comparison of
class types, calling class_decl::get_definition_of_declaration is a
hotspot.  Especially, the fact the function returns a shared pointer
that has to be "handled" shows up in the profile.

This patch introduces a
class_decl::get_naked_definition_of_declaration that returns a
pointer.  Not a shared pointer.

The patch then uses that get_naked_definition_of_declaration function
in the comparison code for class_decl.

The patch also uses get_naked_canonical_type instead of
get_canonical_type when comparing a bunch of other types.

This makes things a little bit faster when compiled without
optimization between 2% and 5%.

	* include/abg-ir.h
	(class_or_union::get_naked_definition_of_declaration): Declare a
	new member function.
	(class_decl::get_naked_definition_of_declaration): Likewise.
	* src/abg-ir.cc ({type_decl, qualified_type_def,
	array_type_def, enum_type_decl}::operator==): Use the
	get_naked_canonical_type and get_naked.
	(class_or_union::priv::naked_definition_of_declaration_): Define
	new data member.
	(class_or_union::priv::priv): Adjust to initialize the new data
	member.
	(class_or_union::get_naked_definition_of_declaration): Define new
	member function.
	({class_or_union, class_decl}::operator==): Use the new
	get_naked_definition_of_declaration instead of
	get_definition_of_declaration.
	(equals): In the overload for class_or_union, do the same.
	(class_decl::get_naked_definition_of_declaration): Define new
	member function.
	(hash_type_or_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:49:57 +02:00
Dodji Seketeli
57fafc1852 Don't consider changes to basic types as being redundant
Suppose we have two types struct A and struct B.  Suppose the two
types have members of integer type.  Suppose there are members of
integer type in struct A that are modified to become members of char
type.  Suppose, at last, that we also have members of integer type in
struct B that are modified to become members of char type.

In that case, we want to see all the changes of members which types
got changed from integer type to char type.  None of these changes
should be considered redundant.

Today, unfortunately, only the first change is reported by default.
The subsequent changes are considered to be redundant.

This patch fixes that by considering that changes that modifies the type of a
decl from a basic type into another are never considered redundant.

	* include/abg-comparison.h (is_diff_of_basic_type)
	(has_basic_type_change_only): Declare these functions ...
	* src/abg-comparison.cc (is_diff_of_basic_type)
	(has_basic_type_change_only): ... and define them.
	(redundancy_marking_visitor::visit_begin): Use the new
	has_basic_type_change_only.
	* tests/data/test-diff-filter/libtest37-v0.so: New binary test input.
	* tests/data/test-diff-filter/libtest37-v1.so: Likewise.
	* tests/data/test-diff-filter/test37-report-0.txt: New test
	reference output.
	* tests/data/test-diff-filter/test37-v0.cc: Source code of the new
	binary test input.
	* tests/data/test-diff-filter/test37-v1.cc: Likewise.
	* tests/data/Makefile.am: Update to add the new test material to
	the source distribution.
	* tests/test-diff-filter.cc (in_out_spec): Add the new test input
	to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:44:17 +02:00
Dodji Seketeli
e1fd8c095e Rename fn_parm_diff::get_type_diff into fn_parm_diff::type_diff
* include/abg-comparison.h (fn_parm_diff::type_diff): Renamed
	fn_parm_diff::get_type_diff intot his.
	* src/abg-comparison.cc (fn_parm_diff::type_diff): Likewise.
	(fn_parm_diff::report): Adjust.
	(redundancy_marking_visitor::visit_begin): Likewise.
	(is_diff_of_variadic_parameter): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:43:31 +02:00
Dodji Seketeli
ae3c88da13 Remove useless overloads of is_type
Now that there is a is_type predicate that takes a a type_or_decl_base
type, the overloads that take a decl_base or a type_base are useless
and can even lead to overload resolution issues.  This patch removes
those useless overloads.

	* include/abg-fwd.h (is_type):  Remove the overloads that take
	decl_base and type_base types.
	* src/abg-ir.cc (is_type): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:39:19 +02:00
Ondrej Oprala
0e88e12f05 cppcheck: mitigate performance warnings
* include/abg-diff-utils.h (print_snake): pass argument of type
	snake by const reference.
	* include/abg-ir.h (location::operator{==,<}): Likewise.
	* include/abg-viz-dot.h (node_base::{node_base,parent_node,child_node}):
	Likewise.
	* include/abg-viz-svg.h (svg::svg) Likewise.
	* src/abg-config.cc (config::config): Member initialization in ctor body.
	* src/abg-dwarf-reader.cc (class_decl_sptr::add_or_update_class_type):
	Initial value never used.
	* src/abg-ir.cc: (decl_base::priv::priv) Member initialization in ctor body,
	pass argument of type location by const reference.
	(equals): Variable initial value never used.
	* src/abg-reader.cc (read_corpus_from_input): Initial variable
	value never used.
	(build_elf_symbol_db): Use pre-increment.
	* src/abg-suppression-priv.h
	(suppression_matches_type_location): Pass argument of type
	location by const reference.
	* src/abg-suppression.cc: Likewise.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2017-04-14 04:41:44 -04:00
Slava Barinov
888cd3c376 Fix types in header to meet sources
Package fails to build for 32bit architectures since size_t is not 64 bits.

Make header consistent with source

	* include/abg-fwd.h: Include stdint.h for uint64_t.
	(ir::set_data_member_offset): Take uint64_t rather than size_t.
	(ir::get_data_member_offset): Return uint64_t rather than size_t.

Signed-off-by: Slava Barinov <v.barinov@samsung.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-27 17:10:13 +02:00
Dodji Seketeli
0c820488d4 Bug 21296 - Reporting diff of const ref against non-const ref aborts
References are always const.  But then GCC sometimes emits DWARF that
represents a const reference.  This leads, for instance, to a given
reference to be considered as different from that same reference wraps
into a const qualifier.  Which is wrong.

Libabigail then represents those const references as a particular case
of a "no-op qualifier".  That is, a qualifier that should be ignored
by the comparison code.

In the case of this issue, the comparison engine considers the two
references (const and non-const) to be equal, but the reporting code
forgets to ignore the ignore no-op qualifier and thus (wrongly)
considers the two references as being different.  That inconsistency
leads to an abort of the process.

This patch moves the code that ignores no-op qualifiers at a lower
level of the comparison engine so that whenever function parameters
are compared, no-op qualifiers are ignored as they should.

	* include/abg-fwd.h (look_through_no_op_qualified_type): Declare
	new function.
	* src/abg-ir.cc (look_through_no_op_qualified_type): Define it.
	(compute_diff_for_types): Use the new
	look_through_no_op_qualified_type here rather than open-coding it.
	(equals): In the overload for function_decl::parameter, use the
	new look_through_no_op_qualified_type function.
	* tests/data/test-diff-dwarf/test40-PR21296-clanggcc.cc: Source
	code of the new test inputs.
	* tests/data/test-diff-dwarf/test40-PR21296-clanggcc-report0.txt:
	New test input.
	* tests/data/test-diff-dwarf/test40-PR21296-libgcc.so: New binary
	test input.
	* tests/data/test-diff-dwarf/test40-PR21296-libclang.so: Likewise.
	* tests/test-diff-dwarf.cc (in_out_specs): Add the new test inputs to
	the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-24 12:39:49 +01:00
Dodji Seketeli
688d18dc71 Bug 21228 - Handle cloning union member functions
It turns out we allow member function cloning only for functions that
are members of classes, not for functions that are member of unions.

This patch fixes that by turning the method
class_decl::add_member_function into the
class_or_union::add_member_function.  Note that there was already an
overload of class_or_union::add_member_function; now, all the member
functions add_member_function are members of the class_or_union type.

The patch then modifies function_decl::clone to make that code avoid
assuming that only member functions of classes can be cloned.

	* include/abg-ir.h (class_or_union::add_member_function): Move the
	class_decl::add_member_function overload declaration into the
	class class_or_union class.
	(class class_decl): Make the class class_or_union be a friend of
	class_decl.
	* src/abg-ir.cc (class_decl::add_member_function): Transform the
	definition of this overload into ...
	(class_or_union::add_member_function): ... this one.  Make sure
	that when setting the virtual-ness attributes of the member
	function, we are effectively looking at the a function that is a
	member of a class.
	(function_decl::clone): Do not assert that a member function is
	necessarily a member of a class_decl.  It can also a member of a
	union_decl!.  So, rather, assert that the scope of the member
	function is of type class_or_union.
	* tests/data/test-diff-pkg/tbb-2017-8.20161128.fc26.x86_64.rpm:
	New test input RPM.
	* tests/data/test-diff-pkg/tbb-2017-9.20170118.fc27.x86_64.rpm:
	* tests/data/test-diff-pkg/tbb-debuginfo-2017-8.20161128.fc26.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/tbb-debuginfo-2017-9.20170118.fc27.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/tbb-2017-8.20161128.fc26.x86_64--tbb-2017-9.20170118.fc27.x86_64.txt:
	New reference test output.
	* tests/data/Makefile.am: Add the new test input RPMs to the
	source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Take the new input tests
	above into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-07 11:50:56 +01:00
Dodji Seketeli
1d85cc4546 Several fixes and enhancements to abigail::workers
While making abipkgdiff to use the abigail::workers API to do away
with using pthreads directory, it appeared that the abigail::workers
API needs fixes and enhancements.

Fixes
=====

* Don't try to schedule a task if the pointer to the task is nil

* Fix a data race when bringing workers (of a queue) down

* Always try to wake up all waiting threads when bringing down queue
  workers.

* Fix a data race when accessing the queue condition variable

* Fix a data race when notifying listeners about the end of the job
  performed by the task.

Enhancements
============

* Pass the "task done" notifier by reference, to the worker queue.

Without this, the worker queue needs to copy the "task done" notifier
by value.  This implies that user code needs to provide task done
notifier instances that come with potentially complicated copy
constructors.  By passing it by reference and by just re-using the
notifier from the user code, we do away with the need for copying
altogether.  This also fixes some latent copying bugs.

* Add a workers::queue::schedule_tasks() method

This allows user code to schedule a vector of tasks at once.

* make workers::queue::get_completed_tasks() return a non-const vector

This enables user code to sort the completed tasks as they wish.

	* include/abg-workers.h (queue::tasks_type): New typedef.
	(queue::queue): Pass task_done_notify by reference.
	(queue::schedule_tasks): Declare new member function.
	(queue::get_completed_tasks): Return non-const vector.
	* src/abg-workers.cc (queue::priv::default_notify): New data
	member.
	(queue::priv::notify): Make this data member be a reference.
	(queue::priv::priv): Initialize the notify data member to either
	the new default_notify (if no notifier is provided by the
	constructor) or to the notifier provided by the constructor.
	(queue::priv::schedule_task): Do not schedule a nil task.  Update
	comment.
	(queue::priv::schedule_tasks): Add a new member function.
	(queue::priv::do_bring_workers_down): Update comment.  Protect
	access to "bring_workers_down" with tasks_todo_mutex to prevent a
	data race.  Call pthread_cond_broadcast on the queue_cond
	unconditionaly to prevent some worker threads to keep waiting for
	ever. Also, protect the access to the queue_cond by the
	queue_cond_mutex to precent a data race.
	(queue::queue): Pass the notifier by reference. Update comment.
	(queue::schedule_task): Update comment.
	(queue::schedule_tasks): Define new member function.
	(queue::wait_for_workers_to_complete): Update comment.
	(queue::get_completed_tasks): Return a non-const vector. Update
	comment.
	(worker::wait_to_execute_a_task): Update several comments. Make
	the execution of the notification code to be synchronized (on the
	tasks_done_mutex).

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-02-27 09:48:08 +01:00
Dodji Seketeli
2d828b3b32 Misc style fixes
* include/abg-ir.h (class_or_union): Fix indentation.
	* src/abg-dwarf-reader.cc (get_die_pretty_representation): Add new
	line.
	* src/abg-ir.cc (struct class_decl::priv): Fix indentation.
	(virtual_member_function_less_than::operator()): Fix a typo in a
	comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-02-14 12:49:48 +01:00
Dodji Seketeli
059c86ec0b Bug 20476 - Compare virtual member functions when comparing classes
There are cases where a virtual member function doesn't have an
implementation that is defined and publicly exported.  This is the
cases for virtual pure classes.

Even in those cases, users might want to detect vtable changes on
virtual member pure classes (interfaces).

Now that, for C++ binaries, all the partial representations of a class
are merged into one class (in a given binary), we can envision to
compare virtual member functions of classes as part of comparing two
classes.

This is what this patch does.  While comparing two classes, the
virtual member functions are compared too.

Note that as there can be several virtual member functions that have
the same vtable offset (think about a virtual destructor that might
have several generated functions that 'conceptually' share the same
vtable offset), comparing the virtual functions can be a little bit
non-trivial.

The approach taken is to check that in the first set of virtual
functions, each virtual function actually matches at least one virtual
function in the second set.  And the match is a "loose" one.  That is,
it doesn't take into account the symbol name or the mangled name.

The patch also fixes the "less than" operator used to sort virtual
member functions.

There is also a buglet in the way we compute the highest vtable offset
number today.  This patch provides a new function named
class_decl::get_biggest_vtable_offset that is used in the change reports.

The patch also fixes a related bug in where we were forgetting to
report about added and removed virtual member functions without an
associated elf symbol.  This patch fixes that.

	* include/abg-ir.h (class_decl::get_biggest_vtable_offset):
	Declare new member function.
	* src/abg-ir.cc (virtual_member_function_less_than::operator()):
	Either compare the symbol id strings if the functions have
	symbols or just compare their pretty representations.
	(class_decl::get_biggest_vtable_offset): Define new member
	function.
	(methods_equal_modulo_elf_symbol)
	(method_matches_at_least_one_in_vector): New static methods.
	(equals): In the overload for classes, compare the virtual member
	functions while comparing classes.
	* src/abg-comparison.cc (represent): In the overload for
	method_decl_sptr, fix the way we compute the highest vtable offset
	number for a give class_decl.
	(class_decl::ensure_lookup_tables_populated): Don't forget added
	and removed virtual member functions in the report for changed
	classes.
	* tests/data/test-diff-dwarf/libtest41-PR20476-hidden-old.so: New
	test binary input file.
	* tests/data/test-diff-dwarf/libtest41-PR20476-hidden-new.so: Likewise.
	* tests/data/test-diff-dwarf/test41-PR20476-hidden-report-0.txt:
	New reference output.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-diff-dwarf.cc (in_out_spec): Add the new tests
	here.
	* tests/data/test-annotate/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-annotate/test11-pr18828.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test22-pr19097-libstdc++.so.6.0.17.so.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/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/test18-pr19037-libvtkRenderingLIC-6.1.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.
2017-02-14 12:49:47 +01:00
Ondrej Oprala
aba99e5106 Bug 20970 - Add a --annotate option to abidw
This option annotates (read "pretty-prints") the types and elf symbols
in the form of XML comments in the ABIXML output emitted by the abidw
command.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>

	* doc/manuals/abidiff.rst: Document the '--no-corpus-path'
	option.
	* doc/manuals/abidw.rst: Document the '--no-corpus-path'
	and '--annotate' options.
	* include/abg-libxml-utils.h ({un,}escape_xml_comment): Add
	new function declarations.
	* include/abg-writer.h: Add new annotate functions
	(write_{translation_unit,corpus_to_{archive,native_xml_file}}):
	Add an optional "annotate" parameter defaulting to "false".
	* src/abg-libxml-utils.cc ({un,}escape_xml_comment): Add
	new function definitions.
	* src/abg-writer.cc (annotate): Define new templatized function
	and specialize it for necessary cases.
	* tests/Makefile.am: Add runtestannotate as a new test.
	* tests/data/Makefile.am: Add paths to below reference test
	outputs.
	* tests/data/test-annotate/libtest23.so.abi: New reference test
	output.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-annotate/test11-pr18828.so.abi: Likewise.
	* tests/data/test-annotate/test12-pr18844.so.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test16-pr18904.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise.
	* tests/data/test-annotate/test3.so.abi: Likewise.
	* tests/data/test-annotate/test4.so.abi: Likewise.
	* tests/data/test-annotate/test5.o.abi: Likewise.
	* tests/data/test-annotate/test6.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Likewise.
	* tests/data/test-annotate/test9-pr18818-clang.so.abi: Likewise.
	* tests/test-annotate.cc: New test for ABIXML annotations.
	* tools/abidiff.cc: Add the new option '--no-corpus-path'.
	* tools/abidw.cc: Likewise. Also add the '--annotate' option.

reviews round 1

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-24 15:41:37 +01:00
Dodji Seketeli
2dcc6062f2 Fix suppression category propagation in diff node graph
Under certain circumstances, a diff node (which we shall name N) that
belongs to the SUPPRESSED_CATEGORY category sees its belonging to that
category been propagated to its parent diff node, effectively
suppressing that parent diff node as well.  This is how some function
diff nodes ends up being suppressed just because some of their
children diff nodes were suppressed.

This suppression category propagation is performed by a pass that
walks the diff nodes graph.  To avoid infinite cycles, the pass avoids
visiting a diff node that is equivalent to a node that has already
been visited.

As a result, diff nodes equivalent to N (the class of equivalence of
N) are not traversed by the propagation pass.  So their parent diff
nodes are not suppressed.

This leads to some functions not being suppressed as they should.
This phenomenon can be observed by comparing the two packages that are
provided in the regression test accompanying this patch using
abipkgdiff with the --redundant option.

Here is how the patch addresses the issue.

When the suppression category propagation pass considers a parent diff
node (named P) of a node N' (with N' being equivalent to N), it now
looks at the category of the *class of equivalence of N'* to determine
if that category should be propagated to P.

Previously, that pass would just look at the at the category of N'
(not the category of the class of equivalence of N') for the
propagation.  But as N' has not been visited (because N has already
been visited and nodes equivalent to N are thus not visited) the
belonging of N' to the SUPPRESSED_CATEGORY hasn't been updated.  So N'
isn't marked as being in SUPPRESSED_CATEGORY.  So the
SUPPRESSED_CATEGORY wouldn't be propagated to P as it should.

So, with this patch abipkgdiff invoked with the --redundant option now
correctly yields:

$ abipkgdiff --redundant --d1 spice-debuginfo-0.12.4-19.el7.x86_64.rpm --d2 spice-debuginfo-0.12.8-1.el7.x86_64.rpm --devel1 spice-server-devel-0.12.4-19.el7.x86_64.rpm --devel2 spice-server-devel-0.12.8-1.el7.x86_64.rpm spice-server-0.12.4-19.el7.x86_64.rpm spice-server-0.12.8-1.el7.x86_64.rpm
================ changes of 'libspice-server.so.1.8.0'===============
  Functions changes summary: 1 Removed, 2 Changed (62 filtered out), 8 Added functions
  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

[...]

  2 functions with some indirect sub-type change:

    [C]'function spice_image_compression_t spice_server_get_image_compression(SpiceServer*)' at reds.c:3618:1 has some indirect sub-type changes:
      return type changed:
        underlying type 'enum __anonymous_enum__' changed:
          type size hasn't changed
          7 enumerator deletions:
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_INVALID' value '0'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_OFF' value '1'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_AUTO_GLZ' value '2'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_AUTO_LZ' value '3'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_QUIC' value '4'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_GLZ' value '5'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_LZ' value '6'

          9 enumerator insertions:
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_INVALID' value '0'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_OFF' value '1'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_AUTO_GLZ' value '2'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_AUTO_LZ' value '3'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_QUIC' value '4'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_GLZ' value '5'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_LZ' value '6'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_LZ4' value '7'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_ENUM_END' value '8'

    [C]'function int spice_server_set_image_compression(SpiceServer*, spice_image_compression_t)' at reds.c:3602:1 has some indirect sub-type changes:
      parameter 2 of type 'typedef spice_image_compression_t' changed:
        underlying type 'enum __anonymous_enum__' changed:
          type size hasn't changed
          7 enumerator deletions:
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_INVALID' value '0'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_OFF' value '1'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_AUTO_GLZ' value '2'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_AUTO_LZ' value '3'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_QUIC' value '4'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_GLZ' value '5'
            '__anonymous_enum__::SPICE_IMAGE_COMPRESS_LZ' value '6'

          9 enumerator insertions:
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_INVALID' value '0'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_OFF' value '1'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_AUTO_GLZ' value '2'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_AUTO_LZ' value '3'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_QUIC' value '4'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_GLZ' value '5'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_LZ' value '6'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_LZ4' value '7'
            'SpiceImageCompression::SPICE_IMAGE_COMPRESSION_ENUM_END' value '8'

================ end of changes of 'libspice-server.so.1.8.0'===============

$

	* include/abg-comparison.h (diff::get_class_of_equiv_category):
	Declare new member function.
	* src/abg-comparison.cc: Update copyright year.
	(diff::get_class_of_equiv_category): Define new member function.
	(suppression_categorization_visitor::visit_end): When considering
	children nodes category for propagation, consider the category of
	the class of equivalence of children nodes.
	* spice-debuginfo-0.12.4-19.el7.x86_64.rpm: New input test package.
	* spice-debuginfo-0.12.8-1.el7.x86_64.rpm: Likewise.
	* spice-server-0.12.4-19.el7.x86_64.rpm: Likewise.
	* spice-server-0.12.8-1.el7.x86_64.rpm: Likewise.
	* spice-server-devel-0.12.4-19.el7.x86_64.rpm: Likewise.
	* spice-server-devel-0.12.8-1.el7.x86_64.rpm: Likewise.
	* spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt:
	New reference test output.
	* spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-1.txt: Likewise.
	* spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test inputs
	to the list of packages to test.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-20 10:59:58 +01:00
Dodji Seketeli
a821154753 Support virtual member functions with vtable offset not yet set
When reading C++ class informatin DWARF, it can happen that a given
virtual member function does not yet have a vtable offset.  Right now,
that offset is set to zero.  Just like a virtual member function which
actual vtable offset is zero.  So we don't make a difference between a
virtual function with no vtable offset and a virtual function with a
vtable offset set to zero.

This can lead to confusions during class comparison.

This patch fixes that problem by setting the default vtable offset to
-1.  So whenever a vtable offset is -1 it means that the virtual
member function doesn't yet have a vtable offset.

	* include/abg-fwd.h (member_function_has_vtable_offset): Declare
	new function.
	(get_member_function_vtable_offset): Return a ssize_t, not a
	size_t.
	(set_member_function_vtable_offset): Take a ssize_t, not a size_t.
	* include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust
	the map typedef to make it take ssize_t as the type of the key.
	(mem_fn_context_rel::vtable_offset_in_bits_): Make this data
	member be of ssize_t type, not size_t.
	(mem_fn_context_rel::mem_fn_context_rel): Initialize the
	vtable_offset_in_bits_ data member to -1.
	* src/abg-ir.cc (member_function_has_vtable_offset): Define new
	function.
	(get_member_function_vtable_offset): Return a ssize_t, not a
	size_t.
	(set_member_function_vtable_offset): Take a ssize_t, not a size_t.
	* src/abg-dwarf-reader.cc (die_virtual_function_index): Take an
	int64_t& rather than a uint64_t&.
	(finish_member_function_reading): Don't set the vtable offset if
	it's -1.
	* src/abg-reader.cc (build_class_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:56 +01:00
Dodji Seketeli
9136c6a639 Handle several virtual member functions having the same vtable offset
In the DWARF for C++, it can happens that a virtual constructor leads
to several (up to 3) destructor functions that all have the same
vtable offset.  That vtable offset is the same as the offset of the
virtual destructor that the user actually defined in her source code.

This patch adds a map data structure to the private data of
class_decl.  That map associates a vtable offset X to a vector of
virtual member functions that have the same vtable offset X.

That new map is populated whenever a virtual member function is added
to the class.

	* include/abg-ir.h (class_or_union::virtual_mem_fn_map_type):
	Define new typedef.
	(class_decl::get_virtual_mem_fns_map): Declare new accessor.
	* src/abg-ir.cc (class_decl::priv::virtual_mem_fns_map_): New data
	member.
	(class_decl::get_virtual_mem_fns_map): Define new accessor.
	(fixup_virtual_member_function): Populate the new virtual member
	functions map.
	(class_decl::on_canonical_type_set): Sort the virtual member
	function vectors stored in the new virtual member functions map.
	(class_decl::add_member_function): Call
	set_member_function_is_virtual *after* calling
	set_member_function_vtable_offset because the former updates the
	virtual function map, so it needs the vtable offset.
	* src/abg-dwarf-reader.cc (finish_member_function_reading):
	Likewise.
	* src/abg-reader.cc (build_class_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
367da46e7a Speed up pretty representing (function) types
During structural (function) type comparison, computing the pretty
representation of the type at hand appears high on performance profiles,
especially when type canonicalization wasn't really effective.

This patch adds a type_base::get_cached_pretty_representation() and a
function_type::get_cached_name() to cache the pretty representation of
a type, as well as the function type name.  This is way, the type
representation is computed just once and stored into a cache.
subsequent invocations of the function just look into the cache
instead of computing the representation again.

Note that we do this only for non-canonicalized types because these
types can still be modified, and so caching the representation of a
type that might be changed (and thus see its representation change)
leads to issue.  So the representation of non-canonicalized types is
not cached.

	* include/abg-ir.h (type_base::get_cached_pretty_representation):
	Declare new function.
	(function_type::get_cached_name): Likewise.
	* src/abg-ir.cc (get_method_type_name): Use the new
	type_base::get_cached_pretty_representation function.
	(type_base::priv::{internal_cached_repr_, cached_repr_}): Add new
	data members.
	(function_type::priv::{internal_cached_name_, cached_name_}):
	Likewise.
	(type_base::get_cached_pretty_representation): Define new
	function.
	(function_type::get_cached_name): Likewise.
	(type_base::get_canonical_type_for): Call
	type_base::get_cached_pretty_representation here, so the internal
	representation is cached right before canonicalization.
	(function_type::{mark_as_being_compared, unmark_as_being_compared,
	comparison_started}): Uset he new type_base::get_cached_name to
	speed up function type name retrieval.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
b49119584b Add missing deep comparison operators for {function, method}_decl_sptr
It turned out we were missing deep comparison operators for smart
pointers to function_decl and method_decl.  Because of coming patches
that compare virtual member functions as part of comparing classes, we
need these deep comparison operators.

	* include/abg-ir.h (operator==): Declare two new overloads for
	function_decl_sptr an method_decl_sptr.
	* src/abg-ir.cc (operator==): Define two new overloads for
	function_decl_sptr an method_decl_sptr.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
0af65e6364 Fix performance regression while analyzing libjvm.so
abidiff libjvm.so libjvm.so is taking forever in the master branch
these days.  At some point it was taking ~ 15 minutes and 15GB of RAM
on a non-optimized build.

Profiling of CPU usage showed that sorting virtual member
functions of a class whenever a new virtual member function is added
was the hot spot.

This patch now sorts virtual member functions once right after the
type was canonicalized.  The patch adds a virtual function
type_base::on_canonical_type_set() that is invoked right after the
canonical type is set for a given type.  class_decl gets its own
version of that virtual function: class_decl::on_canonical_type_set.
In that function, the patch does sort the virtual member functions of
the current class_decl.

Now with this patch, abidiff is still taking around 15 minutes but it
consumes less than 12GB of ram.  This means the memory consumption was
reduced by 20%.  abipkgdiff performs on 16:30 minutes and in less than
12GB of RAM as well.  All these times are measured on a non-optimized
build.

	* include/abg-ir.h ({type_base,
	class_decl}::on_canonical_type_set): Declare new virtual member
	function.
	* src/abg-ir.cc (type_base::on_canonical_type_set): Define new
	virtual member function that does nothing.
	(class_decl::on_canonical_type_set): Define new virtual member
	function that sorts the virtual member functions of class_decl.
	(canonicalize): Invoke type_base::on_canonical_type_set when the
	canonical type is set.
	(fixup_virtual_member_function): Don't sort virtual member
	functions here.
	* src/abg-dwarf-reader.cc (finish_member_function_reading): Do not
	sort virtual member functions here.
	* 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/test21-pr19092.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-01-16 19:25:36 +01:00
Dodji Seketeli
9dc07f5534 Update copyright notice for abg-fwd.h, abg-ir.h and test-abidiff.cc
* include/abg-fwd.h: Adjust copyright.
	* include/abg-ir.h: Likewise.
	* tests/test-abidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 15:36:20 +01:00
Dodji Seketeli
08e760221b Support Linux Kernel ABI whitelist files
Enterprise Linux (at least) kernels come with ABI whitelist files that list the
names of the set of functions to be considered when looking at the ABI
exposed by the kernel to its modules.

This patch adds a new --linux-kernel-abi-whitelist option to abidiff
so that it drops changes that relate to functions that are *NOT*
defined in the whitelist.

The patch reads the whitelist file and generates one or several
instances of function_suppression that are applied when the two
binaries are loaded.

	* include/abg-suppression.h
	(function_suppression::function_suppression): Make the declaration
	of the default constructor public.
	* src/abg-suppression-priv.h (function_suppression::priv::priv):
	Declare a default constructor.
	* src/abg-suppression.cc
	(function_suppression::function_suppression): Define default
	constructor.
	* include/abg-tools-utils.h
	(gen_suppr_spec_from_kernel_abi_whitelist): Declare new function.
	* src/abg-tools-utils.cc
	(gen_suppr_spec_from_kernel_abi_whitelist): Define new function.
	* tools/abidiff.cc (options::kernel_abi_whitelist_paths):
	(display_usage): Display a help string for the new
	--linux-kernel-abi-whitelist option.
	(parse_command_line): Parse the --linux-kernel-abi-whitelist from
	the command line.
	(maybe_check_suppression_files): Check the presence of the kernel
	abi whitelist files.
	(set_suppressions): Generate suppression specifications from the
	whitelist files.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 12:41:57 +01:00
Dodji Seketeli
fadfa1a6f6 Support Linux Kernel binaries
This patch teaches the ELF/DWARF reader of libabigail to load special
ELF sections that are specific to Linux Kernel binaries (either
vmlinux or linux kernel modules).

The patch creates a new flag that tells the ELF reader that it needs
to consider the input binary as a Linux Kernel binary.  This is the
new 'Linux Kernel mode'.

In this linux kernel mode, the reader expects sections that are named
__ksymtab and/or __ksymtab_gpl sections.  Those sections contain
indexes (of ELF symbols described in the normal ELF symbol table) of
exported ELF symbols that are specifically marked by developers using
EXPORT_SYMBOL or EXPORT_SYMBOL_GPL macros.  These are symbols of
global variables and functions defined and meant to be used by kernel
modules.  They constitute the interface exported by the Linux Kernel
to its modules.  So the patch only exports the publicly defined and
exported ELF symbols that are also listed in __ksymtab and
__ksymtab_gpl sections.

The patch also fixes and re-organizes things left and right so that
this new mode works in a well integrated manner with the other parts
of the reader:

  - The load address of the binary is no more assumed to be the load
    address specified by the program header that is at offset zero.
    This is usually the case for user-space programs.  To handle Linux
    Kernel binaries, the load address is now the one specified by the
    program header that is at the smallest offset.

  - The patch now tries to populate the various symbol maps only when
    necessary.  That way, the new symbol maps defined for the ksymtab
    and ksymtab_gpl section are also loaded only when necessary; that
    is, when in Linux Kernel mode.

  - The patch (more) agressively suppresses non-member functions or
    variables that are not declarations and that have no associated
    ELF symbol.

The patch knows how to recognize and read relevant ELF symbol
information from __ksymtab and __ksymtab_gpl sections.

The patch makes abidiff and abidw detect that a binary is a
Linux Kernel binary (either a vmlinux or a module).  It does this by
detecting the presence of the speciall __ksymtab_strings section.

If it detects that a binary is a Linux Kernel binary then it only
considers functions and variables which are defined and exported in
the sense of ELF *AND* which ELF symbols are listed in the __ksymtab
and __ksymtab_gpl sections.

If users want abidiff and abidw to consider their input binaries as
normal ELF binaries then they can use the option --no-linux-kernel-mode.

	* include/abg-dwarf-reader.h (create_read_context): Take a new
	flag to say if the context is to read an ELF binary in linux
	kernel mode.
	* src/abg-dwarf-reader.cc (typedef address_set_type)
	(address_set_sptr): New typedefs.
	(get_binary_load_address):  The load address of the binary is
	the load address specified by the program header that is at the
	smallest offset; not by the program header that is at offset zero.
	(read_context::{ksymtab_section_, ksymtab_gpl_section_,
	linux_exported_fn_syms_, linux_exported_var_syms_,
	linux_exported_gpl_fn_syms_, linux_exported_gpl_var_syms_,
	load_in_linux_kernel_mode_}): New data members.
	(read_context::read_context): Initialize ksymtab_section_,
	ksymtab_gpl_section_ and load_in_linux_kernel_mode_.
	(read_context::{find_symbol_table_section, find_opd_section,
	lookup_elf_fn_symbol_from_address,
	lookup_elf_var_symbol_from_address, get_function_address,
	get_variable_address}): Make these const.
	(read_context::{find_ksymtab_section, find_ksymtab_gpl_section,
	lookup_elf_symbol_from_address, function_symbol_is_exported,
	variable_symbol_is_exported, linux_exported_fn_syms,
	create_or_get_linux_exported_fn_syms, linux_exported_var_syms,
	create_or_get_linux_exported_var_syms, linux_exported_gpl_fn_syms,
	linux_exported_gpl_var_syms,
	create_or_get_linux_exported_gpl_fn_syms,
	linux_exported_gpl_var_syms,
	create_or_get_linux_exported_gpl_var_syms, architecture_word_size,
	load_kernel_symbol_table, load_ksymtab_symbols,
	load_ksymtab_gpl_symbols,
	load_linux_specific_exported_symbol_maps,
	load_in_linux_kernel_mode}): New member functions.
	(read_context::read_int_from_array_of_bytes): Factorize this
	new member function out of ...
	(read_context::{lookup_ppc64_elf_fn_entry_point_address}):
	... this.  Make this function const too.
	(read_context::read_uint64_from_array_of_bytes): New function.
	Uses read_int_from_array_of_bytes above.
	(read_context::{fun_entry_addr_sym_map_sptr}): Try to load symbol
	maps only when it's necessary.
	(read_context::elf_architecture_is_big_endian): Fix logic.
	(read_context::{var_addr_sym_map}):  Express the const variant in
	terms of the non-const one.  In the non-const one, load the map
	only when necessary.
	(read_context::load_symbol_maps_from_symtab_section): Renamed
	load_symbol_maps into this.
	(read_context::is_linux_kernel_binary): Define new member
	function.
	(read_context::{function, variable}_symbol_is_exported): If we are
	not prevented from considering loading in linux kernel mode, then
	just looking at a linux kernel binary makes us consider the
	special kernel sections.
	(read_debug_info_into_corpus): Likewise.
	(build_ir_node_from_die): Take a new flag that says if the ir node
	is a declaration required by another concrete IR node.
	(enum read_context::kernel_symbol_table_kind): New enum.
	(read_context::load_symbol_maps): Support loading linux kernel
	specific sections too.
	(build_var_decl): Use the new
	read_context::variable_symbol_is_exported.
	(function_is_suppressed): Suppress non-member functions or
	variables that are not declarations and that have no symbol.
	(variable_is_suppressed, build_var_decl_if_not_suppressed): Take a
	new flag that says if the variable is a declaration required by a
	concrete variable.  If non member variable that is a declaration
	is not the specification of another concrete variable, then it's
	suppressed.
	(add_fn_symbols_to_map, add_var_symbols_to_map): New function
	definitions.
	(read_debug_info_into_corpus): If we are reading linux kernel or
	linux kernel modules, only set explicitely exported symbols (in
	the linux kernel binary sense) as exported function or variable
	symbols.
	(create_read_context): Take a new flag to say if the context is to
	read an ELF binary in linux kernel mode.
	* tools/abidiff.cc (options::options): Initialize
	options::linux_kernel_mode to true.
	(display_usage): Display usage of the --no-linux-kernel-mode option.
	(parse_command_line): Parse the --no-linux-kernel-mode option.
	* tools/abidw.cc (options::options): Initialize
	options::linux_kernel_mode to true.
	(display_usage): Display usage of --no-linux-kernel-mode option.
	(parse_command_line): Parse the --no-linux-kernel-mode option.
	* doc/manuals/abidiff.rst: Document the new --no-linux-kernel-mode
	options.
	* doc/manuals/abidw.rst: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.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: 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/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/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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 12:35:22 +01:00
Dodji Seketeli
d198b27b64 Update copyright year on a bunch of files
* include/abg-corpus.h: Update copyright year to 2017.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidw.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:51:49 +01:00
Dodji Seketeli
4063dfe487 Misc style fixes
* include/abg-corpus.h: Remove corpus_sptr typedef. It's in
	abg-fwd.h now.
	* src/abg-ir.cc: Remove some unnecessary vertical space.
	* src/abg-reader.cc (build_function_decl): Cleanup some asserts.
	* src/abg-writer.cc (write_function_type): Each the inspection of
	the type id from within the debugger.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:51:30 +01:00
Dodji Seketeli
c495a5c5f0 Handle per translation unit and per corpus types maps
Today, whenever a type is added to its scope, a map that associates
the qualified type name to the type is updated.  There is only one
such map in a given ABI corpus.

So whenever a type is looked up from its name, it's that per-corpus
type map that is used.

This setup makes libabigail type lookup be tailored only for binaries
that respect the One Definition Rule of C++[1] (aka ODR) which
basically says that there should be only one type of a given name in
an ABI corpus.

It turns out that many binaries, especically C binaries, don't respect
the ODR.  So a type "struct foo" can be defined in a file a.c and
another *different* type "struct foo" can also be defined in b.c.
What a useful and safe feature! Not.

For those binaries, just having one type map doesn't work.  We need to
have one type map per translation unit, and one map per-corpus map.

This is the strategy implemented by this patch.

With this patch, whenever a type is added to its scope, a
per translation unit type map is updated.  The per corpus map is
updated as well.  If there are more than one type of a given name, the
entry in the per corpus type map for that type is left empty.

Type lookup now potentially becomes a two phases lookup.  Whenever a
type is looked up from its name, the per corpus type map is looked at
first.  If the type is not in that per corpus type map, then the per
translation unit type maps are lookup up, in sequence.

The patch thus re-visits the type maps updating and lookup routines to
adapt them to the new scheme.  The patch also updates the clients of
the type map updating and lookup code.

Note that this patch is part of a series of patches which aims to move
libabigails away from its ODR-centric organization to make it work
well also on binary where the ODR is not relevant.  As such, the patch
doesn't assure that "make check" passes.  To have "make check" pass,
you need to have all the patches of the series applied.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

	* include/abg-fwd.h (lookup_type_in_corpus): Remove.  This is to
	be replaced by the new lookup_type below.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type):
	(lookup_class_type_through_scopes, lookup_type)
	(lookup_type_through_scopes, lookup_or_synthesize_fn_type)
	* src/abg-ir-priv.h (struct translation_unit::priv):  Move this
	private type here, from abg-ir.h.
	(synthesize_type_from_translation_unit): Declare new functions.
	* include/abg-ir.h (class type_maps): Define new type.
	(translation_unit::get_function_types): Remove.
	(translation_unit::get_types): Now return a type_maps.
	(translation_unit::get_live_fn_types): Declare new type.
	(class decl_base): Make canonicalize be a friend of this class.
	* src/abg-ir.cc (struct translation_unit::priv): Move this to
	abg-ir-priv.h
	(struct type_maps::priv): Define new type.
	(type_maps::{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Define new accessors.
	(translation_unit::bind_function_type_life_time): Adjust.
	(translation_unit::get_function_types): Remove accessor.
	(translation_unit::get_types, get_live_fn_types): Define new
	accessors.
	(lookup_type_in_translation_unit)
	(lookup_class_type_in_translation_unit)
	(lookup_function_type_in_translation_unit)
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit)
	(lookup_class_type_in_translation_unit) Remove function
	definitions.
	(lookup_type_in_map): Define function template.
	(lookup_{basic, class, union, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define functions.
	(lookup_function_type, lookup_type_through_scopes)
	(lookup_class_type_through_scopes)
	(lookup_basic_type_through_translation_units)
	(lookup_union_type_through_translation_units)
	(lookup_enum_type_through_translation_units)
	(lookup_class_type_through_translation_units)
	(lookup_typedef_type_through_translation_units)
	(lookup_qualified_type_through_translation_units)
	(lookup_pointer_type_through_translation_units)
	(lookup_reference_type_through_translation_units)
	(lookup_array_type_through_translation_units)
	(lookup_function_type_through_translation_units)
	(lookup_type_through_translation_units)
	(lookup_or_synthesize_fn_type, lookup_type): Likewise.
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Define function
	template, specilizations and functions.
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit): Define
	functions.
	* include/abg-corpus.h (corpus::get_types): Declare new accessor.
	* src/abg-corpus.cc (corpus::priv::get_types): Define new
	accessor.
	(corpus::get_types): Likewise.
	(lookup_type_in_corpus, lookup_class_type_in_corpus)
	(lookup_type_in_corpus, lookup_function_type_in_corpus)
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Remove.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type): Likewise.
	* src/abg-corpus-priv.h (corpus::priv::{basic, class, union,
	typedef, qualified, pointer, reference, array, function}_types):
	Remove these data members.
	(corpus::priv::get_scopes): Remove member function.
	(corpus::priv::get_{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Remove member
	function declarations.
	(corpus::priv::types_): New data member.
	(corpus::priv::get_types): Declare new member function.
	(lookup_{basic, class, enum, typedef, class_or_typedef, qualified,
	pointer, reference, array, function}_type): Declare new functions.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes)
	(build_translation_unit_and_add_to_ir): Adjust use of
	lookup_class_type.
	* src/abg-reader.cc (read_context::type_is_from_translation_unit):
	Adjust to the use of lookup_function_type_in_translation_unit that
	got renamed into lookup_function_type.
	* src/abg-writer.cc (type_ptr_cmp::operator()): New operator
	implementation.
	(read_context::sort_type): Add new overloads.
	(write_translation_unit): Adjust to get the function types from
	the new translation_unit::get_live_fn_types and sort them.
	* tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust
	to use the new lookup_or_synthesize_fn_type, in lieu of
	lookup_function_type_in_corpus.  Adjust to use lookup_type in lieu
	of lookup_type_in_corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
bca3f9d163 Make abg-fwd.h use *_sptr typedefs
Until now, the abg-fwd.h where the necessary forward generic
declarations where put didn't contain the convenience typedefs of the
form foo_sptr that designate a shared pointer to type foo.

This patch moves these convenience typedefs as well as the missing
forward declarations from abg-ir.h to abg-fwd.h.  The patch also
adjusts the function declarations in abg-fwd.h to make them use these
convenience typedefs.

	* include/abg-ir.h: Move convience typedef declarations and some
	necessary forward declarations to ...
	* include/abg-fwd.h: ... here.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_type_through_scopes): Introduce this to later replace the
	overload of lookup_type_in_translation_unit that takes a list of
	strings.
	(lookup_type_in_scope): Return a type_base_sptr, not a
	decl_base_sptr.
	* src/abg-ir.cc (lookup_type_in_scope, lookup_node_in_scope)
	(lookup_var_decl_in_scope): Adjust.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_node_in_scope): Return a type_or_decl_base_sptr.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_node_in_translation_unit): Return a
	type_or_decl_base_sptr.
	(lookup_type_through_scopes): Replace
	lookup_type_in_translation_unit.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:32 +01:00
Dodji Seketeli
5ed0e40bfd Bug 20887 - Show relative change of offsets
Until now, an offset change is reported by showing the old and new
offsets of the data member that changed.

This patch adds the string "(by +N bits)" with 'N' being the number of
bits by which the offset of the data member was increased, or "(by -N
bits) if the offset of the data member was decreased of N bits.

The patch also emits a string that says "size hasn't changed" if the
size of the structure did not change.

This can be disabled by a new --no-show-relative-offset-changes
option.

	* doc/manuals/abidiff.rst: Document the new
	--no-show-relative-offset-changes.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-comparison.h
	(diff_context::show_relative_offset_changes): New accessors.
	* include/abg-ir.h ({set,get}_data_member_offset): Return uint64_t
	instead of the less portable size_t.
	* src/abg-comparison.cc
	(diff_context::priv::show_relative_offset_changes_): New data
	member.
	(dif_context::show_relative_offset_changes): Define accessor.
	(maybe_show_relative_offset_change): Define new function.
	(represent): In the overload for var_diff, call the new
	maybe_show_relative_offset_change.
	(report_size_and_alignment_changes):  If the size of the type
	didn't change then say it now.
	* src/abg-ir.cc (set_data_member_offset, get_data_member_offset):
	Take or return a uint64_t instead of a size_t.
	* tools/abidiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Display help string for the new
	--no-show-relative-offset-changes.
	(parse_command_line): Parse the new
	--no-show-relative-offset-changes options.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.n
	* tools/abipkgdiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Add help string for the new
	--no-show-relative-offset-changes option.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.
	(parse_command_line): Parse the new command line option.
	* tests/data/test-diff-dwarf/test40-report-0.txt: Add new
	reference output.
	* tests/data/test-diff-dwarf/test40-v0.c: Source code of the first
	test binary.
	* tests/data/test-diff-dwarf/test40-v1.c: Source code of the
	second test binay.
	* tests/data/test-diff-dwarf/libtest40-v0.so: New first test binary.
	* tests/data/test-diff-dwarf/libtest40-v1.so: New second test binary.
	* tests/test-diff-dwarf.cc (in_out_spec): Add the new test
	binaries above to the set of binaries that are compared.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/data/test-abicompat/test7-fn-changed-report-0.txt: Adjust.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Likewise.
	* tests/data/test-abidiff/test-enum0-report.txt: Likewise.
	* tests/data/test-abidiff/test-enum1-report.txt: Likewise.
	* tests/data/test-abidiff/test-struct1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test0-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test10-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test11-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test13-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test15-enum-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test27-local-base-diff-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test4-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test6-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test8-report.txt: Likewise.
	* tests/data/test-diff-filter/test0-report.txt: Likewise.
	* tests/data/test-diff-filter/test01-report.txt: Likewise.
	* tests/data/test-diff-filter/test1-report.txt: Likewise.
	* tests/data/test-diff-filter/test13-report.txt: Likewise.
	* tests/data/test-diff-filter/test16-report-2.txt: Likewise.
	* tests/data/test-diff-filter/test16-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-0-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-1-report.txt: Likewise.
	* tests/data/test-diff-filter/test18-report.txt: Likewise.
	* tests/data/test-diff-filter/test19-enum-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test2-report.txt: Likewise.
	* tests/data/test-diff-filter/test23-redundant-fn-parm-change-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test24-compatible-vars-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-0.t:
	Likewise.xt
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-2.txt:
	Likewise.
	* tests/data/test-diff-filter/test29-finer-redundancy-marking-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test3-report.txt: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test10-changed-parm-c-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test2-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test30-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-8.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-02 21:29:28 +01:00
Dodji Seketeli
72f50a16ce Very light speed improvements
When comparing of two kernel trees showed that for huge changesets
involving highly recursive types, leaf functions used by the
categorization code dominate the performance profile.

This patch introduces some changes that help gain around 30 seconds
(out of 14 minutes) on a non-optimized build, when comparing 4.7 nd
4.8 fedora kernels (between fedora 24 and 26).

	* include/abg-comp-filter.h (has_harmless_name_change): Pass smart
	pointers by reference.
	* src/abg-comp-filter.cc (access_changed)
	(function_name_changed_but_not_symbol)
	(non_static_data_member_type_size_changed)
	(static_data_member_type_size_changed, is_compatible_change)
	(decl_name_changed, has_harmless_name_change):  Pass smart
	pointers by reference.
	* include/abg-ir.h (decl_base::set_context_rel): Take a bare
	pointer, not a smart pointer.
	* src/abg-ir.cc (decl_base::priv::context_): Make this data member
	be a naked pointer, not a smart pointer.
	(decl_base::priv::priv): Initialize it.
	(decl_base::priv::~priv): New constructor.
	(decl_base::{get_context_rel, set_scope}): Adjust.
	(class_decl::method_decl::{method_decl, set_scope}): Likewise.
	(equals): In the overload for var_decl, compare the type of the
	var first as that might be faster (to detect var_decls with
	different types) in the general case where types are
	canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 17:08:19 +01:00
Dodji Seketeli
e861bd3368 Introduce on-the-fly type canonicalization
During canonicalization of a type T, when T is structurally compared
to an already canonicalized type C, it can happen that
non-canonicalized sub-types of T are structurally compared again and
again to canonicalized sub-types of C.

This patch introduces a new optimization or those cases: on-the-fly
type canonicalized.

That means, if a not-yet-canonicalized sub-type S of the type T being
canonicalized structurally compares equal to a canonicalized sub-type,
then the canonical type of S is said to be the canonical type of the
canonicalized sub-type.  So sub-type S is canonicalized, on-the-fly,
during canonicalization of type T.

This considerably speeds up the canonicalization process while doing
"abidiff vmlinux vmlinux".  It goes from taking forever to taking 45
seconds on a non-optimized build.

	* include/abg-ir.h (environment::do_on_the_fly_canonicalization):
	Declare new member functions.
	({type_base, function_type}::priv_): Make this public so that
	static non-member functions defined in abg-ir.cc can access it.
	* src/abg-ir.cc
	(environment::priv::do_on_the_fly_canonicalization_): New data
	member.
	(environment::priv::priv): Initialize it.
	(environment::do_on_the_fly_canonicalization): Define new member
	functions.
	(type_base::get_canonical_type_for): Trigger on-the-fly
	canonicalization during comparison of the type being canonicalized
	and an already canonicalized type.
	(types_are_being_compared, maybe_propagate_canonical_type): Define
	new static functions.
	(equals): In overloads for class_decl and function_type, call
	maybe_propagate_canonical_type when the two types compare equal.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 17:07:28 +01:00
Dodji Seketeli
bd3fe4c748 Fix pretty representation of array types
It turned out we were wrongly emitting the pretty representation of
array types in two cases:

  1/ in case of qualified array types: a const array of string type
  was being pretty-represented as: "const string[]" instead of
  "string[] const".

  2/ in case of array with an empty sub-range DIE; that is a sub-range
  DIE with no attribute at all.  For instance an array of char with an
  empty sub-range DIE was being represented as: "char", instead of
  "char[]".

This patch fixes 1 and 2.  It also updates numerous test reference
output files.

	* include/abg-ir.h (array_type_def::is_infinite): Fix indentation.
	* src/abg-ir.cc (qualified_type_def::build_name): An empty set of
	sub-ranges for a vector is represented by "[]".
	(array_type_def::is_infinite): If a vector has no sub-range, that
	means it has an infinite size.  Adjust comment.
	* tests/data/test-diff-filter/test33-report-0.txt: 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/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/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:51:19 +01:00
Dodji Seketeli
3981244c9d Support naming typedef and use them to speed up type canonicalization
There is a common C idiom in which an anonymous struct is named using
a typedef:

    typedef struct {int member;} anonymous_struct_type;

The typedef name "anonymous_struct_type" becomes the name of the
otherwise anonymous struct.  That is what a naming typedef is.

So, the nice thing about naming typedefs is that an anonymous class
type suddenly becomes non anymous.  So that type becomes eligible to
the ODR-based optimization during type canonicalization.  That speeds
up type canonicalization, at least for 'abidw'.

This patch represents naming typedefs for class_decl types in the
internal representation.  The patch also changes the meaning of an
anonymous class.  Whenever such a class becomes named by a typedef,
the class is not considered anonymous anymore, at least for the
purpose of type canonicalization.

	* include/abg-ir.h (typedef_decl_wptr): New typedef.
	(class_decl::{g,s}et_naming_typedef): Declare new member
	functions.
	* src/abg-dwarf-reader.cc (build_typedef_type): When the
	underlying type of a typedef is an anonymous class, the class type
	is said to have a naming typedef.
	* src/abg-ir.cc (is_anonymous_type):  An anonymous class that has
	a naming typedef is said to not be anonymous anymore.
	(class_decl::priv::naming_typedef): New data member.
	(class_decl::{g,s}et_naming_typedef): Define new member functions.
	(class_decl::get_pretty_representation): When called for internal
	purposes (e.g, for type canonicalization) compute the pretty
	representation of the class by using its typedef name, when class
	is anonymous and has a naming typedef.
	* src/abg-reader.cc (build_class_decl): Read the new
	"naming-typedef-id" attribute.
	* src/abg-writer.cc (write_naming_typedef): New function.
	(write_class_decl_opening_tag): Use the new write_naming_typedef
	function.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:44:06 +01:00
Dodji Seketeli
cfaa7d42b6 Implement de-duplication for types and decls at DWARF loading time
Many types and decls are redefined in every translation unit that make
up an ELF binary.  This patch detects that a DIE represents a type or
decl that has already been defined in the current corpus and so will
not create a new internal representation for it.

The patch defines facilities to build the pretty representation of a
type or decl.  It's by looking at the pretty representation of a DIE
that the patch detects that a different DIE has already defined the
same type or decl.

The patch also fixes detection of the const-ness of member functions
as there were many cases where const member functions were not
recognized as const.  This fix makes it so that the pretty
representation of the DIE of said member functions match the pretty
representation of their internal representation, as far as the
const-ness is concerned.

One bit of infrastructure change that is used by the const-ness fix is
that method_type now carries const-ness.  So a method_decl that has a
const method_type is going to be const itself.

	* include/abg-ir.h (method_type::priv_): Introduce new pimpl
	pointer here.
	(method_type::class_type_): Move this into the pimpl idiom.
	(method_type::method_type): Take a new is_const flag.
	(method_type::get_class_type): Make this method out-of-line.
	(method_type::{s,g}et_is_const): Declare new member functions.
	(get_method_type_name): Declare this function as a friend of
	the method_type type.
	* src/abg-dwarf-reader.cc: Include the new abg-ir-priv.h and
	abg-corpus-priv.h.
	(typedef die_tu_map_type): Fix comment.
	(typedef die_istring_map_type): New typedef.
	(class read_context::die_source_dependant_container_set): New
	class template.
	(read_context::{die_qualified_name_maps_, die_pretty_repr_maps_,
	die_pretty_type_repr_maps_}): Define new data members.
	(read_context::{get_die_qualified_name, get_die_qualified_name,
	get_die_qualified_type_name, get_die_pretty_type_representation,
	get_die_pretty_representation, lookup_type_artifact_from_die,
	lookup_artifact_from_die, lookup_artifact_from_die_representation,
	associate_die_to_artifact_by_repr,
	associate_die_to_artifact_by_repr_internal,
	lookup_type_from_die}): Define new member functions.
	(read_context::lookup_type_from_die_offset): Fix comment.
	(get_parent_die, get_scope_die, die_is_decl)
	(die_is_namespace, die_is_unspecified, die_is_void_type)
	(die_is_pointer_type, die_is_reference_type)
	(die_is_pointer_or_reference_type, die_is_class_type)
	(die_has_object_pointer, die_this_pointer_from_object_pointer)
	(die_this_pointer_is_const, is_decl_tag)
	(die_object_pointer_is_for_const_method, die_is_at_class_scope)
	(die_name, die_qualified_type_name, die_qualified_decl_name)
	(die_qualified_name, die_qualified_type_name_empty)
	(die_return_and_parm_names_from_fn_type_die)
	(die_function_signature, die_peel_qual_ptr)
	(die_function_type_is_method_type, die_pretty_print_type)
	(die_pretty_print_decl, die_pretty_print)
	(build_subranges_from_array_type_die)
	(build_or_get_fn_decl_if_not_suppressed)
	(lookup_class_or_typedef_type)
	(lookup_class_typedef_or_enum_type_from_corpus)
	(is_function_for_die_a_member_of_class)
	(add_or_update_member_function): Define new static functions.
	(read_context::associate_die_to_decl): Call
	associate_die_to_artifact_by_repr.
	(read_context::{associate_die_to_type,
	schedule_type_for_late_canonicalization}): Take just one "die"
	parameter rather than taking a die offset and a die source; adjust
	accordingly.
	(maybe_canonicalize_type): Likewise.
	(finish_member_function_reading): Take a const reference to
	function_decl_sptr.
	(die_loc_and_name): Use the new die_name function.
	(die_is_type): Rename is_type_die into this.
	(build_type_decl): Take a new "where_offset" parameter.  Adjust.
	If a type of the same name as the one for the current DIE is is
	already present, do not create a new type; just return the
	already-existing one.
	(build_enum_type): Take a new "where_offset" parameter.  Adjust.
	(finish_member_function_reading): Pass two smart pointers by const
	reference.  Assert that the type of the member function is a
	method_type.  Some light cleanups.
	(add_or_update_class_type): Rename build_class_type_and_add_to_ir.
	If a DIE defining the same class has already been seen, then
	return that class; don't construct any other internal
	representation for the same class.  Better handle the updating of
	member data and functions.  Do not duplicate member types.
	(build_qualified_type, build_pointer_type_def)
	(build_reference_type): Support de-duplication here.
	(build_function_type): Likewise.  Support detection and building
	of method type.  This also supports *const* method type building.
	(build_array_type): Use the new
	build_subranges_from_array_type_die.
	(build_type_decl): Cleanup logic.
	(build_or_get_var_decl_if_not_suppressed): Renamed
	build_var_decl_if_not_suppressed into this.  Perform
	de-duplication for data members.
	(build_function_decl): Don't set an empty source location.  If the
	function type cannot be constructed, do not construct the function
	decl either.  Adjust.
	(build_ir_node_from_die): Adjust.  When building a function for a
	DW_TAG_subroutine_type DIE, use the new
	build_or_get_fn_decl_if_not_suppressed.
	* src/abg-ir.cc (translation_unit::bind_function_type_life_time):
	Fix comment.
	(strip_typedef): Adjust.
	(qualified_type_def::build_name): Set the prefix name of a the
	name of a noop qualifier to "noop-qual", just like what is done in
	the new die_qualified_name function.
	(struct method_type::priv): New priv type for the method_type
	class.
	(method_type::method_type): Take a new 'is_const' parameter.
	Adjust as the method_type is now pimpl'ed.
	(method_type::{get_class_type, set_is_const, get_is_const}):
	Define new member functions.
	(function_decl::get_pretty_representation_of_declarator): Better
	detecter of const-ness.
	(class_decl::insert_member_decl):  Better setting of the
	const-ness.
	(class_decl::method_decl::method_decl): Adjust.  Deduce the
	const-ness of the method_decl from the const-ness of its
	method_type.
	(copy_member_function): Adjust.
	(set_member_is_static): Do not assume a non-nil scope anymore
	because member_decl can now be scope-less, at least for a little
	while.
	* src/abg-reader.cc (push_decl_to_current_scope): Adjust.
	(build_function_decl): Style adjustment.  Adjust for method_type
	const-ness changes.
	(build_function_type): Likewise.  Also, support the new
	"method-class-id" property that flags a function type as being a
	method type.
	* src/abg-writer.cc (write_function_decl): Style fixes.
	(write_function_type): Likewise.  Emit a new "method-class-id"
	property for function type that is actually a method type.  That
	property's value is the id of the class of the method type.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Adjust.
	* tests/data/test-diff-dwarf/test0-report.txt: Adjust.
	* tests/data/test-diff-filter/test0-report.txt: Adjust.
	* tests/data/test-diff-filter/test01-report.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Adjust.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: 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/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/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/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>
2016-11-29 16:16:56 +01:00
Dodji Seketeli
ccdc44b3eb Setup per-corpus type maps indexed by type names
This patch creates per-corpus maps that associate, for a certain kind
of type, the fully qualified name of the type to the type.

So there is a map for class_decl, one for enum_type_decl, one for
type_decl, etc.

These maps are populated when a new type is added to its scope.

The patch defines overloads of the function
maybe_update_types_lookup_map() that update the right map, depending
on the kind of type we are looking at.

Note that there also is a map in each class that associates a
signature string to a member functions.  This is so that member
functions of a given class can be looked up by signature.

This is so that looking up a type becomes now much faster than having
to walk all the translation units of a corpus to find one.

Note that this patch is specifically part of the series of patches
that implements types and declarations de-duplication while reading
DWARF information.

The patch might slightly change the output of abi serialization or
comparison so it needs some adjustments of some test reference files.
That adjustment is not done here.  Rather, it's done at once in
another patch of the set.

	* include/abg-corpus.h (corpus::priv_): Make this public so that
	functions from outside of the class can access it.  These
	functions are meant to be used only by code that is *inside*
	libabigail.so, though.
	* src/abg-corpus-priv.h: New file.
	* src/abg-corpus.cc: Include the new abg-corpus-priv.h file.
	(struct regex_t_deleter): Move this to abg-sptr-utils.h.
	(build_sptr<regex_t>): Move the declaration of this function
	template specialization to abg-sptr-utils.h and its definition to
	abg-sptr-utils.cc.
	(typedef regex_t_sptrs_type, typedef str_var_ptr_map_type)
	(struct corpus::exported_decls_builder::priv, struct
	corpus::priv): Move these declarations to the new
	abg-corpus-priv.h.
	(maybe_update_types_lookup_map): Define overloads of this (one per
	kind of type).
	(lookup_{basic, class, enum, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define new functions.
	* include/abg-ir.h (typedef istring_type_base_wptr_map_type)
	(typedef istring_type_or_decl_base_sptr_map_type): Declare new
	typedefs.
	(class_decl::find_member_function_from_signature): Declare new
	member function.
	* src/abg-ir.cc: Include the new abg-corpus-priv.h file.
	(maybe_update_types_lookup_map): Remove this initial function.
	There are now new overloads in abg-corpus.cc for it.
	(scope_decl::{add_member_decl, insert_member_decl}): Adjust.
	(class_decl::{set_is_declaration_only, find_member_function,
	add_member_function}): Adjust.
	(class_decl::find_member_function_from_signature): Define new
	member function.
	* include/abg-sptr-utils.h (struct regex_t_deleter): Declare new
	type.
	(build_sptr<regex_t>): New build function template
	specializations.
	* src/abg-sptr-utils.cc: New file.
	* src/Makefile.am: Add src/abg-sptr-utils.cc and
	src/abg-corpus-priv.h to the build system.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:43 +01:00
Dodji Seketeli
1b94d60780 Allow pretty printing function decls for internal purposes
It appears that function_decl::get_pretty_representation doesn't make
the difference between internal and non-internal purposes.  This patch
fixes that by making the helper
get_pretty_representation_of_declarator() take an "internal" flag and
calls that.

	* include/abg-ir.h
	(function_decl::get_pretty_representation_of_declarator): Take an
	"internal" flag.
	* src/abg-ir.cc
	(function_decl::get_pretty_representation_of_declarator): Take an
	"internal" flag.
	(function_decl::get_pretty_representation): Pass the "internal"
	flag to the function
	function_decl::get_pretty_representation_of_declarator.
	(function_decl::parameter::get_type_name):  Better handle variadic
	parameter type.
	(function_decl::parameter::get_type_pretty_representation):
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:31 +01:00
Dodji Seketeli
e7c920edbc Support union types
This patch makes Libabigail understand C and C++ union types.  It
defines a new class abigail::ir::union_decl to represent the
declaration of a union type.  It also defines a new type
abigail::comparison::union_diff to represent the changes between two
union types.  The patch then adds facilities to read union types from
DWARF and abixml and also to write union types into the abixml format.

As union types and class types have a lot in common, the patch tries
very hard to share code between the abigail::ir::class_decl and
abigail::ir::union_decl.  To do so, a new class
abigail::ir::class_or_union is created.  It's the base class for both
abigai::ir::class_decl and abigail::ir::union_decl.  Its data members
and methods represent the set of data and behaviour that are common to
classes and unions.  A lot of code and data that were initially in
abigail::ir::class_decl got moved into the new
abigail::ir::class_or_union class.

Similary, the patch creates a new class
abigail::comparison::class_or_union_diff that is a base class for both
the existing class abigail::comparison::class_diff and the newly
created class abigail::comparison::union_diff.  The new class
abigail::comparison::class_or_union_diff contains data and behaviour
that are common to both union_diff and class_diff and that were
previously in class_diff.

The rest of the patch is mostly adjustment so that code that was
supposed to work with class class_decl only can now work with class
class_or_union when it makes sense.  Similarly for class_diff and
class_or_union_diff.

The patch adds regression tests into the test suite and adjust many
existing tests involving binaries that contain union types; the
reference output of those tests now take union types into account.

	* include/abg-fwd.h (class_or_union, union_decl): Forward-declare
	new types.
	(is_class_or_union_type, is_union_type): Declare new functions.
	* include/abg-ir.h (method_type::class_type_): Make this be of
	class_or_union_wptr type.
	(method_type::method_type): Make the class_type parameter be of
	class_or_union_wptr type.
	(method_type::{g,s}et_class_type): Take or return a
	class_or_union_sptr.
	(member_base, method_decl, member_function_template)
	(member_class_template, member_base::hash)
	(member_function_template::hash, member_class_template::hash):
	Take these class types out of the class_decl scope.
	(is_method_decl): Adjust.
	(operator==, opertor!=): Adjust overloads for
	member_function_template_sptr and member_class_template_sptr.
	(class class_or_union): Declare new type.
	(class class_decl): Make this class inherit class_or_union class.
	(class_decl::{add_member_decl, insert_member_decl,
	remove_member_decl, set_size_in_bits, get_size_in_bits,
	get_alignment_in_bits, set_alignment_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	insert_member_type, add_member_type, remove_member_type,
	get_member_type, find_member_type, add_data_member,
	get_data_members, find_data_member, get_non_static_data_members,
	add_member_function, get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	to the parent class class_or_union.
	(copy_member_function, equals): Add overloads for class_or_union.
	(struct class_or_union::hash): Declare new type.
	(class union_decl): Declare new type.
	(equals, copy_member_function): New overloads for class union_decl
	type.
	(ir_node_visitor::visit): Add new overloads for union_decl* and
	class_or_union*.
	* src/abg-ir.cc (get_member_function_is_ctor)
	(set_member_function_is_ctor, get_member_function_is_dtor)
	(set_member_function_is_dtor, get_member_function_is_const)
	(set_member_function_is_const, get_member_function_vtable_offset)
	(set_member_function_vtable_offset)
	(get_member_function_is_virtual, set_member_function_is_virtual)
	(maybe_update_types_lookup_map, get_location)
	(get_method_type_name, is_at_global_scope, is_at_class_scope):
	Adjust.
	(is_class_or_union_type, is_union_type): Define new functions.
	(type_base::get_canonical_type_for, maybe_adjust_canonical_type)
	(method_type::method_type, method_type::set_class_type)
	(function_decl::get_pretty_representation)
	(function_decl::get_first_non_implicit_parm)
	(function_decl::clone): Adjust.
	(equals): Adjust the overload for function_type.
	(struct class_or_union::priv): Define new type.
	(class::priv::{declaration_, definition_of_declaration_,
	member_types_, data_members_, non_static_data_members_,
	member_functions_, mem_fns_map_, member_function_templates_,
	member_class_templates_, is_declaration_only_}): Move these data
	member into class_or_union::priv.
	(class_priv::{mark_as_being_compared, unmark_as_being_compared,
	comparison_started}): Moved these member functions to
	class_or_union::priv.
	(class_or_union::{class_or_union, traverse, ~class_or_union,
	add_member_decl, remove_member_decl, insert_member_type,
	add_member_type, get_size_in_bits, remove_member_type,
	get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates,
	has_no_member, insert_member_decl, operator==}): Define new member
	functions.
	(class_decl::{add_member_decl, remove_member_decl,
	insert_member_type, add_member_type, get_size_in_bits,
	remove_member_type, get_alignment_in_bits, set_alignment_in_bits,
	set_size_in_bits, get_is_declaration_only,
	set_is_declaration_only, set_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	member functions into class_or_union.
	(class_decl::{class_decl, get_definition_of_declaration,
	insert_member_decl, add_member_function, has_no_base_nor_member}):
	Adjust.
	(equals, copy_member_function): Define new overloads for
	class_or_union.
	(equals): Adjust the overload for class_decl.
	(method_decl::{method_decl, set_linkage_name, ~method_decl,
	get_type, set_scope}): Remove from the class_decl scope.
	(member_base::operator==, member_function_template::operator==):
	Likewise.
	(member_function_template::traverse)
	(member_class_template::operator==)
	(member_class_template::traverse): Likewise.
	(operator==, operator!=): Adjust the overlod for
	member_function_template_sptr.
	(is_method_decl, fixup_virtual_member_function)
	(set_member_is_static): Adjust.
	(virtual_member_function_less_than::operator()): Likewise.
	(union_decl::{union_decl, get_pretty_representation, operator==,
	traverse}): Define new member functions.
	(equals, copy_member_function): Define new overloads for
	union_decl.
	(hash_type_or_decl): Adjust.
	(ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads
	for class_or_union* and union_decl*.
	* include/abg-comparison.h (changed_member_function_sptr)
	(string_member_function_sptr_map): Adjust these typedefs.
	(class class_or_union_diff): Declare new type.
	(class_diff): Adjust to make this inherit the new
	class_or_union_diff type.
	(class_diff::{get_priv, member_types_changes,
	data_members_changes, inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These member functions got moved
	into -- and shared with -- class_or_union_diff class.
	(class union_diff): Declare new type.
	(typedef union_diff_sptr): New typedef.
	(compute_diff): New overload for union_diff
	(is_class_diff, is_union_diff): Declare new functions.
	* src/abg-comparison.cc (is_class_diff, is_union_diff): Define new
	functions.
	(compute_diff_for_types): Support union_decl.
	(represent):  Adjust.
	(represent_data_member): Do not show offset information for data
	members of unions as all union data members are at offset 0.
	(struct class_or_union_diff::priv): New type.
	(class_or_union_diff::priv::{member_type_has_changed,
	subtype_changed_dm, member_class_tmpl_has_changed,
	get_deleted_non_static_data_members_number,
	get_inserted_non_static_data_members_number,
	count_filtered_subtype_changed_dm, count_filtered_changed_dm,
	count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns,
	count_filtered_deleted_mem_fns}): Define new member functions.
	(class_or_union_diff::{class_or_union_diff, finish_diff_type,
	lookup_tables_empty, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, get_priv,
	~class_or_union_diff, first_class_or_union, second_class_or_union,
	member_types_changes, member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members, member_fns_changes,
	changed_member_fns, member_fns_changes, inserted_member_fns,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes, member_class_tmpls_changes,
	has_changes, has_local_changes, report, chain_into_hierarchy}):
	Define new member functions.
	(class_diff::priv::{member_types_changes_, data_members_changes,
	member_fn_tmpls_changes_, member_class_tmpls_changes_,
	deleted_member_types_, inserted_member_types_,
	changed_member_types_, sorted_changed_member_types_,
	deleted_data_members_, deleted_dm_by_offset_,
	inserted_data_members_, inserted_dm_by_offset_,
	subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_,
	sorted_changed_dm_, deleted_member_functions_,
	inserted_member_functions_, changed_member_functions_,
	sorted_changed_member_functions_, deleted_member_class_tmpls_,
	inserted_member_class_tmpls_, changed_member_class_tmpls_,
	sorted_changed_member_class_tmpls_}): Move these data members into
	class_or_union_diff::priv.
	(class_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populate}): Adjust.
	(class_diff::allocate_priv_data): Define new function.
	(class_diff::priv::{count_filtered_changed_mem_fns,
	count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns,
	chain_into_hierarchy, class_diff}): Likewise.
	(class_diff::{member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These are deleted as they got moved
	to class_or_union_diff.
	(class_diff::report): Adjust.
	(union_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, union_diff,
	finish_diff_type, first_union_decl, second_union_decl,
	get_pretty_representation, report}): Define new functions.
	(compute_diff): Define an overload for union_decl_sptr.
	(function_decl_diff::report): Adjust.
	(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
	Adjust.
	(corpus_diff::report): Adjust.
	* src/abg-hash.cc (member_base:#️⃣:operator)
	(member_function_template:#️⃣:operator)
	(member_class_template:#️⃣:operator): Move these out of the
	class_decl scope.
	(class_or_union:#️⃣:operator): Define new member function.
	(class_decl:#️⃣:operator): Adjust.
	(type_base::dynamic_hash::operator): Support hashing of
	union_decl.  Adjust.
	* src/abg-suppression.cc (type_suppression::suppresses_diff):
	Adjust.
	* src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type):
	Define new typedef.
	(read_context::{die_wip_classes_map_,
	alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_):
	Make these data member have type die_class_or_union_map_type.
	(read_context::{lookup_type_from_die_offset, die_wip_classes_map,
	is_wip_class_die_offset, resolve_declaration_only_classes}):
	Adjust.
	(finish_member_function_reading, build_class_type_and_add_to_ir)
	(build_function_type, build_function_decl, build_reference_type)
	(type_is_suppressed, build_function_decl)
	(maybe_canonicalize_type, maybe_set_member_type_access_specifier):
	Adjust.
	(build_union_type_and_add_to_ir): Define new static function.
	(build_ir_node_from_die): Support DW_TAG_union_type DIE tag.
	* src/abg-reader.cc (handle_element_node): Handle union_decl.
	(build_function_decl, build_function_decl_if_not_suppressed):
	Adjust.
	(build_union_decl_if_not_suppressed, build_union_decl)
	(handle_union_decl): Define new functions.
	(build_class_decl): Adjust.
	* src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust.
	(write_decl): Adjust. Support writting union_decl type.
p	(write_class_decl_opening_tag, write_class_decl): Adjust.  Call
	the new write_class_or_union_is_declaration_only.
	(write_union_decl_opening_tag, write_union_decl): Define new
	static functions.
	(write_member_tpe): Support writting union decl.
	* tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this
	union type support.
	* tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input.
	* tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for
	new test input.
	* tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Update test reference.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/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/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>
2016-11-22 16:22:25 +01:00
Dodji Seketeli
f9ed75b8c4 Support empty properties in INI files
The ini file parser doesn't support parsing properties with no value.
This patch adds that feature, as it turned out to be a pre-requisite
for reading Linux Kernel ABI whitelist files.

	* include/abg-ini.h (simple_property::simple_property): Add a new
	constructor for empty values.
	(simple_property::has_empty_value): Declare new member function.
	* src/abg-ini.cc (simple_property::{simple_property,
	has_empty_value}): Define new member functions.
	(read_context::read_property): Support reading a property with no
	value.
	(write_property_value, write_property): Support writting a
	property with empty value.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-10 14:09:51 +01:00
Dodji Seketeli
b96ecbc065 Rename config::property_vector into config::properties_type
This renaming makes the code looks more consistent.

	* include/abg-ini.h (config::properties_type): Rename the typedef
	config::property_vector into this.
	(config::section::{section, get_properties, set_properties}):
	Adjust.
	* src/abg-ini.cc (config::section::priv::properties_): Adjust the
	name of its type.
	(config::section::{section, get_properties, set_properties,
	find_property}): Adjust.
	(write_section): Adjust.
	* src/abg-suppression.cc (read_function_suppression): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-10 14:09:50 +01:00
Dodji Seketeli
9224f40c52 Apply harmless and harmful filters in one pass
When comparing linux kernels with lots of changes, walking changes
twice just to apply harmless and harmful change filters was dominating
the performance profile.

This patch performs the harmless and harmful filtering in one pass.
This makes the overall comparison go from 15 minutes to 10 minutes
when comparing a 4.7 kernel from fedora24 and a 4.8 kernel from
fedora26.

	* include/abg-comp-filter.h (class harmless_harmful_filter):
	Decalre new class.
	(typedef harmless_harmful_filter_sptr): Declare new typedef.
	(class harmless_filter, class harmful_filter): Remove these class
	declarations.
	(typedef harmful_filter_sptr, harmless_filter_sptr): Remove these
	typedefs.
	* src/abg-comp-filter.cc (categorize_harmless_diff_node)
	(categorize_harmful_diff_node): Define new static functions.
	({harmless, harmful}_filter::{visit, visit_end}): Remove these
	member functions.
	(harmless_harmful_filter::{visit, visit_end}): Define new member
	functions.
	* src/abg-comparison.cc (diff_context::diff_context): Register the
	new harmless_harmful_filter, and remove the premier
	harmless_filter and harmful_filter.

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

	# Please enter the commit message for your changes. Lines starting
	# with '#' will be ignored, and an empty message aborts the
	commit.  # On branch kabidiff-dedup # Changes to be committed: #
	(use "git reset HEAD <file>..." to unstage) # # modified:
	include/abg-comp-filter.h # modified: src/abg-comp-filter.cc #
	modified: src/abg-comparison.cc # # Untracked files: # (use "git
	add <file>..." to include in what will be committed) # # diff.txt
	# prtests/ # tests/data/test-read-dwarf/libtest23.so.abi.conflict

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-10 14:09:50 +01:00
Dodji Seketeli
ff0b07e711 Factorize out string representation of array_type_def::subrange_type
As we are going to need to print names of array types from DIEs
directly, we'll need to represent names of subranges.

This patch factorizes the string representation of the
array_type_def::subrange_type type.

	* src/abg-ir.cc (array_type_def::subrange_type::{as_string,
	vector_as_string}): Define methods.
	(array_type_def::get_subrange_representation): Use the new
	vector_as_string method.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-03 15:13:38 +01:00
Dodji Seketeli
6c100a88b5 Cleanup void and variadic parameter type interfaces
While working on something else, it appeared that renaming
abigail::environment::get_void_type_decl() to
abigail::environment::get_void_type() and
abigail::environment::get_variadic_parameter_type_decl() to
abigail::environment::get_variadic_parameter_type() would be an
improvement.

This patch implements that.

	* include/abg-ir.h (environment::{get_void_type,
	get_variadic_parameter_type}): Renamed get_void_type_decl and
	get_variadic_parameter_type_decl to these.
	(environment::is_void_type): Remove the overload that takes a bare
	pointer.
	(environment::is_variadic_parameter_type): Declare new member
	function.
	* src/abg-ir.cc (environment::void_type_): Renamed the data member
	void_type_decl_ into this.
	(environment::variadic_marker_type_): Renamed the data member
	variadic_marker_type_decl_ into this.
	(environment::{get_void_type, get_variadic_parameter_type}):
	Renamed get_void_type_decl and get_variadic_parameter_type_decl to
	these.
	(environment::is_void_type): Take a smart pointer now.
	(environment::is_variadic_parameter_type): Define new member
	function.
	(synthesize_function_type_from_translation_unit): Adjust.
	(function_decl::parameter::get_pretty_representation): Likewise.
	* src/abg-comparison.cc (is_diff_of_variadic_parameter_type):
	Adjust.
	* src/abg-dwarf-reader.cc (build_function_type)
	(build_ir_node_for_void_type): Likewise.
	* src/abg-reader.cc (build_function_parameter)
	(build_function_decl, build_function_type): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-03 15:12:46 +01:00
Dodji Seketeli
c86ffddab7 Cleanup some entry points in abg-fwd.h
While looking at something else I came accross some interface cleanup
opportunities, as usual.  This patch honours some of those
opportunities.

	* include/abg-fwd.h (add_decl_to_scope): Pass the scope smart
	pointer by reference.
	(is_member_type): pass the type smart pointer by reference.
	(is_function_decl, is_pointer_type, is_reference_type)
	(is_qualified_type, is_function_type, is_method_type)
	(is_array_type): Take a type_or_decl base pointer, rather than
	either a decl_base or type_base pointer.
	* include/abg-ir.h (translation_unit::set_corpus): Take a pointer
	to non-const corpus.
	(translation_unit::get_corpus): Add a non-const overload.
	(type_or_decl_base::get_corpus): Likewise.
	(type_or_decl_base::set_translation_unit): Take a pointer to
	non-corpus translation_unit.
	(type_or_decl_base::get_translation_unit): Add a non-const
	overload.
	(scope_decl::{add_member_decl, insert_member_decl}): Pass the
	member smart pointer by reference.
	(scope_decl::remove_member_decl): Take a non-const smart pointer.
	(class_decl::add_member_decl): Pass the decl smart pointer by
	reference.
	(is_method_decl): Take pointer or reference to type_or_decl_base
	rather than function_decl.
	* src/abg-ir.cc (translation_unit::priv::corpus): Make this a
	pointer to non-const corpus.
	(translation_unit::set_corpus): Take a pointer to non-const
	corpus.
	(translation_unit::get_corpus): Add a non-const overload.
	(translation_unit::get_global_scope): Adjust.
	(translation_unit::bind_function_type_life_time): Adjust.
	(type_or_decl_base::translation_unit): Make this a pointer to
	non-const translation_unit.
	(type_or_decl_base::get_corpus): Likewise.
	(type_or_decl_base::set_translation_unit): Take a pointer to
	non-corpus translation_unit.
	(type_or_decl_base::get_translation_unit): Add a non-const
	overload.
	(is_member_type): pass the type smart pointer by reference.
	(scope_decl::{add_member_decl, insert_member_decl}): Take a
	reference to the member decl smart pointer.  Adjust.
	(class_decl::add_member_decl): Likewise.
	(scope_decl::remove_member_decl): Take a non-const smart pointer.
	(add_decl_to_scope): Pass the scope smart pointer by reference.
	(is_decl, is_function_decl, is_pointer_type, is_reference_type)
	(is_qualified_type, is_function_type, is_method_type)
	(is_method_decl, is_array_type): Take a type_or_decl base pointer,
	rather than either a decl_base or type_base pointer.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-03 15:12:29 +01:00
Dodji Seketeli
31cd5d77b8 Cleanup namespace importing in abg-interned-str.h
* include/abg-interned-str.h: Inject std::tr1::shared_ptr,
	std::string and std::ostream inside the abigail namespace.
	(interned_string::{interned_string, raw, operator==, operator!=,
	operator<): Adjust.
	(operator==, operator!=, operator<<, operator+): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-10 12:57:47 +02:00
Dodji Seketeli
4324b82e99 Prevent infinite loops while comparing two function_type
While comparing two function types a given sub-type can itself have a
sub-type that *is* the same function_type as the one we are looking
at.  In that case, an infinite loop appears.

This patch detects those cases, similarly to what we do for class_decl
and avoids the eventual infinite loop.

	* include/abg-ir.h (class environment): Make class function_type
	be a friend of this class.
	(class function_type): Make the equality function for
	function_types be a friend of this class.
	* src/abg-ir.cc (environment::priv::fn_types_being_compared_): New
	data member.
	(function_type::priv::{mark_as_being_compared,
	unmark_as_being_compared, comparison_started}): Define new member
	functions.
	(equals): In the overload for function_types, if any of the the
	function_type being compared is already being compared, return
	early saying that the two function_types are equal.  This avoids

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-10 12:55:22 +02:00
Dodji Seketeli
607dbff271 Define a new interned_string_set_type typedef
In order to prepare other changes to come, this patch declares an
unordered set of abigail::interned_string.

	* include/abg-interned-str.h (interned_string_set_type): Define a new
	typedef for unordered_set<interned_string>.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-10 12:55:02 +02:00
Dodji Seketeli
98c8d61684 Drop suppressed ABI artifacts from the IR
This patch allows dropping suppressed ABI artifacts from the in-memory
internal representation right during the DWARF or abixml reading.

In practise, this means that abidw and abilint now have a
--suppressions options to give them suppression specifications.  If a
suppression specification that has the "drop" property matches an ABI
artifact (type, function or variable) then that artifact is dropped
from the internal representation.  This also applies to abidiff.

Note that now, by default, ABI artifacts (types) that are suppressed
due to the --headers-dir{1,2} option of abidiff are now also dropped
from the IR as well.  Incidentally, abidw and abilint tools now have a
--header-dir option too.

	* doc/manuals/abidw.rst: Document the new --suppressions and
	--headers-dir options off the abidw tool.
	* doc/manuals/abilint.rst: Document the new --suppressions and
	--headers-dir options on the abilint tool.
	* doc/manuals/libabigail-concepts.rst: Document the new "drop" and
	"name_not_regexp" properties on suppression directives.
	* include/abg-corpus.h (corpus::corpus): Add a default argument to
	the path parameter.
	* src/abg-suppression-priv.h: New private header file.
	* src/Makefile.am: Add the new abg-suppression-priv.h file to
	source distribution.
	* include/abg-suppression.h ({suppression_base, type_suppression,
	function_suppression, variable_suppression}::priv): Make these
	public.
	(suppression_base::{g,s}et_drops_artifact_from_ir): Declare new
	member functions.
	(type_suppression::{suppressed_type}): Likewise.
	(suppression_base::{names,sonames}_of_binaries_match): Remove
	member functions.
	(function_suppression::{get_name, set_name, get_name_regex_str,
	set_name_regex_str}): Renamed get_function_name,
	set_function_name, get_function_name_regex_str,
	set_function_name_regex_str into these.
	({variable,function}_suppression::{g,s}et_name_not_regex_str):
	Declare new member functions.
	* src/abg-suppression.cc: Include the new abg-suppression-priv.h
	private header.
	(class suppression_base::priv, class type_suppression::priv, class
	function_suppression::parameter_spec::priv, class
	function_suppression::priv, class variable_suppression::priv):
	Move these types to that new private header.
	(suppression_base::{g,s}et_drops_artifact_from_ir)
	(function_suppression::{g,s}et_name_not_regex_str)
	(variable_suppression::{g,s}et_name_not_regex_str): New member
	functions.
	(sonames_of_binaries_match): New static function, taken from
	suppression_base::sonames_of_binaries_match.
	(names_of_binaries_match): New static function, taken from
	suppression_base::names_of_binaries_match.
	(suppression_matches_type_no_name): New static function.
	(type_suppression::suppresses_type): Adjust
	(function_suppression::suppresses_function)
	(variable_suppression::suppresses_variable): Adjust.  Evaluate the
	new "name_not_regexp" property.
	(suppression_matches_type_name)
	(suppression_matches_type_location)
	(suppression_matches_type_name_or_location)
	(suppression_matches_function_name)
	(suppression_matches_function_sym_name)
	(suppression_matches_variable_name)
	(suppression_matches_variable_sym_name, suppression_matches_type):
	New functions.
	(read_type_suppression): Support the new "drop_artifacts" and
	"drop" properties.
	(read_function_suppression, read_variable_suppression): Support
	the new "drop_artifacts", "drop", and "name_not_regexp"
	properties.
	(function_suppression::{g,s}et_name): Renamed
	{g,s}et_function_name into these.
	(function_suppression::set_name_not_regex_str): Renamed
	{g,s}et_name_regex_str into this.
	(function_suppression::suppresses_function_symbol): Adjust.
	* include/abg-dwarf-reader.h (add_read_context_suppressions):
	Declare new function.
	* src/abg-dwarf-reader.cc: Use the new private
	abg-suppression-priv.h header file.
	(read_context::supprs_): New data member.
	(read_context::get_suppressions): New member function.
	(read_context::get_die_source): Make this const.
	(read_context::tu_die_imported_unit_points_map): Add a const
	overload.
	(read_context::cur_transl_unit): Renamed current_translation_unit
	unit into this;
	(read_context::cur_tu): Remove or rename into cur_transl_unit.
	(get_scope_for_die, build_translation_unit_and_add_to_ir)
	(build_enum_type, build_pointer_type_def, build_reference_type)
	(build_function_type, build_array_type, build_function_decl):
	Adjust.
	(read_context::{suppression_can_match,
	suppression_matches_function_sym_name,
	suppression_matches_function_name,
	suppression_matches_variable_sym_name,
	suppression_matches_variable_name,
	suppression_matches_type_name_or_location,
	suppression_matches_type_name}): Add member functions.
	(die_signed_constant_attribute): Remove this as dead code.
	(die_location, die_loc_and_name)
	(find_import_unit_point_between_dies)
	(find_import_unit_point_before_die, get_parent_die): Make the
	read_context& parameter be const and adjust as required.
	(build_var_decl_if_not_suppressed, function_is_suppressed)
	(variable_is_suppressed, type_is_suppressed): Define new static
	functions.
	(add_read_context_suppressions): Define new function.
	(build_class_type_and_add_to_ir): Do not add suppressed static
	data members to the IR.
	(build_ir_node_from_die): Do not add suppressed enum types, class
	types, variables or functions to the IR.  Adjust for the
	read_context::cur_tu -> read_context::cur_transl_unit rename.
	* include/abg-reader.h (read_context_sptr): Declare new type.
	(create_native_xml_read_context, read_corpus_from_input)
	(add_read_context_suppressions): Declare new functions.
	* src/abg-reader.cc: Include the new private
	abg-suppression-priv.h header file.
	(read_context::m_exported_decls_builder): Renamed
	m_exported_decls_builder_ into this.
	(read_context::get_exported_decls_builder): Adjust.
	(read_context::get_cur_scope): Make this const.
	(read_location): Take a const read_context and adjust.
	(read_corpus_from_input): Make this non-static.
	(build_namespace_decl): Don't abort if trying to add an artifact
	to the IR doesn't succeed.  It might be suppressed now.
	(read_context::{m_path, m_supprs}): New data members.
	(read_context::{g,s}et_path): New member functions.
	(read_context::{get_suppressions,
	suppression_matches_function_name, suppression_can_match,
	suppression_matches_function_name,
	suppression_matches_function_sym_name,
	suppression_matches_variable_name,
	suppression_matches_variable_sym_name,
	suppression_matches_type_name_or_location}): Likewise.
	(add_read_context_suppressions, create_native_xml_read_context)
	(read_corpus_from_native_xml): New functions.
	(build_function_decl_if_not_suppressed, function_is_suppressed)
	(type_is_suppressed, build_var_decl_if_not_suppressed)
	(variable_is_suppressed, build_enum_type_decl_if_not_suppressed)
	(build_class_decl_if_not_suppressed): New static functions.
	(build_class_decl): Add member types that are being built early,
	so that their sub-types can be evaluated for suppression.  Do not
	add suppressed static data members or suppressed member functions
	to the IR.
	(build_type): Do not add an enum type or a class type to the IR if
	they are suppressed.
	(handle_enum_type_decl): Do not add an enum type to the IR if its
	suppressed.
	(handle_var_decl): Likewise for a variable decl.
	(handle_function_decl): Likewise for a function decl.
	(handle_class_decl): Likewise for a class decl.
	* src/abg-tools-utils.cc (handle_fts_entry): Drop suppressed ABI
	from the IR.
	* tools/abidiff.cc (display_usage): Fix help strings for
	--headers-dirs{1,2}.
	(set_suppressions): New static function.
	(main): Adjust.  Release the memory used by read_context early.
	* tools/abidw.cc (options::{headers_dir, suppression_paths}):
	(display_usage): New help strings for the new --header-dir and
	--suppressions options.
	(parse_command_line): Parse the new --header-dir and
	--suppressions options.
	(maybe_check_suppression_files, set_suppressions): New static
	functions.
	(main): Use the two new functions above.  Free the memory used by
	the read context before working with the corpus.
	* tools/abilint.cc (options::suppression_paths):
	(display_usage): New help strings for the new --header-dir and
	--suppressions options.
	(parse_command_line): Parse the new --header-dir and
	--suppressions options.
	(maybe_check_suppression_files, set_suppressions): New static
	functions.
	(main): Use the two new functions above.  Free the memory used by
	the read context before working with the corpus.
	* tests/data/test-diff-suppr/test24-soname-suppr-{2,3].txt:
	Adjust.
	* tests/data/test-diff-suppr/test29-suppr-6.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-8.txt: Likewise.
	* tests/data/test-diff-suppr/libtest31-v{0,1}.so: New test input.
	* tests/data/test-diff-suppr/libtest31.suppr: Likewise
	* tests/data/test-diff-suppr/libtest32-v{0,1}.so: Likewise.
	* tests/data/test-diff-suppr/libtest32-0.suppr: Likewise.
	* tests/data/test-diff-suppr/libtest33-v{0,1}.so: Likewise.
	* tests/data/test-diff-suppr/test31-report-{0,1}.txt: Likewise.
	* tests/data/test-diff-suppr/test31-v{0,1}.cc: Likewise.
	* tests/data/test-diff-suppr/test32-report-{0,1}.txt: Likewise.
	* tests/data/test-diff-suppr/test32-v{0,1}.c: Likewise.
	* tests/data/test-diff-suppr/test33-suppr-1.txt: Likewise.
	* tests/data/test-diff-suppr/test33-v{0,1}.cc: Likewise.
	* tests/data/test-diff-suppr/test33-v{0,1}.h: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test24-drop-fns-0.suppr: Likewise.
	* tests/data/test-read-dwarf/test24-drop-fns.cc: Likewise.
	* tests/data/test-read-write/test28-drop-std-fns.abignore:
	Likewise.
	* tests/data/test-read-write/test28-drop-std-vars.abignore:
	Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-fns.xml: Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars.xml:
	Likewise.
	* tests/data/test-read-write/test28.xml: Likewise.
	* tests/data/Makefile.am: Add the new test artifacts to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_spec): Take the new test inputs
	into account.
	* tests/test-read-dwarf.cc (Inoutspec::in_suppr_spec_path): New
	data member.
	(in_out_spec): Adjust.  The new test inputs into account.
	(set_suppressions): New static function.
	(handle_in_out_spec): Adjust.
	* tests/test-read-write.cc (Inoutspec::{in_suppr_spec_path,
	ref_out_path}): New data members.
	(in_out_spec): Adjust.  Take new test inputs into account.
	(main): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-09-21 18:35:08 +02:00
Dodji Seketeli
24b418795e Pimplify the abigail::ir::scope_decl type
The abigail::ir::scope_decl still has its data member members be
visible from its header file.  This patch hides those data member
using the pimpl idiom, just as what is done other types throughout the
project.

	* include/abg-ir.h (scope_decl::{priv, priv_sptr}) Declare new types.
	(scope_decl::priv_): New pimpl data member.
	(scope_decl::{member_, member_scopes}): Move this as data member
	of the new scope_decl::priv type in the abg-ir.cc file.
	(scope_decl::{scope_decl, get_member_decls, get_member_scopes,
	is_empty}): Make these inline member functions be out-of-line.
	* src/abg-ir.cc (struct scope_decl::priv): Define new type.
	(scope_decl::{scope_decl, get_member_decls, get_member_scopes,
	is_empty}): Define these new member functions here.  They were
	inline in the include/abg-ir.h header files before.
	(scope_decl::{add_member_decl, insert_member_decl,
	remove_member_decl}): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-09-21 18:35:07 +02:00
Dodji Seketeli
e73c0ed0fb Add new helper functions
In preparation of dropping ABI artifacts from the IR, add new generic
helper functions.

	* include/abg-fwd.h (get_location, build_qualified_name): Declare
	new functions.
	* include/abg-ir.h (is_method_decl): Declare two new overloads of
	this function.
	* src/abg-ir.cc (get_location, build_qualified_name)
	(is_method_decl): Define these functions declared above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-09-21 18:35:07 +02:00
Dodji Seketeli
756cdc113b Do not emit empty namespaces in abixml
Today The abixml writer emits namespaces even if they are empty or
contain empty namespaces.  This leads to abixml files that are
unnecessarily big and verbose.  This patch prevents that.

	* include/abg-ir.h
	(namespace_decl::is_empty_or_has_empty_sub_namespaces): Declare
	new function ...
	* src/abg-ir.cc
	(namespace_decl::is_empty_or_has_empty_sub_namespaces): ... and
	define it.
	* src/abg-writer.cc (write_namespace_decl): Do not write empty
	namespaces or namespaces containing empty namespaces.
	* tests/data/test-read-dwarf/test9-pr18818-clang.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/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/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-09-21 18:35:07 +02:00
Dodji Seketeli
b07fcbcc0d Cleanup is_class and is_compatible_with_class_type
There was two overloads of is_class, one for types and one for decls.
Now that we have type_or_decl_base which is a common base type for
both, having just one is_class function that takes a type_or_decl_base
is more compact and easier to maintain.  This patch does that.  It
also cleans up the declaration of the is_compatible_with_class_type
function.

	* include/abg-fwd.h (is_class): Remove the overloads that take a
	decl_base or a type_base.  Add one that takes a type_or_decl_base.
	(is_compatible_with_class_type): Make this take a reference to
	smart pointer, not just the smart pointer.
	* src/abg-ir.cc (is_class): Do the same as in the header file.
	(is_compatible_with_class_type): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-07-26 20:04:53 +02:00
Dodji Seketeli
5a24ffcd61 Add ABG_ASSERT_NOT_REACHED macro
Adding this macro to abort at places where the execution flow
shouldn't take us to.  Using this is more explicit (self-documented)
than using abort.

This patch replaces the use of abort() in abg-dwarf-reader.cc.

	* include/abg-tools-utils.h (ABG_ASSERT_NOT_REACHED): New macro.
	* src/abg-dwarf-reader.cc (stt_to_elf_symbol_type)
	(stb_to_elf_symbol_binding, get_elf_class_size_in_bytes)
	(build_ir_node_from_die): Use the new ABG_ASSERT_NOT_REACHED macro
	in lieu of just calling abort().

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-07-26 20:04:23 +02:00
Dodji Seketeli
93fea0667e Better recognize qualified void type
This fixes Bug 20329 - DW_TAG_const_type with no DW_AT_type not recognized as "const void".

It appears that GCC sometimes emits "const void" types by emitting a
const type DIE with no type attribute.  The DWARF reader didn't
recognize that construct as a qualified void type.

This patch teaches the DWARF reader to recognize that construct.

It also appears that "const void" and "void" are equivalent and can be
emitted interchangeably by compilers (Intel and GCC) in their debug
info.  That can lead to spurious ABI change reports saying that a type
"const void" was changed into a "void" type.

This patch transforms an occurrence of "const void" type into a "void"
type in the internal representation when reading DWARF.  This does
away with the spurious change that appears when comparing selected
binaries emitted with the intel against binaries emitted with GCC.

	* include/abg-ir.h (environment::is_void_type): Declare new member
	function.
	* src/abg-ir.cc (environment::is_void_type): Define new member
	function.
	* src/abg-dwarf-reader.cc (maybe_strip_qualification): Strip const
	qualifier from const void.
	* tests/data/test-diff-filter/test34-libjemalloc.so.2-gcc-6.1.0:
	New test input.
	* tests/data/test-diff-filter/test34-libjemalloc.so.2-intel-16.0.3: Likewise.
	* tests/data/test-diff-filter/test34-report-0.txt: New reference output.
	* tests/data/Makefile.am: Add the new files above to the source
	distribution.
	* tests/test-diff-filter.cc (in_out_specs): Compare the two new
	binaries above.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: 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/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/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-07-07 14:04:10 +02:00
Dodji Seketeli
9da7ae49d7 Add a new overload for is_type_decl
While working on something else, it appeared that I needed an overload
for is_type_decl that takes a shared pointer to decl_base.  The
current is_type_decl takes a shared opinter to type_base.

This patch also updates some code that unnecessarily calls
is_type_decl.

	* include/abg-fwd.h (is_type_decl): Declare a new overload
	* src/abg-ir.cc (is_type_decl): Define a new overload.
	(function_decl::parameter::get_pretty_representation): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-07-04 16:51:10 +02:00
Dodji Seketeli
a1b07236bb Misc white space and comment cleanups
While looking at something else, I noticed some spots that need
cleanup with respect to white space or comments.  This patch does just
that.  No big deal.

	* include/abg-ir.h (typedef type_or_decl_base): Cleanup comment.
	* src/abg-ir.cc (struct type_or_decl_base::priv): Fix comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-06-13 14:43:52 +02:00
Dodji Seketeli
b36ca1501e Bug 20180 - Support system-wide suppression specifications
This patch adds support for loading system and user level suppression
specifications for libabigail tools.

At launch time, relevant libabigail tools (abidiff, abipkgdiff
fedabipkgdiff for now) read the default system suppression
specification file, if it's present, from a file which path is the
value of the environment variable
LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE, if set, or from the file
$libdir/libabigail/default.abignore.

Then it reads the user system suppression specification file, if it's
present, from a file which path is the value of the environment
variable LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE, if set, or from the
file $HOME/.abignore.

The content of the user system suppression file is merged with the
content of default system suppression file.

That content is also merged with the content of the suppression
specification files that might be provided by the --suppressions
command line option of the invoked tools.

The resulting set of all these suppression specifications is thus used
to filter the ABI change reports that are emitted.

abidiff, abipkgdiff and abipkgdiff gain a --no-default-suppression
option to avoid loading any of these default suppression specification
files.

The patch also installs a default.abignore file into $(pkglibdir).
Note that on x86_64, that directory is /usr/lib64/libabigail.  Now we
just need to think about the content of that default.abignore file.

	* doc/manuals/abidiff.rst: Document the default suppression
	scheme, its interaction with the --supprs option and the new
	--no-default option.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* doc/manuals/fedabipkgdiff.rst: Likewise.
	* configure.ac: Generate the tests/runtestdefaultsupprs.py file
	from the new tests/runtestdefaultsupprs.py.in template.
	* default.abignore: New file.
	* Makefile.am: Add it to source distribution.
	* src/Makefile.am: Define the ABIGAIL_ROOT_SYSTEM_LIBDIR
	preprocessor macro that is set the value of the $libdir autotools
	macro.
	* include/abg-tools-utils.h: Update copyright years.
	(get_system_libdir, get_default_system_suppression_file_path)
	(get_default_user_suppression_file_path)
	(load_default_system_suppressions)
	(load_default_user_suppressions): Declare new functions
	* src/abg-tools-utils.cc (get_system_libdir)
	(get_default_system_suppression_file_path)
	(get_default_user_suppression_file_path)
	(load_default_system_suppressions)
	(load_default_user_suppressions): Define new functions.
	(is_regular_file): Amend this so that it return true for symlinks
	to regular files too.
	(is_dir): Amend this so that it returns true for symlinks to
	directories too.
	* tools/abidiff.cc (options::no_default_supprs): New data member.
	(options::options): Initialize the new data member.
	(display_usage): Display a new help string for the new
	--no-default-suppression command line option.
	(parse_command_line): Parse this new command line option.
	(set_diff_context_from_opts): Load the default suppression
	specifications, unless --no-default-suppression or --supprs was
	provided.
	* tools/abipkgdiff.cc (options::no_default_supprs): New data
	member.
	(options::options): Initialize the new data member.
	(parse_command_line): Parse the new --no-default-suppression
	command line option.
	(main): Load the default suppression specifications, unless
	--no-default-suppression or --supprs was provided.
	* tools/fedabipkgdiff (abipkgdiff): Add --no-default-suppression
	to the invocation of abipkgdiff if it was provided on the command
	line.
	(build_commandline_args_parser): Parse the new
	--no-default-suppression command line option.
	* tests/runtestdefaultsupprs.py.in: New test harness template.
	* tests/Makefile.am: Add the new runtestdefaultsupprs.py to the
	set of tests.
	* tests/data/test-default-supprs/test0-type-suppr-0.suppr: New
	test input.
	* tests/data/test-default-supprs/test0-type-suppr-report-0.txt: Likewise.
	* tests/data/test-default-supprs/test0-type-suppr-v0.o: Likewise.
	* tests/data/test-default-supprs/test0-type-suppr-v1.o: Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir-report-0.txt:
	Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir1: Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir2: Likewise.
	* tests/data/Makefile.am: Add new the new tests input above to
	Makefile.am.
	* tests/runtestcanonicalizetypes.sh.in: Pass
	--no-default-suppression to abidiff invocations.
	* tests/runtestdefaultsupprs.py.in: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tools/abidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-30 18:39:49 +02:00
Dodji Seketeli
e19bf5627a Make abi{pkg}diff filter out changes about private types
This is to address the following enhancement requests:

    #19588 - Add a --headers-dir1 and --headers-dir2 option to abidiff
    #19948 - Add --devel-pkg1 and --devel-pkg2 options to abipkgdiff

When the user specifies where to find header files for two binaries
(or packages) being compared, this patch generates a type suppression
specification that filters out change reports about types that are
defined in files that are not in the set of header files specified.

The type suppression specification also suppresses change reports
about changed/added/removed virtual member functions which enclosing
class type matches the type suppression specification.

There is a corner case that the patch handles too, and that is
exhibited by the accompanying test case for abidiff.  There can be a
class defined by DWARF as having no source location and as being a
pure declaration.  This can be a class declaration that has inline
virtual members only, and one or several non-defined virtual methods
too.  When that declaration is included in a source file, GCC
generates debug info that describes that class as being a
declaration-only class with no source declaration.  This patch
considers such a class as being non defined; you know, like a true
opaque type.  So it's considered being not defined in any public
header file.  Changes to this kind of class are thus filtered out.

	* include/abg-comp-filter.h: Update copyright year.
	* src/abg-comp-filter.cc (has_virtual_mem_fn_change): Make this
	static function become exported.
	(has_virtual_mem_fn_change): Declare new function.
	* include/abg-suppression.h
	(suppression_base::{get,set}_is_artificial): Declare new
	accessors.
	(type_suppression::get_source_locations_to_keep): Return an
	unordered set of strings, not a vector.  Add a non-const overload.
	(type_suppression::set_source_locations_to_keep): Set an unordered
	set of strings, not a vector.
	* src/abg-suppression.cc (suppression_base::priv::is_artificial_):
	New data member.
	(suppression_base::priv::priv): Initialize the new data member.
	(suppression_base::{get,set}_is_artificial): Define new accessors.
	(type_suppression::priv::source_locations_to_keep_): Change the
	vector of strings representing source file names into unordered
	set of string.
	(type_suppression::get_source_locations_to_keep): Return an
	unordered set of strings, not a vector.  Define a non-const
	overload.
	(type_suppression::set_source_locations_to_keep): Set an unordered
	set of strings, not a vector.
	(type_suppression::suppresses_diff): Make this suppress virtual
	member function diffs if the enclosing type of the changed virtual
	member is suppressed by the current type_suppression.
	(read_type_suppression): Adjust to use the fact that the source
	locations are not stored in an unordered set, not in a vector
	anymore.  Otherwise, using a vector here make things too slow.
	(type_suppression::suppresses_type): Likewise.  Also, If the type
	we are looking at has no location because it's a true opaque type
	and if the current suppression is an artificial suppression that
	is meant to suppress change reports about non-public types, then
	suppress the type.
	* include/abg-tools-utils.h (gen_suppr_spec_from_headers): Declare
	new public function.
	* src/abg-tools-utils.cc (PRIVATE_TYPES_SUPPR_SPEC_NAME): Define a
	new constant variable.
	(handle_fts_entry): Define new static function.
	(gen_suppr_spec_from_headers): Define new public function.
	* src/abg-comparison.cc
	(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
	If a type suppression suppresses a given class C, make it change
	added/removed virtual functions whose enclosing type is C.
	* tools/abidiff.cc (options::{headers_dir1, headers_dir2}): New
	data members.
	(display_usage): Add help strings for --headers-dir1 and
	--headers-dir2.
	(parse_command_line): Parse the new --headers-dir1 and
	--headers-dir2 options.
	(set_diff_context_from_opts): Generate suppression specifications
	to filter out changes on private types, if --headers-dir1 or
	--headers-dir2 is given.
	* tools/abipkgdiff.cc (options::{devel_package1, devel_package2}):
	New data members.
	(typedef package_sptr): New typedef.
	(enum package::kind): New enum.
	(package::kind_): New data member.  This replaces ...
	(package::is_debug_info_): ... this data member.
	(package::{devel_package_, private_types_suppressions_}): New data
	members.
	(package::package): Adjust.
	(package::get_kind): Define new member function.  This replaces
	...
	(package::is_debug_info): ... this member function overload.
	(package::set_kind): Define new member functin.  It replaces ...
	(package::is_debug_info): ... this member function overload.
	(package::{devel_package, private_types_suppressions}): Define new
	accessors.
	(package::erase_extraction_directies): Erase the sub-directory
	where development packages are extracted to.
	(compare_args::private_types_suppr{1,2}): New data members.
	(compare_args::compare_args): Adjust.
	(display_usage): Add help strings for --devel-pkg1/--devel-pkg2.
	(compare): Make the overload that compares elf files take private
	types suppressions.  Add the private types suppressions to the
	diff context.
	(pthread_routine_compare): Adjust the call to compare.
	(maybe_create_private_types_suppressions): Define new static
	function.
	(pthread_routine_extract_pkg_and_map_its_content): If a devel
	package was specified for the main package then extract it in
	parallel with the other package extraction.  When the extraction
	is done, create private types suppressions by visiting the
	directories that contain the header files.
	(compare): In the overload that compares packages by scheduling
	comparison of individual elf files that are in the packages, pass
	in the private type suppressions too.
	(parse_command_line): Parse the new --devel-pkg{1,2} command line
	options.
	(main): Associate the devel package to the main package, if the
	--devel-pkg{1,2}.
	* doc/manuals/abidiff.rst: Add documentation about the new
	--headers-dir1 and --headers-dir2 options.
	* doc/manuals/abipkgdiff.rst: Likewise, add documentation about
	the new --devel-pkg1 and --devel-pkg2 libraries.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	New test reference output.
	* tests/data/test-diff-pkg/tbb-devel-4.1-9.20130314.fc22.x86_64.rpm:
	New test input package.
	* tests/data/test-diff-pkg/tbb-devel-4.3-3.20141204.fc23.x86_64.rpm: Likewise.
	* tests/test-diff-pkg.cc b/tests/test-diff-pkg.cc
	(InOutSpec::{first,second}_in_devel_package_path): New data
	members.
	(in_out_specs): Adjust.  Also, add a new entry describing the new
	test inputs above.
	(test_task::perform): When the new test entry contains devel
	packages, pass them to abipkgdiff using the --devel1 and --devel2
	options.
	* tests/data/test-diff-suppr/test30-include-dir-v0/test30-pub-lib-v0.h:
	A new test input source code.
	* tests/data/test-diff-suppr/test30-include-dir-v1/test30-pub-lib-v1.h: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v0.cc: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v0.h: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v1.cc: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v1.h: Likewise.
	* tests/data/test-diff-suppr/test30-pub-lib-v0.cc: Likewise.
	* tests/data/test-diff-suppr/test30-pub-lib-v0.so: Add new test
	binary input.
	* tests/data/test-diff-suppr/test30-pub-lib-v1.cc: Add new test
	input source code.
	* tests/data/test-diff-suppr/test30-pub-lib-v1.so: Add new test
	binary input.
	* tests/data/test-diff-suppr/test30-report-0.txt: Add new test
	reference output.
	* tests/data/test-diff-suppr/test30-report-1.txt: Add new test
	reference output.
	* tests/test-diff-suppr.cc (InOutSpec::headers_dir{1,2}): New data
	members.
	(InOutSpec::abidiff_options): Renamed the bidiff_options data
	member into this.
	(in_out_specs): Adjust.  Also, added the new test input above to
	this.
	(main): Adjust to invoke abidiff with the new --hd1 and --hd2
	options if the input specs for the tests has the new
	InOutSpec::headers_dir{1,2} data member set.  Renamed bidiff into
	abidiff.
	* tests/data/Makefile.am: Add the new test inputs to the source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-24 10:32:08 +02:00
Dodji Seketeli
a9e01ad6e9 Optimize out some shared_ptr use
Profiling showed that getting the pointed-to type of a pointer type is
on the hot spot when comparing corpora with a lot of entry points with
a lot of pointer types reachable from the entry points of the corpora.

So avoid handling the shared_ptr to the pointed-to type for that case
can save us a few CPU cycles in a noticeable way.

This patch does this by creating a new
pointer_type_def::get_naked_pointed_to_type() (that returns a naked
pointer) to supplement the classic
pointer_type_def::get_pointer_to_type() function, and uses that in a
code spot that profiling revealed to be a critical path.

	* include/abg-ir.h (pointer_type_def::get_naked_pointed_to_type):
	Declare new member function.
	* src/abg-ir.cc (pointer_type_def::priv::naked_pointed_to_type_):
	New data member.
	(pointer_type_def::priv::priv): Adjust to initialize the new data
	member.
	(pointer_type_def::pointer_type_def): Adjust to use the
	constructor pointer_type_def::priv::priv to initialize the
	pointed-to type (including its new naked pointer variant).  So we
	do not have to initialize the priv_->pointed_to_type_ explicitely
	in the constructor anymore.
	(pointer_type_def::get_naked_pointed_to_type): Define new data
	member.
	(pointer_type_def::get_qualified_name): Use a naked pointer to the
	pointed-to type, rather than a smart pointer.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
22cd4059cd Light optimizations by passing reference to smart pointers around
Profiling shows that some smart pointers were unnecessarily created
here and there, and that had a noticeable effect on performance, when
comparing two gtk3 packages.

This patch passes references to smart pointers in those cases.

	* include/abg-fwd.h (get_type_name): Take a reference to type_sptr.
	* src/abg-ir.cc (get_type_name): Take a reference to type_sptr.
	(suppression_base::priv::{get_file_name_regex,
	get_file_name_not_regex, get_soname_regex, get_soname_not_regex}):
	Return a reference to regex_t_sptr.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
49db3f838c Plug leak of diffs of member variables of class type
On certain work loads, cycles in the tree of diffs of member variables
can appear.  This because:

  1/ each diff tree nodes holds a reference on each of its children
  nodes
  2/ each var_diff tree node holds a reference on the diff tree node
  representing its type changes.

There can thus be reference cycles in involving diff the tree --> child
node relationship and the var_diff tree --> type diff tree
relationship.

This patch fixes the issue be make sure that a diff tree node does not
hold a reference on its children nodes.  That is, rather than having a
vector of shared pointers to its children diff nodes, it has a vector
of naked pointers to those.  The patch goes further by making sure
that a var_diff node does not hold a reference to its type diff node
either.  It holds a weak pointer to the type diff node, rather than a
shared pointer.

The patch should be followed by a patch make sure that all kinds of
diff nodes follow this pattern; that is, if a diff node needs to carry
a sub-type diff node, it should do so by either using a naked pointer
to the sub-type diff node, or a weak pointer.

For now, the patch fixes the leaks reported by running all the tests
of the suite under Valgrind.

	* include/abg-comparison.h (diff_wptr, unordered_diff_sptr_set): New typedefs.
	(struct diff_sptr_hasher): Define new type.
	(diff_context::keep_diff_alive): Declare new member function.
	(diff::children_nodes): Return a vector of diff*, rather than a
	vector of diff_sptr.
	* src/abg-comparison.cc (diff_context::priv::live_diffs_): New
	data member.
	(diff_context::keep_diff_alive): Define new data member.
	(diff::priv::children_): Make this be a vector of diff*, rather
	than a vector of diff_sptr.
	(diff_less_than_functor::operator()): Add a new overload for
	diff*.  Make the existing overload of diff_sptr use the new one.
	(diff::children_nodes): Adjust;
	(diff::append_child_node): Make sure the child node is kept
	alive.  Only add the naked pointer to the child node to the vector
	of children.
	(diff::traverse): Adjust.
	(var_diff::priv::type_diff_): Make this be a weak pointer, rather
	than a shared pointer.
	(var_diff::type_diff): The var_diff::priv::type_diff_ data member
	is now a weak pointer, so make this accessor convert it to a
	shared pointer.
	(corpus_diff::priv::children_): Turn this into a vector of diff*,
	rather than a vector of diff_sptr.
	(corpus_diff::children_nodes): Adjust.
	(corpus_diff::append_child_node): Make sure the child node is kept
	alive.  Only add the naked pointer to the child node to the vector
	of children.
	(category_propagation_visitor::visit_end): Adjust.
	(suppression_categorization_visitor::visit_end): Adjust.
	(redundancy_marking_visitor::{visit_begin, visit_end}): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
00f79732fb Plug leak of shared private data of class_diff type
Some time ago, a memory optimization was put in place to reduce the
memory usage of the IR used to represent the result of a comparison
between two corpora.

The principle of that optimization was to share the data of the
class_diff::priv member among instances of class_diff that are in the
same class of equivalence.

In practice, the class_diff::priv member of an instance that has a non
empty class of equivalence was set to the class_diff::priv of its
canonical type.

Because clas_diff::priv is a shared pointer, setting it to the
class_diff::priv of another instance was creating cycles in the graph
of class_diff, sometimes.  And those cycles lead to memory leaks as
the reference count of shared pointers to class_diff would not go down
to zero anymore.

This patch fixes the problem of those cycles by not setting the
class_diff::priv data member.  Rather, when a class_diff is part of a
non-empty class of equivalence, its class_diff::priv is left nil.  A
new class_diff::get_priv() accessor is provided; it returns the shared
class_diff::priv of the canonical type when the current
class_diff::priv is nil; otherwise it just returns the current
class_diff::priv.

	* include/abg-comparison.h (class_diff::get_priv): Declare new
	member function.
	(class_diff::get_priv): Define new member function.
	(class_diff::{chain_into_hierarchy, base_changes, deleted_bases,
	inserted_bases, changed_bases, base_changes, member_types_changes,
	member_types_changes, data_members_changes, inserted_data_members,
	deleted_data_members, member_fns_changes, changed_member_fns,
	member_fns_changes, deleted_member_fns, inserted_member_fns,
	member_fn_tmpls_changes, member_class_tmpls_changes,
	member_class_tmpls_changes, report}): Rather than accessing
	class_diff::priv directly, use the new class_diff::get_priv.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
5cf19e47ef Remove circular ref from class_decl::priv::definition_of_declaration
It appears that there are cases where the data member
class_decl::priv::definition_of_declaration_ can point to the current
instance of class_decl, leading to a circular reference and thus a
leak because the reference count of the current instance of class_decl
will never reach zero.

This patch fixes that by making
class_decl::priv::definition_of_declaration_ be a weak pointer, rather
than a smart pointer.

	* include/abg-ir.cc (class_decl::get_definition_of_declaration):
	Return a shared pointer, rather than a reference to a shared pointer.
	* src/abg-ir.cc (class_decl::priv::definition_of_declaration_):
	Make this be a weak pointer.
	(class_decl::get_definition_of_declaration):
	Likewise.  And return the shared pointer built out of the weak
	pointer we have in there now.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
b71e5c6f22 Plug leak of regex_t in suppression engine
The suppression engine was not creating the shared pointer to
regex_t in the proper way that would correctly free the memory
allocated by the glibc's regcomp function.

This patch fixes that.

	* include/abg-sptr-utils.h (build_sptr<T>): Declare an overload that
	allocates a T* and wraps it into a shared_ptr<T>.
	(build_sptr<regex_t>): Declare a specialization for regex_t.
	* src/abg-corpus.cc (build_sptr<regex_t>()): Define the
	specialization here.
	* src/abg-suppression.ccp
	(suppression_base::priv::{get_file_[not]_name_regex,
	get_soname_[not]_regex}): Use the new build_sptr<regex_t>().
	(type_suppression::priv::{get_type_name_regex,
	get_source_location_to_keep_regex}): Likewise.
	(function_suppression::parameter_spec::priv::get_type_name_regex):
	Likewise.
	(function_suppression::priv::{get_name_regex,
	get_return_type_regex, get_symbol_name_regex,
	get_symbol_version_regex}): Likewise.
	(variable_suppression::priv::{get_name_regex,
	get_symbol_name_regex, get_symbol_version_regex,
	get_type_name_regex}): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
080b88c9a1 Implement a [suppress_file] suppression directive
abidiff, abipkgdiff and abicompat now recognize a [suppress_file]
directive in suppression specifications.  That directive instructs the
tool to avoid loading some binaries altogether.

This is the first directive that won't act on the result of the
comparison of two binaries.  It actually acts earlier and prevents the
tool from loading some binaries altogether.

The directive looks like:

    [suppress_file]
      # Don't load any library named lib_private*.so
      file_name_regexp = lib_private.*\\.so

This prevents the tool from loading (and thus comparing) any library
which name matches the pattern "lib_private*.so".

    [suppress_file]
      # Only load libraries name lib_public*.so
      file_name_not_regexp = lib_public.*\\.so

This instructs the tool to only load (and compare) files which name
match the pattern "lib_public*.so".

	* doc/manuals/libabigail-concepts.rst: Document the new
	'suppress_file' directive.
	* include/abg-suppression.h (file_suppression): Define new class.
	(file_suppression_sptr): Define new typedef.
	(is_file_suppression, file_is_suppressed): Declare new functions.
	* src/abg-suppression.cc ():
	(read_file_suppression, is_file_suppression, file_is_suppressed):
	Define new functions.
	(file_suppression::{file_suppression, suppresses_file,
	~file_suppression}): Define new member functions.
	* tools/abidiff.cc (main): If a suppression specification
	suppresses one of the input files, then do not perform the
	comparison.
	* tools/abipkgdiff.cc (compare): If a suppression specification
	suppresses a file that is to be compared, then do not perform the
	comparison.
	* tools/abicompat.cc (create_diff_context): New static function.
	(perform_compat_check_in_normal_mode)
	(perform_compat_check_in_weak_mode): Adjust to take a context in
	parameter.  Do not create a diff context here anymore, do not load
	suppression files here either.
	(main): Use the new create_diff_context to create a diff context
	and initialize it, including loading suppression specifications.
	If any suppression specification suppresses a file to load, then
	do not load perform any compatibility checking.  Adjust
	invocations of perform_compat_check_in_weak_mode and
	perform_compat_check_in_normal_mode to pass the diff context.
	* tests/data/test-diff-suppr/test0-type-suppr-3.suppr: New test
	input.
	* tests/data/test-diff-suppr/test0-type-suppr-4.suppr: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-5.suppr: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-6.suppr: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-6.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt:
	Likewise.
	* tests/test-diff-suppr.cc (in_out_specs): Use the new test
	inputs.
	* tests/data/test-abicompat/test0-fn-changed-1.suppr: New test
	input.
	* tests/data/test-abicompat/test0-fn-changed-report-3.txt:
	Likewise.
	* tests/test-abicompat.cc (in_out_specs):: Use the new test
	inputs.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-08 12:39:26 +02:00
Dodji Seketeli
7cd624a1cd Split suppression engine off of abg-comparison.{cc,h}
Until now, the suppression engine was part of the comparison engine.
The code of both was in the abg-comparison.{cc,h} files.

For the sake of greater modularity, this patch separates the suppression
engine from the comparison engine.  The suppression engine now lives
in include/abg-suppression.h and src/abg-suppression.cc.  The patch
also updates logical consumers of the suppression engine to adapt them
to the change.

	* include/Makefile.am: Add abg-suppression.h to source
	distribution.
	* include/abg-comparison.h: Remove abg-ini.h include directive.
	(suppression_sptr, suppressions_type): Move these typedefs to
	abg-fwd.h.
	(class suppression_base, type_suppression)
	(type_suppression::insertion_range)
	(type_suppression::insertion_range::boundary)
	(type_suppression::insertion_range::integer_boundary)
	(type_suppression::insertion_range::fn_call_expr_boundary)
	(function_suppression, function_suppression::parameter_spec)
	(variable_suppression): Move these type definitions to the new
	abg-suppression.h.
	(read_suppressions, is_type_suppression, is_integer_boundary)
	(is_fn_call_expr_boundary, is_function_suppression)
	(is_variable_suppression, operator&)
	(operator|): Move these function declarations to the new
	abg-suppression.h.
	(type_suppression, type_suppression_sptr, type_suppression_type)
	(function_suppression, function_suppression_sptr)
	(function_suppressions_type, variable_suppression)
	(variable_suppression_sptr, variable_suppressions_type): Move
	these forward declaration and typedefs to the new
	abg-suppression.h.
	(diff_context::suppressions): Adjust return type to
	suppr::suppressions_type&.
	(diff_context::add_suppression): Adjust parameter type to
	suppr::suppressions_sptr.
	(diff_context::add_suppressions): Adjust parameter type
	suppr::suppressions_type&.
	(is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff)
	(is_pointer_diff, is_reference_diff, is_fn_parm_diff)
	(is_base_diff, is_child_node_of_function_parm_diff)
	(is_child_node_of_base_diff): Declare these new functions.  They
	were previously static, local to abg-comparison.cc only.  Now they
	need to be exported because they are used by the suppression
	engine's code that now lives in its one files.
	* include/abg-fwd.h (suppr::{suppression_base, suppression_sptr,
	suppressions_type}): Forward declare these here.
	* include/abg-suppression.h (class suppression_base)
	(type_suppression, type_suppression::insertion_range)
	(type_suppression::insertion_range::boundary)
	(type_suppression::insertion_range::integer_boundary)
	(type_suppression::insertion_range::fn_call_expr_boundary)
	(function_suppression, function_suppression::parameter_spec)
	(variable_suppression): Move these type definitions here, in the
	namespace suppr.
	(read_suppressions, is_type_suppression, is_integer_boundary)
	(is_fn_call_expr_boundary, is_function_suppression)
	(is_variable_suppression, operator&)
	(operator|): Move these function decalration here, in the
	namespace suppr.
	(type_suppression_sptr, type_suppressions_type)
	(function_suppression_sptr, function_suppressions_type)
	(variable_suppression_sptr, variable_suppressions_type): Move
	these typedefs here, in the namespace suppr.
	* src/Makefile.am: add src/abg-suppression.cc to source
	distribution.
	* src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff)
	(is_function_decl_diff, is_pointer_diff, is_reference_diff)
	(is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff)
	(is_child_node_of_function_parm_diff, is_child_node_of_base_diff):
	Export these functions.
	(*suppression*): Move all the suppression-related definitions to
	the new abg-suppression.cc.
	* src/abg-suppression.cc: New file. Contains all the *suppression*
	definitions from src/abg-comparison.cc, that are put in the suppr
	namespace.
	* tools/abicompat.cc: Adjust.
	* tools/abidiff.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-08 12:29:57 +02:00
Dodji Seketeli
e2f777164f Update copyright year on abg-comparison.h
* include/abg-comparison.h: Update copyright year.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-08 11:14:35 +02:00
Dodji Seketeli
19463fc485 Add some apidoc to dwarf_reader
* include/abg-dwarf-reader.h (namespace dwarf_reader): Add apidoc.
	(enum elf_type): Add an apidoc for each enumerator.
	* src/abg-dwarf-reader.cc (get_type_of_elf_file): Add an apidoc
	for the 'type' parameter.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-06 18:18:07 +02:00
Dodji Seketeli
b885e6283f Bug 20015 - support file_name_not_regexp and soname_not_regexp in suppr specs
The supression directives suppress_type, suppress_function and
suppress_variable support the two properties below, among others:

    file_name_regexp = <some-regexp>
    soname_regexp = <some-regexp>

When the regular expression matches either the file name or the
soname, then the suppression directive is activated.

This patch adds the support for these two additional properties for
these suppression directives:

    file_name_not_regexp = <some-regexp>
    soname_not_regexp = <some-regexp>

These activate the current suppression directive if the regular
expression does *NOT* match the file name or soname.

This is very helpful to express change report suppressions like:

    "suppress all ABI change reports for all libraries but those with
    file names (or sonames) with the pattern libfoobar.*"

	* include/abg-comparison.h
	(suppression_base::{get,set}_file_name_not_regex_str): Declare new
	member functions.
	(suppression_base::{get,set}_soname_not_regex_str): Likewise.
	(suppression_base::{names,sonames}_of_binaries_match): Likewise.
	* src/abg-comparison.cc
	(suppression_base::priv::get_file_name_regex): Fix comment.
	(suppression_base::priv::get_file_name_not_regex): New member
	function.
	(suppression_base::priv::get_soname_regex): Fix comment.
	(suppression_base::priv::get_soname_not_regex): New member
	function.
	(suppression_base::{get,set}_file_name_not_regex_str): Define new
	member functions.
	(suppression_base::{get,set}_soname_not_regex_str): Likewise.
	(suppression_base::{names,sonames}_of_binaries_match): Likewise.
	These got factorized out of type_suppression::suppresses_type,
	function_suppression::suppresses_function,
	function_suppression::suppresses_function_symbol,
	variable_suppression::suppresses_variable,
	variable_suppression::suppresses_variable_symbol.
	(type_suppression::suppresses_type): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	(read_type_suppression): Read the new file_name_not_regexp and
	soname_not_regexp properties.
	(function_suppression::{suppresses_function,
	suppresses_function_symbol}): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	(read_function_suppression): Read the new file_name_not_regexp and
	soname_not_regexp properties.
	(variable_suppression::{suppresses_variable,
	variable_suppression::suppresses_variable_symbol}): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	(read_variable_suppression): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	* doc/manuals/libabigail-concepts.rst: Document the new
	file_name_not_regexp and soname_not_regexp suppression properties.
	* tests/data/test-diff-suppr/test24-soname-report-10.txt: New test
	reference output.
	* tests/data/test-diff-suppr/test24-soname-report-11.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-12.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-13.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-14.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-15.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-16.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-9.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-10.txt: New test input.
	* tests/data/test-diff-suppr/test24-soname-suppr-11.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-12.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-13.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-14.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-15.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-16.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-9.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-2.txt: New test
	reference output.
	* tests/data/test-diff-suppr/test29-soname-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-6.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-8.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-2.txt: New test input.
	* tests/data/test-diff-suppr/test29-suppr-3.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-4.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-5.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-6.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-7.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-8.txt: Likewise.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Make this test harness
	run over the new test inputs.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-27 23:58:50 +02:00
Dodji Seketeli
8d670d6dde Make API documentation of thread pools visible
* include/abg-workers.h: Document the workers namespace, the task,
	queue and queue::task_done_notify types.
	* src/abg-workers.cc: Move the documentation of the thread_pool
	module inside the abigail::worker namespace, so that references to
	task and queue types (which are also in the abigail::worker
	namespace) can be resolved in the apidoc.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-27 23:58:50 +02:00
Sinny Kumari
8944ceb9ef Bug 19961 - Distinguish between PI executable and shared library
In the ELF format, Position Independent Executables (aka PIE) and
shared libraries are marked as being of type ET_DYN.  So just looking
at the type of the ELF file is not enough to discriminate a position
independent executable from a shared library.

And this is the problem.  Libabigail just looks at the type of the ELF
file to discriminate PIE binaries from shared libraries binaries.

So it treats both kinds of binaries as being shared libraries.  When
we run abipkgdiff with the --dso-only option, the tool considers both
PIEs and shared libraries, even though the intent of the --dso-only
option is have the tool consider shared libraries only.

With this patch, we introduce a new enumerator ELF_TYPE_PI_EXEC (to
the elf_type enum) for PIE binaries.  From now on, a file will be
properly recognized as being of the ELF_TYPE_DSO kind only if it is a
shared library.

	* include/abg-dwarf-reader.h (elf_type): Add new enumerator
	ELF_TYPE_PI_EXEC.
	* src/abg-dwarf-reader.cc
	(lookup_data_tag_from_dynamic_segment): New function for
	data tag lookup in dynamic segment of an elf
	(elf_file_type): Return ELF_TYPE_PI_EXEC file type for
	a PI executable.
	(get_elf_file_type): Change this to take an elf handle.
	(get_type_of_elf_file): New function that got factorized out of ...
	(load_dt_soname_and_needed): ... this one.
	* tools/abipkgdiff.cc (create_maps_of_package_content): Also
	consider ELF_TYPE_PI_EXEC file type.
	(compare): Likewise.
	* tests/test-diff-pkg.cc (in_out_specs): Test case additions
	* tests/data/Makefile.am: Include test files
	* tests/data/test-diff-pkg/tarpkg-1-dir1.tar.gz: New test data
	* tests/data/test-diff-pkg/tarpkg-1-dir2.tar.gz: New test data
	* tests/data/test-diff-pkg/tarpkg-1-report-0.txt: New test result

Signed-off-by: Sinny Kumari <sinny@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-20 17:05:16 +02:00
Dodji Seketeli
67435cf6cd Bug 19867 - abipkgdiff skips symbolic links
When comparing two directories, abipkgdiff skips symbolic links
pointing to ELF binaries altogether.  It only consider regular files.
This is a problem when abipkgdiff is given two directories that only
contain symbolic links.  In that case, abipkgdiff just performs no
comparison.

This patch makes abipkgdiff resolve the symbolic link to its target
file.

	* include/abg-tools-utils.h (maybe_get_symlink_target_file_path):
	Declare new function.
	* src/abg-tools-utils.cc (get_stat): Use lstat here, not stat.
	Update comment.
	* tools/abipkgdiff.cc (first_package_tree_walker_callback_fn)
	(second_package_tree_walker_callback_fn): Follow symbolic links to
	elf files to get their target paths, and only work with that
	target path.
	(maybe_get_symlink_target_file_path): Define new function.
	* test-diff-pkg/symlink-dir-test1-report0.txt New test material.
	* test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise.
	* test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-pkg.cc (in_out_spec): Run this test harness
	over the new test material above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 13:52:02 +01:00
Dodji Seketeli
61a0a8b2c0 Fix a typo in include/abg-tools-utils.h
* include/abg-tools-utils.h (enum abidiff_status): Fix typo in
	comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-16 20:50:45 +01:00
Dodji Seketeli
cf233e4fc2 Some small speed optimizations
* include/abg-ir.h (var_decl::get_naked_type): Declare new member function.
	* src/abg-ir.cc (var_decl::get_naked_type): Define it.
	(equals): For the var_decl overload, avoid copying symbol
	smart pointers.  Likewise for variable type smart pointers.
	(hash_type_or_decl): Avoid accessing canonical type smart pointer.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 15:13:20 +01:00
Dodji Seketeli
a6aa328731 Mist style cleanups
Various style cleanups and comment additions here and there.

	* include/abg-ir.h: Add missing comments.  Space cleanups.  Use
	shorter typedefs rather than long template instantiation names.
	Use string rather than the longer std::string.
	* src/abg-ir.cc: Space cleanups. Add missing comments.  User
	shorter typedefs.
	* src/abg-reader.cc: Likewise.
	* src/abg-writer.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 15:13:20 +01:00
Dodji Seketeli
cf8eba68c3 Implement string interning for Libabigail
This patch implements string interning optimization.  One can read
about the principles of this optimization at
https://en.wikipedia.org/wiki/String_interning.

The patch introduces an abigail::interned_string type, as well as an
abigail::interned_string_pool type.  Each environment type owns a
string pool and strings are interned in that pool for all types and
decls of that environments.  The interned_string has methods to
interact seemingly with std::string including a hashing function.  Of
course hashing and comparing interned_string is faster than for
std::string.

To enable ABI artifacts to intern strings, each constructor of ABI
artifacts now takes the environment it's constructed in as parameter.
From the environment, it can thus use the interned string pool.

The patch then changes declaration names to be of type
interned_string, and performs the necessary adjustments.  The hash
maps that hash strings coming from those declaration names are
adjusted to hash interned_string.

	* include/Makefile.am: Add the new abg-interned-str.h file to
	source distribution.
	* include/abg-corpus.h (corpus::corpus): Re-arrange the order of
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::priv::get_id): Return
	interned_string rather than std::string.
	(corpus::corpus): Re-arrange the order of parameters: take an
	environment as first parameter.  parameters: take an environment
	as first parameter.
	* include/abg-dwarf-reader.h (lookup_symbol_from_elf)
	(lookup_public_function_symbol_from_elf): Likewise.
	* src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab)
	(lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab)
	(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf)
	(lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf)
	(lookup_public_function_symbol_from_elf): Take an environment as
	first parameter and adjust.
	(build_translation_unit_and_add_to_ir)
	(build_namespace_decl_and_add_to_ir, build_type_decl)
	(build_enum_type, finish_member_function_reading)
	(build_class_type_and_add_to_ir, build_function_type)
	(read_debug_info_into_corpus, read_corpus_from_elf): Adjust.
	* include/abg-fwd.h: Include abg-interned-str.h
	(get_type_name, get_function_type_name, get_method_type_name):
	Return a interned_string, rather than a std::string.
	* include/abg-interned-str.h: New declarations for interned strings
	and their pool.
	* include/abg-ir.h (environment::intern): Declare new method.
	(elf_symbol::{g,s}et_environment): Likewise.
	(type_or_decl_base::type_or_decl_base): Make the default
	constructor private.
	({translation, type_or_decl_base}::set_environment)
	(set_environment_for_artifact): Take a const environment*.
	(elf_symbol::elf_symbol)
	(elf_symbol::create)
	(type_or_decl_base::type_or_decl_base)
	(translation::translation, decl_base::decl_base)
	(scope_decl::scope_decl, type_base::type_base)
	(type_decl::type_decl, scope_type_decl::scope_type_decl)
	(namespace_decl::namespace_decl)
	(enum_type_decl::enumerator::enumerator)
	(function_type::function_type, method_type::method_type)
	(template_decl::template_decl, function_tdecl::function_tdecl)
	(class_tdecl::class_tdecl, class_decl::class_decl): Take an
	environment.
	(type_or_decl_base::operator=)
	(enum_type_decl::enumerator::get_environment): Declare new method.
	(decl_base::{peek_qualified_name, peek_temporary_qualified_name,
	get_qualified_name, get_name, get_qualified_parent_name,
	get_linkage_name}, qualified_type_def::get_qualified_name)
	(reference_type_def::get_qualified_name)
	(array_type_def::get_qualified_name)
	(enum_type_decl::enumerator::{get_name, get_qualified_name})
	({var,function}_decl::get_id)
	(function_decl::parameter::{get_type_name, get_name_id}): Return
	an interned_string, rather than a std::string.
	(decl_base::{set_qualified_name, set_temporary_qualified_name,
	get_qualified_name, set_linkage_name})
	(qualified_type_def::get_qualified_name)
	(reference_type_def::get_qualified_name)
	(array_type_def::get_qualified_name)
	(function_decl::parameter::get_qualified_name): Take an
	interned_string, rather than a std::string.
	(class_decl::member_{class,function}_template::member_{class,function}_template):
	Adjust.
	* src/abg-ir.cc (environment_setter::env_): Make this be a pointer
	to const environment.
	(environment_setter::visit_begin): Adjust.
	(interned_string_pool::priv): Define new type.
	(interned_string_pool::*): Define the method declared in
	abg-interned-str. h.
	(operator==, operator!=, operator+): Define operator for interned_string and
	std::string
	(operator<<): Define for interned_string.
	(translation_unit::priv::env_): Make this be a pointer to const
	environment.
	(translation_unit::priv::priv): Take a pointer to const
	environment.
	(elf_symbol::priv::env_): New data member.
	(elf_symbol::priv::priv): Adjust.  Make an overoad take an
	environment.
	(translation_unit::{g,s}et_environment): Adjust.
	(interned_string_bool_map_type): New typedef.
	(environment::priv::classes_being_compared_): Make this hastable
	of string be a hashtable of interned_string.
	(environment::priv::string_pool_): New data member.
	(environment::{get_void_type_decl,
	get_variadic_parameter_type_decl}): Adjust.
	(type_or_decl_base::priv::env_): Make this be a pointer to const
	environment.
	(type_or_decl::base::priv::priv): Adjust.
	(type_or_decl_base::set_environment)
	(set_environment_for_artifact): Take a pointer to const
	environment.
	(elf_symbol::{g,s}et_environment, environment::intern)
	(type_or_decl_base::operator=): Define new methods.
	(decl_base::priv::{name_, qualified_parent_name_,
	temporary_qualified_name_, qualified_name_, linkage_name_}): Make
	these data member be of tpe interned_string.
	(decl_base::priv::priv): Make this take an environment. Adjust.
	(decl_base::{peek_qualified_name, peek_temporary_qualified_name,
	get_linkage_name, get_qualified_parent_name, get_name,
	get_qualified_name}, get_type_name, get_function_type_name)
	(get_method_type_name, get_node_name)
	(qualified_type_def::get_qualified_name)
	(pointer_type_def::get_qualified_name)
	(array_type_def::get_qualified_name)
	(enum_type_decl::enumerator::get_qualified_name)
	(var_decl::get_id, function_decl::get_id)
	(function_decl::parameter::get_{name_id, type_name}): Return an
	interned_string.
	(decl_base::{set_qualified_name, set_temporary_qualified_name})
	(qualified_type_def::get_qualified_name)
	(pointer_type_def::get_qualified_name)
	(reference_type_def::get_qualified_name)
	(array_type_def::get_qualified_name)
	(function_decl::parameter::get_qualified_name): Take an
	interned_string.
	(decl_base::{set_name, set_linkage_name}): Intern the std::string
	passed in parameter.
	(equals): In the overload for decl_base, adjust for a little speed
	optimization that is justified by profiling.
	(pointer_type_def::priv::{internal_qualified_name_,
	temp_internal_qualified_name_}): Make these data member be
	interned_string.
	(enum_type_decl::enumerator::priv::env_): New data member.
	(enum_type_decl::enumerator::priv::{name_, qualified_name}): Make
	these data member be of type interned_string.
	(enum_type_decl::enumerator::get_environment): New method.
	(enum_type_decl::enumerator::priv::priv) Adjust.
	(typedef_decl::operator==): Implement a little speed optimization.
	(var_decl::priv::nake_type_): New data member.
	(var_decl::priv::id_): Make this data member be of type
	interned_string.
	(equals): In the overload for var_decl, function_type,
	function_decl, adjust for the use of interned_string.
	(function_decl::priv::id_): Make this be of type interned_string.
	(scope_decl::{add_member_decl, insert_member_decl})
	(lookup_function_type_in_translation_unit)
	(synthesize_type_from_translation_unit, lookup_node_in_scope)
	(lookup_type_in_scope, scope_decl::scope_decl)
	(qualified_type_def::qualified_type_def)
	(qualified_type_def::get_qualified_name)
	(pointer_type_def::pointer_type_def)
	(reference_type_def::reference_type_def)
	(array_type_def::array_type_def, array_type_def::append_subrange)
	(array_type_def::get_qualified_name)
	(enum_type_decl::enum_type_decl)
	(enum_type_decl::enumerator::get_qualified_name)
	(enum_type_decl::enumerator::set_name)
	(typedef_decl::typedef_decl, var_decl::var_decl)
	(function_type::function_type, method_type::method_type)
	(function_decl::function_decl)
	(function_decl::parameter::parameter)
	(class_decl::priv::comparison_started)
	(class_decl::add_base_specifier)
	(class_decl::base_spec::base_spec)
	(class_decl::method_decl::method_decl)
	(type_tparameter::type_tparameter)
	(non_type_tparameter::non_type_tparameter)
	(template_tparameter::template_tparameter)
	(type_composition::type_composition)
	(function_tdecl::function_tdecl, class_tdecl::class_tdecl)
	(qualified_name_setter::do_update): Adjust.
	(translation_unit::translation_unit, elf_symbol::elf_symbol)
	(elf_symbol::create, type_or_decl_base::type_or_decl_base)
	(decl_base::decl_base, type_base::type_base)
	(type_decl::type_decl, scope_type_decl::scope_type_decl)
	(namespace_decl::namespace_decl)
	(enum_type_decl::enumerator::enumerator, class_decl::class_decl)
	(template_decl::template_decl, function_tdecl::function_tdecl)
	(class_tdecl::class_tdecl): Take an environment.
	* src/abg-comparison.cc
	(function_suppression::suppresses_function): Adjust.
	* src/abg-reader.cc (read_translation_unit)
	(read_corpus_from_input, build_namespace_decl, build_elf_symbol)
	(build_function_parameter, build_function_decl, build_type_decl)
	(build_function_type, build_enum_type_decl, build_enum_type_decl)
	(build_class_decl, build_function_tdecl, build_class_tdecl)
	(read_corpus_from_native_xml): Likewise.
	* src/abg-writer.cc (id_manager::m_cur_id): Make this mutable.
	(id_manager::m_env): New data member.
	(id_manager::id_manager): Adjust.
	(id_manager::get_environment): New method.
	(id_manager::{get_id, get_id_with_prefix}): Return an
	interned_string.
	(type_ptr_map): Make this be a hash map of type_base* ->
	interned_string, rather a type_base* -> string.
	(write_context::m_env): New data member.
	(write_context::m_type_id_map): Make this data member be mutable.
	(write_context::m_emitted_type_id_map): Make this be a hash map of
	interned_string -> bool, rather than string -> bool.
	(write_context::write_context): Take an environment and adjust.
	(write_context::get_environment): New method.
	(write_context::get_id_manager): New const overload.
	(write_context::get_id_for_type): Return an interned_string; adjust.
	(write_context::{record_type_id_as_emitted,
	record_type_as_referenced}): Adjust.
	(write_context::type_id_is_emitted): Take an interned_string.
	(write_context::{type_is_emitted,
	record_decl_only_type_as_emitted}): Adjust.
	(write_translation_unit, write_corpus_to_native_xml, dump):
	Adjust.
	* tools/abisym.cc (main): Adjust.
	* tests/data/test-read-write/test22.xml: Adjust.
	* tests/data/test-read-write/test23.xml: Adjust.
	* tests/data/test-read-write/test26.xml: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 15:13:20 +01:00
Dodji Seketeli
445923157d Update copyright notice
* include/abg-corpus.h: Update copyright notice.
	* include/abg-dwarf-reader.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-ir.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 15:10:00 +01:00
Dodji Seketeli
6668baaff4 Add missing inequality operators for ABI artifacts
Some ABI artifact declared in the internal representation don't have
inequality operator (!=) declared.  I thought relying on the !=
operator provided by std::rel_ops would be enough, but it's not.
Sometimes, especially for smart pointers to ABI artifacts we do not
want the != operator of shared_ptr to be picked by argument dependent
lookup.  Rather, we want the deep operator!= to be picked up.  In certain
cases, this was causing subtle spurious change comparison reports.

This patch thus systematically declares (and defines) operator!=
whenever operator== is declared.

	* include/abg-ir.h ({translation_unit, elf_symbol::version,
	context_rel, decl_base, type_base, type_decl,
	array_type_def::subrange_type, enum_type_def::enumerator,
	dm_context_rel, template_parameter}::operator!=): Declare.
	(operator==): Make the overload form translation_unit_sptr,
	scope_decl_sptr, class_decl::base_spec_sptr,
	class_decl::member_function_template_sptr,
	class_decl::member_class_template_sptr take const references.
	(operator!=): Declare an an overload for the non-member operator
	!= of translation_unit_sptr, elf_symbol_sptr,
	type_or_decl_base_sptr, type_base_sptr, scope_decl_sptr,
	type_decl, qualified_type_def_sptr, pointer_type_def_sptr,
	reference_type_def_sptr, enum_type_decl_sptr, class_decl_sptr,
	class_decl::base_spec_sptr,
	class_decl::member_function_template_sptr,
	class_decl::member_class_template_sptr.
	* src/abg-ir.cc ({translation_unit, elf_symbol::version,
	context_rel, decl_base, type_base, type_decl,
	array_type_def::subrange_type, enum_type_def::enumerator,
	dm_context_rel, template_parameter}::operator!=): Define.
	(operator==): Make the overload for translation_unit_sptr,
	scope_decl_sptr, class_decl::base_spec_sptr,
	class_decl::member_function_template_sptr,
	class_decl::member_class_template_sptr take const references.
	(operator!=): Define an an overload for the non-member operator !=
	of translation_unit_sptr, elf_symbol_sptr, type_or_decl_base_sptr,
	type_base_sptr, scope_decl_sptr, type_decl,
	qualified_type_def_sptr, pointer_type_def_sptr,
	reference_type_def_sptr, enum_type_decl_sptr, class_decl_sptr,
	class_decl::base_spec_sptr,
	class_decl::member_function_template_sptr,
	class_decl::member_class_template_sptr.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-23 14:00:07 +01:00
Dodji Seketeli
e62901963f Bug 19658 - Type canonicalization slow for the 2nd binary loaded
When loading two binaries (e.g, when the library is used by abidiff),
and when the second one does have deep types (e.g, classes with
recursively deep hierarchies) with lots of duplicated types in lots of
translation units, canonicalizing the types of the second binaries can
take a *lot* of time, given the quadratic nature of the structural
type comparisons that take place and the cheer number of those type
comparisons (because of the duplication).

There is already an optimization based on the One Definition Rule in
the canonicalization code.  That optimization avoids structural
comparison of types of the same corpus which have the same name.  But
then, this optimization only works on types of the first corpus.

As soon as we are loading a second corpus, all types being
canonicalized are coming from a corpus that is different from the
first corpus, by definition.  So a structural comparison is taking
place for *all* those types.

The patch extends the existing optimization to make it work on the
second corpus being loaded.  Once a type from the second corpus is
canonicalized, the canonical type is cached inside the corpus.  Then,
later, when a type with the same name has to be canonicalized, the
system looks inside the cache of that corpus to see if there is a
canonicalized type the same name.

I tested the patch on this command:

    abipkgdiff --d1 nss-debuginfo-3.19.1-8.el6_7.i686.rpm \
               --d2 nss-debuginfo-3.21.0-0.1.el6_7.i686.rpm \
               nss-3.19.1-8.el6_7.i686.rpm \
               nss-3.21.0-0.1.el6_7.i686.rpm

I whitnessed a x10 speedup, at least.

On binaries that don't have a lot of duplicated deep types, the patch
doesn't have any noticeable effect.  At lesat It doesn't slow things
down in that case.

	* include/abg-corpus.h (corpus::{record_canonical_type,
	lookup_canonical_type}): Declare new member functions.
	* src/abg-corpus.cc (corpus::priv::canonical_types_): New data
	member.
	(corpus::{record_canonical_type, lookup_canonical_type}): Define
	new member functions.
	* src/abg-ir.cc (type_base::get_canonical_type_for): Cache the
	canonical type inside the corpus of the type being canonicalized.
	Then later when canonicalizing another type, lookup in the cache
	inside its corpus to see if there is a type with the same name.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-18 16:06:13 +01:00
Dodji Seketeli
9cef1838c9 Add --verbose option to abidiff
This is useful to see the progress of e.g type canonicalization and
visually spot where it takes times on some big binaries.

To do this, this patch enables logging in libabigail itself too.

	* doc/manuals/abidiff.rst: Add documentation for new --verbose
	option.
	* include/abg-dwarf-reader.h (set_do_log): Declare new function.
	* src/abg-dwarf-reader.cc (read_context::do_log_): New data
	member.
	(read_context::read_context): Initialize the new data member.
	(read_context::do_log): Define accessors.
	(set_do_log): Define new function;
	(read_context::canonicalize_types_scheduled)
	(read_debug_info_into_corpus): Add logs.
	* tools/abidiff.cc (options::do_log): New data member.
	(options::options): Initialize it.
	(display_usage): Add an usage string for --verbose.
	(parse_command_line): Parse the new --verbose option.
	(main): Set the dwarf reader's context wrt presence of the
	--verbose option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-18 16:06:13 +01:00
Dodji Seketeli
1bb3461d1d Bug 19638 - DWARF reader fails to link clone function to its declaration
There are three mains issues that cause the reported problem.  Let's
look at them closely.

Suppose there is a DIE of a member function Klass::clone_of_foo, which
is a clone of the DIE of the function Klass_foo, which is the concrete
instance of the DIE of the declaration of Klass::foo.

When libabigail's DWARF reader sees the DIE for Klass::clone_of_foo,
it fails to get the context of the declaration of Klass::clone_of_foo
-- which is Klass::foo.

So, in the model built by libabigail, the symbol of
Klass::clone_of_foo never gets associated to Klass::foo.  It thus
looks like Klass::clone is never defined.  It also looks like that
symbol is unreferenced.  From there, a number of bad things happen.
This is the first root cause of the reported problem.  I call it issue
1/.

2/ While looking at this, I noticed that libabigail uses the
underlying symbol name of a given function as the linkage name of that
function, rather than using the value of the DW_AT_linkage_name DWARF
property.  This usually works, until the the function has a symbol
which has several aliases.  In that case, depending on the symbol
alias that is used, a given function can have different linkage names.
This causes problems later at comparison time.  This is issue 2/.

3/ I also noticed that in the libabigail model, even if type Klass
does have all its member functions (including Klass::foo) defined in
in a particular translation unit TU1 , the same Klass in another
translation unit TU2 might not have that Klass::foo defined, just
because that function is not used in TU2.  So after type
canonicalization, if the version of Klass that is kept is the one from
TU2, we end up with a type Klass *NOT* having Klass::foo defined.
Sometimes, it's just that one member function in the canonical type
doesn't have any underlying symbol, whereas the same member function
in another type of the same class of equivalence as the canonical type
does have that an underlying symbol.  This is issue 3/.

To address issue 1/ the patch fixes build_ir_node_from_die, in the
case where a DW_TAG_subprogram DIE is being handled.  It fixes the
case of finding the root interface of the clone of a function
definition.  The patch also fixes a bug in build_function_decl that
prevents it to update the linkage name of a function, *if* that
function already had one.  This was preventing build_function_decl to
adjust the linkage name of a function which is a clone of an original
function which already had a non-empty linkage name.

To address 2/ the patch makes function_decl::get_id return the linkage
name of the function, *if* it exists (rather than primarily returning
the ID of the underlying symbol).

To address 3/ the patch implements the copying of member functions or
underlying function symbols missing from the canonical type -- but
otherwise present in the type that has just been canonicalized.

	* include/abg-ir.h (decl_base::set_linkage_name): Make this member
	function virtual.
	(class_decl::string_mem_fn_ptr_map_type): Define new member type.
	(class_decl::find_member_function): Declare new member function.
	(copy_member_function): Declare new function.  Declare it as
	friend of class_decl.
	(method_decl::set_linkage_name): Declare an overload for this
	virtual function.
	* src/abg-dwarf-reader.cc (build_function_decl): Allow updating of
	linkage_name even if the linkage_name was already defined.
	(build_ir_node_from_die): In the case DW_TAG_subprogram, make the
	lookup of scope of the DIE work even if it has both an abstract
	origin and a specification (DW_AT_abstract_origin and
	DW_AT_specification).
	* src/abg-ir.cc (maybe_adjust_canonical_type): Define new
	function.
	(canonicalize): Use it.
	(function_decl::get_id): Return the linkage name first, if it
	exist.
	(class_decl::priv::mem_fns_map_): New data member.
	(class_decl::find_member_function): Define new member function.
	(class_decl::method_decl::set_linkage_name): Likewise.
	(class_decl::add_member_function): Update the new data member
	class_decl::priv::mem_fns_map_.
	(copy_member_function): Define new static function.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.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.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-17 16:30:01 +01:00
Dodji Seketeli
f8761a48af Add function lookup by linkage name to libabigail::corpus
Until now, it was not possible to lookup a function declaration from a
corpus, using a symbol name for the function.  This patch adds that
functionnality, which is useful, at least for debugging purposes.

	* include/abg-corpus.h (corpus::lookup_functions): Declare new
	member function.
	* src/abg-corpus.cc (class corpus::exported_decls_builder::priv):
	Make class corpus be a friend of this type.
	(corpus::exported_decls_builder::priv::add_fn_to_id_fns_map): Fix
	a thinko that was preventing the fn_id -> functions map from ever
	being filled.  Fix this function to make it associate each aliases
	of a given function to the function, in the hash table.
	(corpus::lookup_functions): Define new member function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-17 14:20:43 +01:00
Dodji Seketeli
421aa4ab5f Fix style cleanups
* include/abg-ir.h (method_type::{method_type, set_class_type,
	get_type, set_type}): Use type_base_sptr and class_decl_sptr
	instead of the full non-typedefed name.
	(method_type):Do some cleanups in the definition of the
	convenience typedefs.
	* src/abg-ir.cc (method_type::{method_type, set_class_type,
	get_type, set_type}): Use type_base_sptr and class_decl_sptr
	instead of the full non-typedefed name.
	* src/abg-writer.cc (write_class_decl): Add a comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-17 13:08:24 +01:00
Dodji Seketeli
b0335a42d5 Prefix abidiff error message with the 'abidiff' program name
* include/abg-tools-utils.h (emit_prefix): Declare new function.
	(check_file): Add a new parameter with a default value, so that
	existing code keeps compiling.
	* src/abg-tools-utils.cc (emit_prefix): Define new function.
	(check_file): Use the emit_prefix function and give it the program
	name passed as a new parameter.
	* tools/abidiff.cc (display_usage, main): Use the new emit_prefix
	to prefix error messages.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 10:12:38 +01:00
Dodji Seketeli
4b7e295b20 Bug 19596 - Incorrect exit status for incompatible ABI change
The comparison engine doesn't take virtual offset changes into account
when deciding if a diff node carries an incompatible change.  This is
obviously an oversight.

Fixed thus.

	* include/abg-comparison.h (enum diff_category): Adjust the
	comment for enumerator VIRTUAL_MEMBER_CHANGE_CATEGORY; changes of
	this category are incompatible ABI changes.
	(corpus_diff::diff_stats::num_func_with_virtual_offset_changes):
	Declare new accessors.
	* src/abg-comparison.cc
	(corpus_diff::diff_stats::priv::num_func_with_virt_offset_changes):
	New data member.
	(corpus_diff::diff_stats::priv::priv): Initialize the new data
	member.
	(corpus_diff::diff_stats::num_func_with_virtual_offset_changes):
	Define new accessors.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the
	new accessor to set the number of functions with virtual offset
	changes onto the stats data structure.
	(corpus_diff::has_incompatible_changes): Take functions with
	virtual offset changes into account.
 	* tests/test-abidiff-exit.cc: New test harness to test for exit
	codes of abidiff.
	* tests/Makefile.am: Build the new test harness runtestabidiff
	from the test-abidiff-exit.cc source file.
	* tests/data/test-abidiff-exit/test1-voffset-change-report0.txt:
	New reference test output.
	* tests/data/test-abidiff-exit/test1-voffset-change-v0.cc: New
	test input source code.
	* tests/data/test-abidiff-exit/test1-voffset-change-v0.o: New test input.
	* tests/data/test-abidiff-exit/test1-voffset-change-v1.cc: New
	test input source code.
	* tests/data/test-abidiff-exit/test1-voffset-change-v1.o: New test input.
	* tests/data/Makefile.am: tests/data/Makefile.am: Add the new test
	inputs above to the source distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-10 21:31:53 +01:00
Dodji Seketeli
2f88edd3b3 Fix synthesizing of pointer type
Libabigail fails to to synthesize a non-existing pointer type to an
existing type.

This makes abicompat fail in weak mode when trying to detect changes
to a function type where the parameter is a pointer to a structure
which changed.  In the application, the function is invoked and a
pointer to the structure is passed to it.  It appears that the type of
structure is defined in the debug info of the application, but not the
pointer to that structure.  So abicompat needs to synthesize that
pointer to struct in order to synthesize the type of the function, and
so, compare it to the type of the function coming from the library.

It appears that synthesizing a pointer type (to an existing type) is
not supported.  Only synthesizing qualified type was supported.

This patch adds support for that and thus fixes the abicompat test
case that is attached.

	* include/abg-ir.h: Update copyright.
	* src/abg-ir.cc (synthesize_type_from_translation_unit): Support
	synthesizing pointer types.

	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so: New
	test input.
	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-app.c: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v0.c: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v0.h: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v1.c: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v1.h: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-report-0.txt: Likewise.
	* tests/data/Makefile.am: Add the new test input files to source
	distribution.
	* tests/test-abicompat.cc (in_out_specs): Add the new test inputs
	above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-03 13:00:51 +01:00
Dodji Seketeli
11c89cad3e Pass parm of elf_symbol::add_alias by reference
* include/abg-ir.h (elf_symbol::add_alias): Pass parameter by
	reference.
	* src/abg-ir.cc (elf_symbol::add_alias): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-20 14:02:04 +01:00
Dodji Seketeli
640b3a2f59 Bug 19141 - Libabigail doesn't support common ELF symbols
Libabigail's internal representation of elf symbols fails to account
for common symbols in relocatable files.  There can be several common
symbols of the same name (defined in a section of SHN_COMMON kind).
In that case, Libabigail wrongly considers these multiple instances of
the same common symbol as being alias, and that breaks some
basic assumptions about aliases.  Oops.

This patch adds support for the common symbols (and the fact that
relocatable files can have several instances of the same common
symbol) and amends the ELF reader to make it properly represent those.
	* include/abg-ir.h (elf_symbol::elf_symbol): Take a new flag to
	say if the symbol is common.
	(elf_symbol::{is_common_symbol, has_other_common_instances,
	get_next_common_instance, add_common_instance}): New member functions.
	* src/abg-ir.cc (elf_symbol::priv::{is_common_,
	next_common_instance_): New data members.
	(elf_symbol::priv::priv): Adjust.
	(elf_symbol::{elf_symbol, create}): Take a new flag to say if the
	symbol is common.
	(textually_equals): Adjust to account for symbol common-ness.
	(elf_symbol::{is_common_symbol, has_other_common_instances,
	get_next_common_instance, add_common_instance}): Define new member
	functions.
	(elf_symbol::add_alias): Drive-by fix; compare symbols using
	pointer value.  Value comparison is not necessary.
	* 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): Adjust the creation
	of the symbol to account for common-ness.
	(read_context::load_symbol_maps): Recognize instances of a given
	common symbol and represent them as such.  Do not mistake this
	with symbol aliases.
	* src/abg-reader.cc (build_elf_symbol): Adjust the creation of the
	symbol to account for common-ness.
	* src/abg-writer.cc (write_elf_symbol): Adjust symbol
	serialization to account common-ness.
	* tests/data/test-types-stability/pr19141-get5d.o: Add new test
	binary input.
	* tests/data/test-types-stability/pr19142-topo.o: Likewise.
	* tests/data/Makefile.am: Add the new test inputs to source distribution.
	* tests/test-types-stability.cc (elf_paths): The the new test
	inputs into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-20 13:37:52 +01:00
Dodji Seketeli
c3869ecc7b Bug 19434 - invalid character in attribute value
* include/abg-tools-utils.h (string_is_ascii_identifier): Declare
	new function.
	* src/abg-tools-utils.cc (string_is_ascii_identifier): Define new function.
	* src/abg-dwarf-reader.cc (build_function_type): Discard parameter
	name if it's made of non-identifier ascii characters.
	* tests/data/test-types-stability/pr19434-elf0: New test binary input file.
	* tests/data/Makefile.am: Add the new test input to source distribution.
	* tests/test-types-stability.cc: Test the new test input into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-18 18:23:19 +01:00
Dodji Seketeli
f275939df2 Use worker threads pattern to speed up some tests
We are going to need to speed up more and more tests, and coding directly
with libpthread for that can be tedious and bug-prone.  So I devised an
implementation for the worker threads design pattern instead, and used
it to speed up some tests.

	* include/Makefile.am: Add the new abg-workers.h to source
	distribution.
	* include/abg-workers.h: New file.
	* src/Makefile.am: Add the new abg-worker.cc to source
	distribution.
	* src/abg-workers.cc: New file.
	* tests/test-utils.cc: Update copyright.  Make get_src_dir() and
	get_build_dir() return a const char*, as opposed to returning a
	string.  Make that const char reside in thread local storage, so
	that two concurrent threads can safely call these functions in
	parallel, without any race.
	* tests/test-utils.h: Make get_src_dir() and get_build_dir()
	return a const char*, as opposed to returning a string.
	* tests/test-abicompat.cc: Update copyright.  Adjust for
	get_src_dir() and get_build_dir() change.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.  Use the new task queue
	type to run these tests in parallel.
	* tests/test-diff-filter.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-18 18:23:18 +01:00
Dodji Seketeli
64375c64d3 Make enum values take 64 bits on all platforms
The is still some changes in the way values of enumerators are
represented in 32 and 64 bits systems.  This is because the type of
enumerators is size_t which 32 bits on 32 bits systems and 64 bits on
64 bits systems.  The problem is, the output of, abidw can thus be
different on 32 and 64 bits, making some tests output be different on
these platforms.

This patch thus uses uint64_t to represent enumerator values on all
platforms.

	* include/abg-ir.h: Include stdint.h for int64_t.
	(enumerator::enumerator): Take an int64_t value for the value of
	the enumerator.
	(enumerator::{s,g}et_value): Take/return an int64_t value.
	* src/abg-ir.cc (enum_type_decl::enumerator::priv): Store the
	value in an int64_t.
	(enumerator::priv::priv): Take a int64_t for the value.
	(enum_type_decl::enumerator::enumerator): Likewise.
	(enum_type_decl::enumerator::{s,g}et_value): Take/returnan int64_t
	value.
	* src/abg-dwarf-reader.cc (die_unsigned_constant_attribute): Take
	an uint64_t value.
	(die_signed_constant_attribute): Take an int64_t value.
	(die_location, die_size_in_bits, die_access_specifier)
	(die_virtuality, die_is_virtual, die_is_declared_inline)
	(build_translation_unit_and_add_to_ir, build_type_decl)
	(build_enum_type, build_pointer_type_def, build_array_type):
	Adjust.
	* src/abg-reader.cc (build_enum_type_decl): Adjust.
	* src/abg-writer.cc (write_enum_type_decl): Do not cast the result
	of enumerator::get_value() anymore, it's value is now a int64_t.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-11 11:22:39 +01:00
Dodji Seketeli
5c8c049e70 Bug 19138 - Failure to relate variables address from DWARF and ELF
In this problem report libabigail's DWARF reader wrongly looks up the
address of variables (that it got from DWARF) in the .bss section of
the ELF file.  But then, in these files (generated by the Intel C++
compiler) the variables we are looking at have their addresses in the
.data1 section.

This patch changes the DWARF/ELF reader to make it look for variable
addresses in .data, .data1, .rodata and .bss sections, as it should
be.

	* include/abg-dwarf-reader.h (elf_type::ELF_TYPE_RELOCATABLE): New
	enumerator.
	* src/abg-dwarf-reader.cc (find_section): Factorize this from ...
	(find_text_section, find_bss_section): ... these.
	(find_rodata_section, find_data_section, find_data1_section):
	Define new static functions.
	(elf_file_type): Move this static function definition up.
	(read_context::{get_elf_file_type, address_is_in_section,
	get_data_section_for_variable_address}): New member functions.
	(read_context::maybe_adjust_fn_sym_address): Adjust comment.
	Adjust to use the new
	read_context::get_data_section_for_variable_address().
	* tests/data/test-types-stability/pr19138-elf0: New test input
	binary.
	* tests/data/Makefile.am: Add the new test input binary to the
	test suite.
	* tests/test-types-stability.cc (elf_paths): Take it into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-08 22:38:58 +01:00
Dodji Seketeli
d50882bf4f Make class_decl::base_spec class follow the pimpl pattern
* include/abg-ir.h (class_decl::base_spec::priv): Declare new
	private data type.
	(class_decl::base_spec::priv_): Declare new pimpl data member.
	(class_decl::base_spec::{base_class_, offset_in_bits_,
	is_virtual_}): Remove.
	(class_decl::base_spec::{get_base_class, get_is_virtual,
	get_offset_in_bits}): Make these member functions out of line.
	* src/abg-ir.cc (struct class_decl::base_spec::priv): New type.
	(class_decl::base_spec::{get_base_class, get_is_virtual,
	get_offset_in_bits}): Define these functions here.
	(class_decl::base_spec::base_spec): Adjust because now there is
	only one pimpl data member to initialize.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-04 19:57:45 +01:00
Ondrej Oprala
6a7566d513 Add the option of printing the file, line and column information about a type being reported.
* bash-completion/abicompat: Complete the new "--no-show-locs" option.
	* bash-completion/abidiff: Likewise.
	* bash-completion/abidw: Likewise.
	* bash-completion/abipkgdiff: Likewise.
	* doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option.
	* doc/manuals/abidiff.rst: Likewise.
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-comparison.h (show_locs): Add declarations.
	* src/abg-comparison.cc: (diff_context::priv): Add a new switch
	called "show_locs_" and set its default value to false.
	(report_loc_info): New function. Outputting the extra information
	is conditionalized based on the associated diff contexts settings.
	(show_locs): define a getter/setter for
	diff_context::priv::show_locs_.
	({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm,
	typedef,corpus}_diff::report): Call report_loc_info when
	appropriate.
	(maybe_report_diff_for_member): Likewise.
	(represent): Accept a const reference to a diff_context_sptr as a first
	argument and call report_loc_info on its second argument.
	* src/abg-dwarf-reader.cc:
	* tests/data/Makefile.am: Add the new test reference files.
	* tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test
	reference output.
	* tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise.
	* tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise.
	* tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise.
	* tests/test-abidiff.cc: Explicitly create a diff context and turn off
	location emitting.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-abicompat.cc: Add --no-show-locs to all existing test
	arguments. Run a few of the existing tests again, but without this
	option.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tools/abicompat.cc: Handle the new "--no-show-locs" option.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-12-15 12:32:55 +01:00
Dodji Seketeli
b017143876 [PERF] Access naked pointers for canonical types and function types
Performance profiling has shown that accessing shared_ptr to canonical
types and function type during type comparison was noticeable slowing
down the process.  This patch thus access naked pointers for canonical
types and function types at these performance hot spots.

The profiling took place while running abidw --abidiff on the
r300_dri.so binary.

	* include/abg-ir.h (type_base::get_naked_canonical_type): Declare
	new accessor.
	(function_decl::get_naked_canonical_type): Likewise.
	(function_decl::set_type): Pass a reference to the shared_ptr.
	* src/abg-ir.cc (type_base::priv::naked_canonical_type): New data
	member.
	(type_base::priv::priv): Initialize it.
	(canonicalize): Set the naked canonicalize type when we set its
	shared pointer.
	(type_base::get_naked_canonical_type): Define new accessor.
	({pointer_type_def,reference_type_def,function_type,class_decl}::operator==):
	Use naked canonical pointers rather than the slower shared_ptr to
	canonical pointers.
	(function_decl::priv::naked_type_): New data member.
	(function_decl::priv::priv): Initialize it.
	(function_decl::get_naked_type): Define new accessor.
	(function_decl::set_type): Pass a reference to the shared_ptr .
	(equals): In the overload for function_decl, use the faster naked
	pointers to the type of the function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-11 11:19:57 +01:00
Dodji Seketeli
c0de97846c [PERF] Turn some pimpl pointers into naked pointers
The private data pointers of libabigail IR types are usually managed
using shared_ptr.  But performance profiling has shown that
de-referencing some of these private data shared_ptr can have a
noticeable performance impact.  This is because de-referencing
shared_ptr involves some locking that show up on some performance
profile.

So, for decl_base, type_base, and function_decl, this patch replaces
the private data shared pointers by naked pointers.  This speeds up
the access to private data members, especially during comparison of
class pointer, reference and function types.  And that has a
noticeable impact when libabigail handles huge binaries with lots of
functions an type, like r300_dri.so.

	* include/abg-ir.h ({decl_base, type_base, function_decl}::priv_)
	Make this a naked pointer to priv, rather than a shared_ptr<priv>.
	* src/abg-ir.cc (decl_base::~decl_base): Destroy the private data
	pointer, aka pimpl pointer.
	(type_base::~type_base): Likewise.
	(function_decl::~function_decl): Likewise.
	(class_decl::~class_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-11 11:19:57 +01:00
Dodji Seketeli
1466510881 [PERF] Pass a bunch of perf-sensitive smart pointers by reference
* include/abg-fwd.h (lookup_type_in_corpus, lookup_type_in_scope)
	(lookup_var_decl_in_scope): Pass the decls smart pointers by
	reference.
	* src/abg-ir.cc (lookup_type_in_corpus, lookup_type_in_scope)
	(lookup_var_decl_in_scope): Pass the decls smart pointers by
	reference, for performance reasons.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-11 11:19:57 +01:00
Dodji Seketeli
0ec2416837 Bug 19126 - abidw segv on a dwz compressed version of r300_dri.so
Suppose a declaration D (which locus is in a file F) is imported at an
offset offset of O1 into a compilation unit C1 and at an offset O2
(using DW_TAG_imported_unit) into a compilation unit C2.

When the DWARF reader creates the ABI artifact for D in O1, its
location is encoded by a location manager that is handled by C1.

At O2 (in C2) the ABI artifact for D (created at O1, in C1) is
re-used.  But then, to decode the location of D, the DWARF reader
wrongly uses the location manager that is handled by C2.  It should
use the location manager of C1, because that is the one used to encode
the location of D.

It picks the wrong location manager because it picks the wrong
translation unit for D. Right now, the translation unit for a given
declaration is the "current" translation unit at the moment the DIE
was being inspected.  And that is wrong when imported type units kick
in.

1/ More generally, each ABI artifact should be associated with its
translation unit, which is the current translation unit when the
artifact was created.  As there is just one copy of D, its translation
unit should always be the same.

2/ Also, the location should ensure that about the location manager used
to encode it is the same one used to decode it, so that this kind of
bug cannot arise.

This patch fixes the issue by doing 1/ and 2/.  The r300_dri.so test
case on which is was failing is not added to the test suite because
it's too big.  It was taking more than 55 minutes to have complete
abidw --abidiff complete on that binary, on my machine.  So I am going
to work on the performance side of things, I think.

	* include/abg-ir.h (class location_manager): Forward declare it
	before class location.
	(location::loc_manager_): New data member.
	(location::location): Take the location manager in one overload
	and initialize the new loc_managers_ in all the overloads.
	(location::get_location_manager): New getter.
	(location::expand): New member function.
	(location::*): Add API doc to all entry points.
	(location_manager::expand_location): Take a const location.
	(type_or_decl_base::set_corpus): Remove.
	(type_or_decl_base::{get,set}_translation): New accessors.
	(decl_base::{decl_base,get_location}): Take or return a reference
	on location.
	(scope_decl::scope_decl): Likewise.
	(type_decl::type_decl): Likewise.
	(namespace_decl::namespace_decl): Likewise.
	(qualified_type_def::qualified_type_def): Likewise.
	(pointer_type_def::pointer_type_def): Likewise.
	(reference_type_def::reference_type_def): Likewise.
	(array_type_def::subrange_type::{subrange_type,
	get_location}): Likewise.
	(enum_type_decl::enum_type_decl): Likewise.
	(typedef_decl::typedef_decl): Likewise.
	(var_decl::var_decl): Likewise.
	(function_decl::function_decl): Likewise.
	(function_decl::parameter::parameter): Likewise.
	(template_decl::template_decl): Likewise.
	(type_tparameter::type_tparameter): Likewise.
	(non_type_tparameter::non_type_tparameter): Likewise.
	(function_tdecl::function_tdecl): Likewise.
	(class_tdecl::class_tdecl): Likewise.
	(class_decl::class_decl): Likewise.
	(class_decl::method_decl::method_decl): Likewise.
	* src/abg-ir.cc (location::expand_location): Define new member
	function.
	(type_or_decl_base::priv::corpus_): Remove.
	(type_or_decl_base::priv::translation_unit_): New data member.
	(type_or_decl_base::priv::priv): Adjust.
	(type_or_decl_base::set_corpus): Remove.
	(type_or_decl_base::get_corpus): Adjust.
	(type_or_decl_base::{get,set}_translation_unit): New member
	functions.
	(decl_base::priv::priv): Take a reference to location.
	(decl_base::decl_base): Likewise.
	(decl_base::get_location): Return a reference to location.
	(location_manager::create_new_location): Adjust.
	(location_manager::expand_location): Take a reference to location.
	(translation_unit::get_global_scope()): Adjust.
	(translation_unit::bind_function_type_life_time): Likewise.
	(scope_decl::{add,insert}_member_decl): Adjust.
	(get_translation_unit): Likewise.
	(type_decl::type_decl): Take a reference to location.
	(namespace_decl::namespace_decl): Likewise.
	(qualified_type_def::qualified_type_def): Likewise.
	(pointer_type_def::pointer_type_def): Likewise.
	(reference_type_def::reference_type_def): Likewise.
	(array_type_def::subrange_type::priv::priv): Likewise.
	(array_type_def::subrange_type::{subrange_type,
	get_location}): Likewise.
	(enum_type_decl::enum_type_decl): Likewise.
	(typedef_decl::typedef_decl): Likewise.
	(var_decl::var_decl): Likewise.
	(function_decl::function_decl): Likewise.
	(function_decl::parameter::parameter): Likewise.
	(template_decl::template_decl): Likewise.
	(type_tparameter::type_tparameter): Likewise.
	(non_type_tparameter::non_type_tparameter): Likewise.
	(function_tdecl::function_tdecl): Likewise.
	(class_tdecl::class_tdecl): Likewise.
	(class_decl::class_decl): Likewise.
	(class_decl::method_decl::method_decl): Likewise.
	* src/abg-writer.cc (write_location): Take a reference to
	location and adjust.
	(write_array_type_def, write_function_decl, dump_decl_location):
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-10 16:47:18 +01:00
Dodji Seketeli
2eda63d0f2 Fix internal name for pointers, typedefs and arrays
Internal names (and pretty representation) of types are used for type
canonicalization.  These were not being correctly computed for
pointers typedefs and arrays because we were forgetting sometimes to
use internal names of the underlying types, especially because of caching issues.

This patch addresses that.

Note that I noticed this while comparing the two versions of
libgromacs_d.so.0.0.0 involved in the comparison referenced by bug
https://bugzilla.redhat.com/show_bug.cgi?id=1283906.  But then that
library is too big (and takes too much time) to be included as a non
regression test :(

	* include/abg-ir.h (pointer_type_def::priv_): New data structure.
	The type is now pimpled.
	(typedef_decl::priv_): Likewise.
	* src/abg-ir.cc (struct pointer_type_def::priv): New struct.
	(pointer_type_def::pointer_type_def): Adjust.
	(pointer_type_def::get_pointed_to_type): Likewise.
	(pointer_type_def::get_qualified_name): Store temporary/internal
	names into different caches.
	(array_type_def::priv::{temp_internal_qualified_name_,
	internal_qualified_name_}): New data members.
	(get_type_representation): In the overload for array_type_def,
	take requests for internal names into account.
	(array_type_def::get_qualified_name): Take requests for internal
	names into account.  Store temporary/internal names into different
	caches.
	(typedef_decl::priv): New struct.
	(typedef_decl::typedef_decl): Adjust.
	(typedef_decl::get_underlying_type): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-08 14:14:09 +01:00
Dodji Seketeli
fa4b7c8069 Fix comparison in qualified_type_diff::has_changes
* src/abg-comparison.cc (qualified_type_diff::has_changes): Make
	this stupid and simple, now that we have (fast) canonical type
	based comparison.
	* include/abg-ir.h (qualified_type_diff::operator==): Add an
	overload for qualified_type_diff here.
	(operator==): Likewise.
	* src/abg-ir.cc (qualified_type_diff::operator==): Define it.
	(operator==): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-08 14:14:08 +01:00
Dodji Seketeli
43c908ed15 Bug 19336 - Better handle redundantly qualified reference types
Sometimes we can see const references in DWARF.  But then, a reference
is always const, so that qualified reference is redundant.
Furthermore, having that construct make its way into the internal
representation can cause awkward diagnostics.

The DWARF reader was thus eliding such redundant qualifiers in the
function "maybe_strip_qualification".  It was doing so by stripping
the qualifier from the qualified type. So const reference, for
instance, becomes a (non-qualified) reference.  In that case, we are
turning a qualified type into a non-qualified one.

But as the accompanying problem report suggests, this can cause issues
during the DWARF parsing.  This is because a given Debug Information
Entry (DIE) of qualified type kind can be referenced elsewhere, by
another type.  That other type expects that DIE to be a qualified
type.  And libabigail's DWARF reader code enforces that.  So the
internal representation of a type resulting from a qualified type DIE
must be a qualified type itself.

So the way the function "maybe_strip_qualification" was doing the
redundancy elision was wrong.  This patch fixes that by keeping the
type qualified, but introducing a "no-op" qualifier.  Actually, the IR
already has that "no-op" qualifier: abigail::ir::qualified_type_def::CV_NONE.

So now "maybe_strip_qualification" just turns the CV_CONST qualifier
into a CV_NONE one when the former is redundant.

Now that the libabigail type system actually *has* types qualified
with this no-op qualifier, we need to handle things like printing the
name of such qualified types.  When we are printing the name of the
type for internal reasons (i.e, for type canonicalization purposes) we
need to make a difference between the name of a no-op qualified type
and the name of the underlying type of the qualified type, otherwise,
the canonicalizer wrongly considers the two types as being equal.  But
then when we are printing the name of the no-op qualified type for
diagnostics reasons, then the name is the same as the name of its
underlying unqualified type.

	* src/abg-dwarf-reader.cc (maybe_strip_qualification): Do not nuke
	the qualified type.  Rather, just turn the redundant const
	qualifier into a no-op one.
	* src/abg-comparison.cc (compute_diff_for_types): Look through
	no-op qualified types.
	* include/abg-ir.h
	(decl_base::{peek,set}_temporary_qualified_name): Declare new
	accessors.
	* src/abg-ir.cc (decl_base::priv::temporary_qualified_name_): New
	data member.
	(decl_base::{peek,set}_temporary_qualified_name): Define new
	accessors.
	(qualified_type_def::priv::{temporary_internal_name_,
	internal_name}): New data members.
	(qualified_type_def::build_name): For a no-op qualified type, the
	internal name (which contains the 'none' qualifier) is different
	from the non-internal name.
	(qualified_type_def::get_qualified_name): Handle temporary names
	and non-temporary names in two different caches.  Also handle
	internal and non-internal names in two different caches.  This
	makes four different caches.
	(qualified_name_setter::do_update): Do not touch the non-internal,
	non-temporary qualified name cache if the qualified parent name is
	empty.
	* tools/abidw.cc (main): change --check-alternate-debug-info to
	make it *not* display the name/path to the alternate debug info,
	when it's found.  Rather, only
	--check-alternate-debug-info-base-name keeps displaying the base
	name of the alternate debug info.
	* tests/data/test-alt-dwarf-file/test1-libgromacs-debug-dir/*: New
	test material.
	* tests/data/Makefile.am: Add the new test material to the build
	system.
	* tests/test-alt-dwarf-file.cc (in_out_specs): Take the new test
	input into account.
	* tests/data/test-read-dwarf/test1.abi: Adjust.
	* tests/data/test-read-dwarf/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-08 14:11:22 +01:00
Dodji Seketeli
1bee40c075 Do not forget to peel qualified type off when peeling types
When peeling off typedefs, references and pointers to see if a type is
made of a class type, we forget to peel qualified types off.

This is in the context of parsing type info from DWARF and to
determine if we should delay type canonicalization (because a given
type is made of a class) or not.

Fixed thus.

	* include/abg-fwd.h (peel_qualified_type): Declare new function
	...
	* src/abg-ir.cc (peel_qualified_type): ... and define it.
	(peel_typedef_pointer_or_reference_type): Peel qualified types
	here too.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-06 17:29:50 +01:00
Dodji Seketeli
35dd76bc69 Constify is_qualified_type()
* include/abg-fwd.h (is_qualified_type): Make this take a const
	parameter.
	* src/abg-ir.cc (is_qualified_type): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-12-06 17:12:43 +01:00
Dodji Seketeli
86ec69a86d Read enum values in the size_t and write them in ssize_t
Make sure to read enum values in the widest possible integer (size_t)
but write them (in abixml writer) using a signed type to ease
comparison.

This makes the runtestreaddwarf pass on 32 bit x86, because we were
losing some precision reading enum values using a signed integer.

	* include/abg-ir.h (enum_type_def::enumerator::get_value): Return
	a size_t.
	* src/abg-ir.cc (enum_type_decl::enumerator::get_value): Likewise.
	* src/abg-dwarf-reader.cc (die_signed_constant_attribute): #if-out
	this static function that is not used anymore.
	(build_enum_type): Read the value of the enumerator using a size_t
	value.
	* src/abg-reader.cc (build_enum_type_decl): Read the enum value
	using a long long int.
	* src/abg-writer.cc (write_enum_type_decl): Write using a ssize_t.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-17 16:01:23 +01:00
Dodji Seketeli
266fa9288e Add --version option to several libabigail tools
This patch changed the revision number of the libabigail library to
make it reflect the fact that we are not in "release candidate" mode,
before the first 1.0 release.  So the revision number is now "rc0".

The configuration manager has been updated to support version numbers
that are strings, so that it can supports things like "rc0".

Then, several libabigail tools have been modified to support the
--version option to display their version number.

	* configure.ac: Set the version revision to "rc0".
	* doc/manuals/abicompat.rst: Adjust manual for new --version
	option.
	* doc/manuals/abidiff.rst: Likewise.
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/abilint.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-config.h (config::{m_format_minor, m_format_major}):
	Make these be strings.
	(config::{get,set}_format_minor_version_number): Make these return
	strings.
	(config::{get,set}_format_major_version_number): Make these return
	or take strings.
	(abigail_get_library_version): Make this take strings.
	* src/abg-config.cc (config::config): Adjust.
	(config::{get,set}_format_major_version_number): Make these return
	or take strings.
	(config::{get,set}_format_minor_version_number): Make these return
	strings.
	(abigail_get_library_version): Make this take strings.
	* include/abg-version.h.in: Make the version variables be strings.
	* src/abg-writer.cc (write_translation_unit): The version numbers
	are now strings so adjust.
	* tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc
	(options::display_version): New data member.
	(options::options): Initialize it.
	(display_usage): Add documentation for new --version option.
	(parse_command_line): Parse new --version option.
	(main): Support --version.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-16 12:54:10 +01:00
Dodji Seketeli
ba980025fb 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>
2015-11-07 23:22:18 +01:00
Dodji Seketeli
4adbafaa43 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>
2015-11-07 23:22:17 +01:00
Dodji Seketeli
7b35e89315 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>
2015-11-05 16:40:22 +01:00
Dodji Seketeli
089b3fc762 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>
2015-10-17 16:09:50 +02:00
Dodji Seketeli
caaeaea10b 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>
2015-10-15 13:50:56 +02:00
Dodji Seketeli
093bc5da06 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>
2015-10-15 13:50:55 +02:00
Dodji Seketeli
7bb65377a5 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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
60425d2996 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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
4b754229d1 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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
f1c48fe80f 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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
1a6b957401 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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
f95af3a89a 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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
e9bdb488b3 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>
2015-10-08 13:50:49 +02:00
Dodji Seketeli
0e3416e7e2 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>
2015-10-07 00:41:32 +02:00
Dodji Seketeli
48801d23e4 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>
2015-10-06 13:32:12 +02:00
Dodji Seketeli
9a0abd846b 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>
2015-10-04 13:52:25 +02:00
Dodji Seketeli
6e36a4381d 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>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
38e17e0e07 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>
2015-10-04 13:51:24 +02:00