Commit Graph

821 Commits

Author SHA1 Message Date
Dodji Seketeli
dbe88f1103 Fix the new regression test for type canonicalizing
* tests/runtestcanonicalizetypes.sh.in (binaries): Refer to
	abg-tools-utils, not abg-tools-utils.o; the extension is computed
	automatically, depending on the underlying platform.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-19 11:44:19 +01:00
Dodji Seketeli
cc3f6a86a7 Make strip_typedef() act on canonical types only
strip_typedef(), when constructing new pointers,
references and other composite types was building new types that
weakly referred to their sub-types; for instance, a pointer type
has a weak reference on its pointed-type.  That means the referred-to
type must be 'own' by something else.  That means that strip_typedef()
needs to create types which lifetime is "long enough".  This patch
ensures that strip_typedef() returns a canonical type; and we are sure
that a canonical type is live during the entire life time of the
libabigail library itself.

So that means strip_typedef can only be used after types have been
canonicalized.  To that end, this patch changes is_class_type() to
make it not strip typedefs.  That way, is_class_type() can be used
even when canonicalized types are not yet available.  The patch then
introduces a new is_compatible_with_class_type() function that strips
typedef.  The code of type_size_changed() that wanted to strip
typedefs is then adjusted to use this new
is_compatible_with_class_type() instead.

	* include/abg-fwd.h (is_compatible_with_class_type): Declare new
	function.
	(canonicalize): Move the declaration here, from ...
	* include/abg-ir.h (canonicalize): ... here.
	* src/abg-ir.cc (strip_typedef): Assert that the input type is
	canonicalized.  Make sure that weak references are on
	canonicalized types.  Make sure that the returned type is a
	canonical one.
	(canonicalize): Make this return the canonical type that it has
	computed.
	* src/abg-comp-filter.cc (type_size_changed): Use the new
	is_compatible_with_class_type() function, instead of
	is_class_type().

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-19 11:44:11 +01:00
Dodji Seketeli
3afb235d0c Speed up function_decl::get_id() and var_decl::get_id()
function_decl::get_id() var_decl::get_id() showed up high on CPU usage
profiles.  This patch thus implements a caching-version of these
version and it incurred a 10% (at least) speed on binaries with a lot
publicly exported symbols.

	* src/abg-ir.cc (var_decl::priv::id_): New data member.
	(var_decl::get_id): Cache the result on the first invocation and
	and returns it on subsequent invocations.
	(function_dec::priv::id_): New data member.
	(function_decl::get_id): Cache the result on the first invocation
	and and returns it on subsequent invocations.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 21:32:38 +01:00
Dodji Seketeli
2346a328eb Speed up symbol version reading
Profiling showed that symbol version info reading was on the hot spot.
This patch implements caching the symbol table and symbol
version-related sections.  It incurred speed ups of at least 20% on
big binaries with a lot versionned symbols.

	* src/abg-dwarf-reader.cc (find_symbol_table_section)
	(get_symbol_versionning_sections): Forward declare these existing
	static functions.
	(read_context::{symtab_section_,
	symbol_versionning_sections_loaded_,
	symbol_versionning_sections_found_, versym_section_
	verdef_section, verneed_section}): New data members.
	(read_context::read_context): Initialize them.
	(read_context::{find_symbol_table_section,
	get_symbol_versionning_sections, get_version_for_symbol}):
	Implement a caching version of their exisiting non-caching
	counterpart.
	(read_context::lookup_elf_symbol_from_index): Use the new caching
	functions read_context::find_symbol_table_section and
	read_context::get_version_for_symbol.
	(read_context::load_symbol_maps): Likewise, use the new caching
	function read_context::find_symbol_table_section.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 21:32:38 +01:00
Dodji Seketeli
955c466ba7 Stop traversing function/variable node when added to symbol table
During the building of the list of publicly exported functions and
variables from a corpus, when we visit a function it's useless (and
time consuming) to visit the sub-nodes of the function.  This patch
does away with that.

	* src/abg-corpus.cc (symtab_build_visitor_type::visit_begin):
	Replace symtab_build_visitor_type::visit_end with this and return
	false.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 21:32:38 +01:00
Dodji Seketeli
ba8ecf46a1 Do not apply diff filters sub-tree not carrying changes
Some *huge* sub-trees might not carry any change.  In that case do not
bother applying the filter because eventually no filter is going to be
applied anyway.  This can save us a lot of walking time.

	* src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Do
	not try to do the categorizing on a diff sub-tree that does
	not carry any change.
	* src/abg-comparison.cc (diff_context::maybe_apply_filters): Do
	not bother trying to apply the filters on a diff sub-tree that
	does not carry any change.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 21:32:37 +01:00
Dodji Seketeli
8b28d171c3 Canonicalize types either early or late after TU reading
While trying to diff two identical files (abidiff foo.so foo.so) it
appeared that canonicalizing types during e.g, the DWARF reading
process was leading to subtle errors because it's extremely hard to
know when a type is complete.  That is, during the building of a class
type C, a pointer to C can be built before C is complete.  Worse, even
after reading the DIE (from DWARF) of class C, there can be DIE seen
later in the translation unit that modifies type C.  In these late
cases, one needs to wait -- not only until C is fully built, but also
sometimes, after the translation unit is fully built -- to
canonicalize C and then the pointer to C.  This kind of things.

So now there are two possible points in time when canonicalization of
a type can happen.  It can happen early, when the type is built.  This
is the case for basic types and composite types for which all
sub-types are canonicalized already.  It can happen late, right after
we've finished reading the debug info for the current translation
unit.

So this patch fixes the IR traversal and uses that to walk the
translation unit (or even types) after it's built.  It does away with
the first attempt to perform early canonicalizing only.

The patch also handles type canonicalizing while reading xml-abi
format.

	* include/abg-fwd.h (is_class_type)
	(type_has_non_canonicalized_subtype): Declare new functions.
	(is_member_type): Remove the overload that takes a decl_base_sptr.
	It's superfluous.  We just need the one that takes a
	type_base_sptr.
	* include/abg-ir.h (translation_unit::{is_constructed,
	set_is_constructed}): Add new methods.
	(class_decl::has_virtual_member_functions): Likewise.
	(class decl_base): Makes it virtually inherit ir_traversable_base.
	(class type_base): Make this virtually inherit traversable_base
	too.
	(type_base::canonicalize): Renamed enable_canonical_equality
	into this.
	(type_base::traverse): Declare new virtual method.
	(canonicalize): Renamed enable_canonical_equality into this.
	(scope_type_decl::traverse): Declare new virtual method.
	(namespace_decl::get_pretty_representation): Declare new virtual
	method.
	(function_type::traverse): Likewise.
	(class_decl::base_spec::traverse): Likewise.
	(ir_node_visitor::visit): Remove the overloads and replace each of
	them with a pair of ...
	(ir_node_visitor::{visit_begin, visit_end}): ... of these.
	* include/abg-traverse.h (traversable_base::visiting): New
	method.
	(traversable_base::visiting_): New data member.
	(traversable_base::traversable_base): New constructor.
	* src/abg-ir.cc ({scope_decl, type_decl, namespace_decl,
	qualified_type_def, pointer_type_def, reference_type_def,
	array_type_def, enum_type_decl, typedef_decl, var_decl,
	function_decl, function_decl::parameter, class_decl,
	class_decl::member_function_template,
	class_decl::member_class_template, function_tdecl,
	class_tdecl}::traverse): Fix this to properly set the
	traversable_base::visiting_ flag and to reflect the new signatures
	of the ir_node_visitor methods.
	({type_base, scope_type_decl, function_type,
	class_decl::base_spec}::traverse): New method.
	(type_base::get_canonical_type_for): Handle the case of the type
	already having a canonical type.  Properly hash the type using the
	dynamic type hasher.  Look through declaration-only classes to
	consider the definition of the class instead.  Fix logic to have a
	single pointer of return, to ease debugging.
	(canonicalize): Renamed enable_canonical_equality into this.
	(namespace_decl::get_pretty_representation): Define new method.
	(ir_node_visitor::visit): Replace each of these overloads with a
	pair of visit_begin/visit_end ones.
	(translation_unit::priv::is_constructed_): New data member.
	(translation_unit::priv::priv): Initialize it.
	(translation_unit::{is_constructed, set_is_constructed}): Define
	new methods.
	(is_member_type(const decl_base_sptr)): Remove.
	(is_class_type(decl_base *d)): Define new function.
	(class_decl::has_virtual_member_functions): Define new method.
	(equals(const class_decl&, const class_decl&, change_kind*)): If
	the containing translation unit is not constructed yet, do not
	take virtual member functions in account when comparing the
	classes.  This is because when reading from DWARF, there can be
	DIEs that change the number of virtual member functions after the
	DIE of the class.  So one needs to start taking virtual members
	into account only after the translation unit has been constructed.
	(class non_canonicalized_subtype_detector): Define new type.
	(type_has_non_canonicalized_subtype): Define new function.
	* src/abg-corpus.cc (symtab_build_visitor_type::visit): Renamed
	this into symtab_build_visitor_type::visit_end.
	* src/abg-dwarf-reader.cc (die_type_map_type): New typedef.
	(die_class_map_type): This is now a typedef on a map of
	Dwarf_Off/class_decl_sptr.
	(read_context::{die_type_map_, alternate_die_type_map_,
	types_to_canonicalize_, alt_types_to_canonicalize_}): New data
	members.
	(read_context::{associate_die_to_decl,
	associate_die_to_decl_primary}): Make these methods public.
	(read_context::{associate_die_to_type,
	lookup_type_from_die_offset, is_wip_class_die_offset,
	types_to_canonicalize, schedule_type_for_canonicalization}):
	Define new methods.
	(build_type_decl, build_enum_type)
	(build_class_type_and_add_to_ir, build_qualified_type)
	(build_pointer_type_def, build_reference_type, build_array_type)
	(build_typedef_type, build_function_decl): Do not canonicalize
	types here.
	(maybe_canonicalize_type): Define new function.
	(build_ir_node_from_die): Take a new flag that says if the ir node
	is a member type/function or not. Early-canonicalize base types.
	Canonicalize composite types that have only canonicalized
	sub-types.  Schedule the other types for late canonicalizing.  For
	class types, early canonicalize those that are non-member types,
	that are fully constructed and that have only canonicalized
	sub-types.  Adjust to the new signature of build_ir_node_from_die.
	(get_scope_for_die, build_namespace_decl_and_add_to_ir)
	(build_qualified_type, build_pointer_type_def)
	(build_reference_type, build_array_type, build_typedef_type)
	(build_var_decl, build_function_decl): Adjust for the new
	signature of build_ir_node_from_die.
	(build_translation_unit_and_add_to_ir): Likewise.  Perform the
	late canonicalizing of the types that have been scheduled for
	that.
	(build_class_type_and_add_to_ir): Return a class_decl_sptr, not a
	decl_base_sptr.  Adjust for the new signature of
	build_ir_node_from_die.  Early canonicalize member types that are
	created and added to a given class, or schedule them for late
	canonicalizing.
	* src/abg-reader.cc (class read_context::{m_wip_classes_map,
	m_types_to_canonicalize}): New data members.
	(read_context::{clear_types_to_canonicalize,
	clear_wip_classes_map, mark_class_as_wip, unmark_class_as_wip,
	is_wip_class, maybe_canonicalize_type,
	schedule_type_for_late_canonicalizing,
	perform_late_type_canonicalizing}): Add new method definitions.
	(read_context::clear_per_translation_unit_data): Call
	read_context::clear_types_to_canonicalize().
	(read_translation_unit_from_input): Call
	read_context::perform_late_type_canonicalizing() at the end of the
	function.
	(build_function_decl): Fix the function type canonicalizing (per
	translation) that was already in place.  Do the canonicalizing of
	these only when the type is fully built.  Oops.  This was really
	brokend.  Also, when the function type is constructed, consider it
	for type canonicalizing.
	(build_type_decl): Early canonicalize basic types.
	(build_qualified_type_decl, build_pointer_type_def)
	(build_pointer_type_def, build_reference_type_def)
	(build_array_type_def, build_enum_type_decl, build_typedef_decl):
	Handle the canonicalizing for these composite types: either early
	or late.
	(build_class_decl): Likewise.  Also, mark this class a 'being
	built' until it's fully built.  This helps the canonicalizing code
	to know that it should leave a class alone until it's fully built.
	* tests/test-ir-walker.cc (struct name_printing_visitor): Adjust
	to the visitor methods naming change.
	* configure.ac: Generate the tests/runtestcanonicalizetypes.sh
	testing script from tests/runtestcanonicalizetypes.sh.in.
	* tests/runtestcanonicalizetypes.sh.in: Add the template for the
	new runtestcanonicalizetypes.sh script that test for type
	canonicalizing.
	* tests/Makefile.am: Add the new runtestcanonicalizetypes.sh
	regression testing script to the build system.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 21:32:37 +01:00
Dodji Seketeli
f968b7d422 Factorize per TU data clearing in the xml-abi reader
It's more maintainable to have a function that clears the per
translation unit data that needs to be erased before we parse the next
translation unit using the same reading context.  This patch does just
that.  Subsequent patches use this cleanup.

	* src/abg-reader.cc
	(read_context::clear_per_translation_unit_data): Factorize this
	function out of ...
	(read_context::read_translation_unit_from_input): ... this one.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 19:16:14 +01:00
Dodji Seketeli
4f73543250 Use the deep type sptr equality operator when possible
While looking at something else, it occurs to me that we ought to use
the deep sptr equality operator when we can.

	* src/abg-ir.cc (equals):  On function_decl overload, use the deep
	sptr type equality operator when comparing types.
	(non_type_tparameter::operator==): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 19:16:13 +01:00
Dodji Seketeli
988d2bafb4 Properly compare virtualness of member functions
* src/abg-ir.cc (equals(const function_decl&, const
	function_decl&, change_kind*)): Compare virtualness of member
	function before comparing their vtable offsets.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 19:16:13 +01:00
Dodji Seketeli
d1d4965ee1 Misc style fixes
* include/abg-ir.h (reference_type_def::get_pointed_to_type): use
	type_base_sptr, rather than shared_ptr<type_base>
	(typdef_decl::get_underlying_type): Likewise.
	(function_decl::get_return_type): Likewise.
	(function_decl::set_type): Likewise.
	(class_decl::member_class_template::as_class_tdecl): Likewise.
	* src/abg-comparison.cc (compute_diff): Remove useless vertical
	space.
	(corpus_diff::traverse): Add a vertical space after this.
	* src/abg-dwarf-reader.cc (type_ptr_map): Remove this unused
	typedef.
	(get_version_for_symbol)
	(finish_member_function_reading): Fix the comments of these
	functions.
	* src/abg-reader.cc (build_function_decl): Return a
	function_decl_sptr rather than a shared_ptr<function_decl>.
	(build_qualified_type_decl)
	(build_pointer_type_def, build_reference_type_def)
	(build_array_type_def, build_typedef_decl, build_class_decl): Use
	the is_<someking_of_type> functions here, rather than using the
	dynamic cast.  This increases maintainability.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-18 19:15:17 +01:00
Dodji Seketeli
e39715f6c1 Optimize compressed debug info reading for speed
Profiling of abidiff or rather abidw on an Xorg binary that is
dwarf-compressed revealed that find_last_import_unit_point_before_die
was a hot spot.  This patch optimizes it for speed by ooking for the
inclusion point in reverse topological order.

	* src/abg-dwarf-reader.cc
	(find_last_import_unit_point_before_die): Look for the inclusion
	point of the partial unit in reverse topological order.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-11 10:38:11 +01:00
Dodji Seketeli
3e033263fc Share private data of class_diff nodes
Profiling has shown that there can be a *lot* of class_diff nodes that
actually represent the same diffs.  In other words, these instances of
class_diff that is they are in the same equivalence class.  In that
case the private data of these class_diff node consume a lot of
redundant memory.  This patch is an optimization that leverages that
insight.  It shares the private data of the class_diff nodes that are
in the same equivalence class.

This makes the memory consumption of abidiff on the Xorg binaries of
RHEL 6 and 7 drop from more than 6GB to less than 370MB; execution
time drops from 15 to 7 minutes.

	* src/abg-comparison.cc (class_diff::class_diff): Do not
	initialize the private data of class_diff here.
	(compute_diff): In the overload for class_diff, initialize the
	private data of the new instance of class_diff to the private data
	of its canonical instance.
	(redundancy_marking_visitor::visit_begin): If a node is marked
	redundant, do not dare visit its children.  In cases of classes
	that have members that reference themselves, this prevents us from
	wrongly marking some of the data member changes as being
	redundant.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-10 16:08:26 +01:00
Dodji Seketeli
899bbd75cf Do not crash when applying filters to a NULL diff
While looking at something else, I stumbled accross this two-liner.

	* src/abg-comparison.cc (diff_context::maybe_apply_filters): Do
	not crash when called with a NULL diff.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-10 11:41:48 +01:00
Dodji Seketeli
8fbd4f93ba Initial implementation of canonical type comparison in the IR
Comparing types that are equal showed up high in profiles.  This patch
is an answer to that.  It implements the notion of canonical type for
types known to libabigail.  Then when comparing two types, if they
have a canonical types, just comparing the pointer value of their
canonical type is enough.  This speeds up type comparison somewhat;
comparing the Xorg binaries from rhel 6 and 7 goes from more than 20h
(I gave up after that) to under 15 minutes.

	* include/abg-ir.h (class type_base): Pimplify this class.
	(type_base::canonical_types_map_type): New typedef.
	(type_base::{get_canonical_types_map, get_canonical_type_for,
	get_canonical_type}): Declare new member functions.
	(enable_canonical_equality): Declare new function.
	(struct type_base::hash): Declare this functor here.
	* src/abg-ir.cc ():
	* src/abg-dwarf-reader.cc (build_type_decl, build_enum_type)
	(build_class_type_and_add_to_ir, build_qualified_type)
	(build_pointer_type_def, build_reference_type, build_array_type)
	(build_typedef_type, build_function_decl): Enable canonical
	equality for the resulting type returned by these functions.
	* src/abg-hash.cc (type_base:#️⃣:operator()(const type_base&)):
	Adjust as this is now out-of-line.  Also, add two overloads for
	type_base* and type_base_sptr.
	(struct type_base::priv): Define new type for private data of
	type_base.
	(type_base::{get_canonical_types_map, get_canonical_type_for,
	get_canonical_type}): Define new member functions.
	(enable_canonical_equality): Define new function
	(type_base::{type_base, set_size_in_bits, get_size_in_bits,
	set_alignment_in_bits, get_alignment_in_bits}): Adjust.
	({type_decl, scope_type_decl, qualified_type_def,
	pointer_type_def, reference_type_def, array_type_def,
	enum_type_decl, typedef_decl, function_type,
	class_decl}::operator==): If the types being compared have
	canonical type then use them for comparison.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-09 17:01:48 +01:00
Dodji Seketeli
c27ec0db35 Don't walk the diff tree when there are no suppressions
Profiling showed that we were walking the diff tree to apply
suppressions even when there were no suppressions to apply.  This
patch does away with that behaviour.

	* src/abg-comparison.cc (apply_suppressions): Do not walk the diff
	tree to apply suppressions when there are no suppressions to
	apply.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-07 11:00:05 +01:00
Dodji Seketeli
6fa1dca62a Speedup some diff::has_changes() implementations
Some implementations of diff::has_changes() are high on performance
profiles. This patch make them faster by trying to detect as quickly
as possible cases where the diff node actually has changes.  The
longest past is to detect when the diff node does *not* have changes.
We'll deal the latter case later.

	* src/abg-comparison.cc ({distinct_diff, var_diff,
	class_diff}::has_changes): Use the hash value of the diff subjects
	to detect quickly if they differ.  If they don't, then go the slow
	path of comparing the types.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-07 11:00:05 +01:00
Dodji Seketeli
34b94a06da Get out as early as possible when comparing different ABI artefacts
When the the of 'equals' overloaded functions was introduced, it was
to get the possibility to have a hint about the kind of difference
(local or sub-type difference) there was between two different ABI
artifacts.  To do that, it was quite common to keep on comparing the
two artifacts even when we knew there were different, because we need
to know all the kinds of the differences there are.

Now, profiling shows that doing this generally is too costly.  So,
this patch adds a way to doing it only when necessary.

	* include/abg-ir.h (equal): Turn the last parameter of type
	change_kind& into a change_kind*.  Do this on all the overloads'
	declarations.
	* src/abg-ir.cc (equal): Do the same for the definitions of the
	overloads and adapt them to report about the kind of changes makes
	the two ABI artifact different -- only if the change_kind pointer
	is non-null.  That way, callers have a way to choose if they want
	to go the expensive route of knowing what kind of changes there
	are.
	({decl_base, scope_decl, type_base, scope_type_decl,
	qualified_type_def, pointer_type_def, pointer_type_def,
	reference_type_def, array_type_def, enum_type_decl, typedef_decl,
	var_decl, function_type, function_decl, function_decl::parameter,
	class_decl::base_spec, class_decl}::operator==): Adjust to the new
	signature of equals; call it with the change_kind* parameter set
	to NULL.
	* src/abg-comparison.cc ({var_diff, pointer_diff, array_diff,
	reference_diff, qualified_type_diff, enum_diff, class_diff,
	base_diff, scope_diff, fn_parm_diff, function_decl_diff,
	type_decl_diff, typedef_diff}::has_local_changes): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-07 11:00:05 +01:00
Dodji Seketeli
3b3dbf6643 Rename diff::length() into diff::has_changes()
Since it turned out that the length of the changes carried by a diff
node has never been used in the algorithms of the comparison engine,
the diff::length() feels wrong.  What we want is rather a name like
diff::has_changes() so this is what this patch does.

	* include/abg-comparison.h (*::has_changes): Rename the ::length()
	method of all the diff types that inherit the diff class into
	this, in the class declarations.
	* src/abg-comparison.cc (*::has_changes): Do the same as in the
	declarations, in the definitions.
	(diff::to_be_reported, distinct_diff::has_local_changes)
	(distinct_diff::report, distinct_diff::, array_diff::has_changes)
	(reference_diff::has_changes, qualified_type_diff::has_changes)
	(enum_diff::has_changes, translation_unit_diff::has_changes)
	(suppression_categorization_visitor::visit_end)
	(redundancy_marking_visitor::visit_begin): Adjust.
	* tests/test-diff-dwarf.cc (main): Adjust.
	* tools/abidiff.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-05 12:44:59 +01:00
Dodji Seketeli
32352341c5 Add a method to diff_context to dump a diff tree to error output
For debugging purposes it's very convenient to able to dump a diff
tree to error output.  This patch just adds that possibility.

	* include/abg-comparison.h (diff_context::error_output_stream):
	Make this function const.
	(diff_context::{do_dump_diff_tree}): Declare new methods.
	* src/abg-comparison.cc (diff_context::error_output_stream): Make
	this function const.
	(diff_context::do_dump_diff_tree): Define new methods.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-27 12:49:40 +01:00
Dodji Seketeli
2173563f3c Keep children nodes of class_diff and scope_diff sorted
I realized that some children nodes of class_diff and scope_diff node
appear in the order laid out by the hash map that contains them.  This
can be quite random depending on various factors.  More over the
reporting code walks sorts the children nodes before walking them to
emit reports, so the walking order of the reporting code is (or can
be) different from the natural walking order used, for instance, by
the categorization or redundancy detection code.  This can have weird
side effects, especially for reporting about redundancy where the
walking other matters.

This patch thus sorts the children nodes of the class_diff and
scope_diff nodes and hopefully udpates all the code that needs
updating to take that in account.

	* include/abg-comparison.h (decl_diff_base, type_diff_base):
	Forward declare these types.
	(diff_sptrs_type, decl_diff_base_sptr, decl_diff_base_sptrs_type)
	(type_diff_base_sptr, type_diff_base_sptrs_type)
	(base_diff_sptrs_type, string_type_diff_base_sptr_map)
	(string_decl_diff_base_sptr_map, string_diff_sptr_map): New
	typedefs.
	(changed_type_or_decl, changed_parm, changed_parms_type)
	(string_changed_type_or_decl_map)
	(unsigned_changed_type_or_decl_map, changed_type_or_decl_vector):
	Remove typedefs.
	(class_diff::changed_base): Make this return a
	base_diff_sptrs_type now.  No more a string_base_diff_sptr_map.
	(class_diff::changed_member_fns): Make this return a
	function_decl_diff_sptrs_type, no more a
	string_changed_member_function_sptr_map.
	(class_diff::changed_types): Make this return a diff_sptrs_type,
	not a string_changed_type_or_decl_map anymore.
	(class_diff::changed_decls): Make this return a diff_sptrs_type,
	not a string_changed_type_or_decl_map anymore.
	* src/abg-comp-filter.cc (has_virtual_mem_fn_change)
	(has_non_virtual_mem_fn_change): Adjust.
	* src/abg-comparison.cc (compute_diff): For the decl_base_sptr and
	type_base_sptr overloads, assert that the resulting diff is
	non-null.
	(class_diff::priv::{sorted_changed_base_,
	sorted_changed_member_types_, sorted_subtype_changed_dm_,
	sorted_changed_dm_, sorted_changed_member_functions_,
	sorted_changed_member_class_tmpls_}): New data members.
	(class_diff::priv::changed_member_types_): Changed the type of
	this from string_changed_type_or_decl_map to string_diff_sptr_map.
	(class_diff::priv::changed_member_functions_): Changed the type of
	this from string_changed_member_function_sptr_map to
	string_function_decl_diff_sptr_map.
	(class_diff::priv::changed_member_class_tmpls_): Changed the type
	of this from string_changed_type_or_decl_map to
	string_diff_sptr_map.
	(class_diff::ensure_lookup_tables_populated): Adjust.  Initialize
	the new sorted members class_diff::priv::{sorted_changed_bases_,
	sorted_subtype_changed_dm_, sorted_changed_dm_,
	sorted_changed_member_functions_, sorted_changed_member_types_}.
	(class_diff::priv::{member_type_has_changed,
	member_class_tmpl_has_changed, count_filtered_bases,
	count_filtered_subtype_changed_dm, count_filtered_changed_mem_fns,
	}): Adjust.
	(class_diff::chain_into_hierarchy): Adjust:  The children nodes of
	class_diff are now laid out in a sorted way.
	(class_diff::{changed_bases, changed_member_fns}): Adjust.
	(base_diff_comp, virtual_member_function_diff_comp): New types.
	(sort_string_base_diff_sptr_map)
	(sort_string_virtual_member_function_diff_sptr_map): New static
	functions.
	(data_member_diff_comp): Renamed var_diff_comp into this.
	(sort_unsigned_data_member_diff_sptr_map): Renamed sort_var_diffs
	into this and adjust.
	(class_diff::report): Do not sort the nodes we are about to emit
	here.  Just use the natural order of the nodes in their parent
	tree as they should now be sorted.
	(scope_diff::priv::{changed_types_, changed_decls_}): Change the
	type of these from string_changed_type_or_decl_map to
	string_diff_sptr_map.
	(scope_diff::priv::{sorted_changed_types_,
	sorted_changed_decls_}): New data members.
	(scope_diff::ensure_lookup_tables_populated): Adjust.  Initialize
	the new scope_diff::priv::sorted_changed_{types_, decls_}.
	(scope_diff::chain_into_hierarchy): Adjust.  The children of
	scope_diff are now sorted.
	(scope_diff::changed_{types, decls}): Return the sorted vectors of
	children nodes.
	(struct changed_type_or_decl_comp): Remove.
	(struct diff_comp): New type.
	(sort_changed_type_or_decl): Remove.
	(sort_string_diff_sptr_map): New static function.
	(scope_diff::report): Adjust.  Do not sort children nodes here
	ourselves before reporting about them.  Rather, use the natural
	topological order of the children as they are now sorted.
	(corpus_diff::priv::sorted_changed_vars_): Renamed
	corpus_diff::priv::changed_vars_ into this to make it more
	explicit that the things it holds are sorted.
	(corpus_diff::changed_variables_sorted): Adjust.
	(corpus_diff::priv::ensure_lookup_tables_populated): Likewise.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats):
	Likewise.
	(corpus_diff::priv::categorize_redundant_changed_sub_nodes):
	Likewise.
	(corpus_diff::priv::clear_redundancy_categorization): Likewise.
	(corpus_diff::priv::maybe_dump_diff_tree): Likewise.
	(corpus_diff::report): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-27 12:49:40 +01:00
Dodji Seketeli
a00ed6bf41 Hand-code the string representation of GElf_Ehdr::e_machine
I was using elfutils/libebl.h to get a string representation of the
marchine architecture of the elf file.  It appears elfutils/libebl.h
is an internal header not meant to be used by client code of
elfutils.  So this patch hand-codes the string representation of the
value of the GElf_Ehdr data member and does away with the need of the
elfutils/libebl.h header as with libebl.

	* configure.ac: Do not check for elfutils/libebl.h and libebl.a
	anymore.
	* src/abg-dwarf-reader.cc: Do not include elfutils/libebl.h
	anymore.
	(e_machine_to_string): Define new static
	function.
	(read_context::::load_elf_architecture): Use the new
	e_machine_to_string() function rather than ebl_backend_name() and
	ebl_openbackend().
	* tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-26 22:17:39 +01:00
Dodji Seketeli
29bc673dc0 Fix chaining of descendant node of qualified type diff node
While looking at the abidiff report emitted for two versions of the
TBB library, I noticed that some diff nodes were not marked as
redundant as they should be.  As a result, they were being reported as
having "been reported earlier", which seems to be an acceptable cruft
to me especially now that the comparison IR can do proper redundancy
detection and marking.

I tracked that down and it's because the child node of a
qualified_type_diff is just the underlying type diff node, whereas
during reporting, we report about the leaf underlying type diff node,
which can be different from the just the underlying type diff node
because the later is always non-qualified.

The fix is to make the child node of qualified_type_diff be the leaf
underlying type diff node, so that diff tree walking (for the purpose
of redundancy detection) and reporting are all looking at the same
tree.

	* include/abg-comparison.h
	(qualified_type_diff::leaf_underlying_type_diff): Declare new
	accessor.
	* src/abg-comparison.cc (get_leaf_type): Forward declare this
	static function.
	(qualified_type_diff::priv::leaf_underlying_type_diff): Define new
	data member.
	(qualified_type_diff::leaf_underlying_type_diff): Define this new
	accessor.
	(qualified_type_diff::chain_into_hierarchy): Call
	leaf_underlying_type_diff() here rather than
	underlying_type_diff().
	(qualified_type_diff::report): Use leaf_underlying_type_diff()
	rather than re-computing the diff between the two leaf underlying
	type diff nodes.
	* libtest26-qualified-redundant-node-v{0,1}.so: New binary test
	input files.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-v{0,1}.cc:
	Source code for the binary test inputs above.
	* tests/test-diff-filter.cc (int_out_spec): Add the new test input
	to the vector of test input data over which to run this test
	harness.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-{0,1.txt:
	New test input file.
	* tests/data/Makefile.am: Add the new test input data to the
	source distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-26 12:12:57 +01:00
Dodji Seketeli
ddfb37ab17 Recognize cyclic diff tree nodes as being redundant
Okay I need to introduce some vocabulary here.  Suppose we have the
version 1 of a library named library-v1.so which source code is:

    struct S
    {
     int m0;
     struct S* m2;
    };

    int
    foo(struct S* ptr)
    {
      return ptr;
    }

And now suppose we have a version 2 of that library named
library-v2.so which source code is modified so that a new data member
is inserted into struct S:

    struct S
    {
     int m0;
     char m1; /* <--- a new data member is inserted here.  */
     struct S* m2;
    };

    int
    foo(struct S* ptr)
    {
      return ptr;
    }

struct S is said to be a cyclic type because it contains a (data)
member which type refers to struct S itself, namely, the type of the
data member S::m2 is struct S*, which refers to struct S.

So, by analogy, the diff node tree that represents the changes of
struct S is also said to be cyclic, for similar reasons: the diff
node of the change of S::m2 refers to the diff node of the change of
the type of S::m2, namely the diff node of struct S*, which refers to
the diff node for the change of struct S itself.

Now let's talk about redundancy.  When walking the diff node tree of
struct S in a depth-first manner, at some point, we look at the diff
node for the data member S::m2, and we end up looking at the diff node
of its type which is the diff node for struct S*; we keep walking and
eventually we look the diff node of the change of the underlying type
of struct S, which is the diff node of struct S, and hah! that is a
redundant node because it's the first node that we visited when
visiting the diff node of ...  struct S!  So the diff tree node for
the change of struct S is not only a cyclic node, it's a redundant
diff node as well, and its second occurrence is located at the point
of appearance of data member S::m2.  Hence the wording "cyclic
redundant diff tree node".  There! We have our vocabulary all set now.

This patch enhances the code of the comparison engine so that a cyclic
diff tree node is marked as redundant from the point of its second
occurrence, onward.

First the patch separates the notion of visiting a diff node from the
notion of traversing it.  Now traversing a diff node means visiting it
and visiting its children nodes.  So one can visit a node without
traversing it, but one can not traverse a node without visiting it.

So, when walking diff node trees, we need to avoid ending up in
infinite loop in presence of cyclic nodes.  This is why re-traversing
a node that is already being traversed is forbidden by this patch, but
visiting a node that is being visited is allowed.  Before this patch,
the notions of visiting and traversing were conflated in one and were
not very clear; and one couldn't visit a node that was currently being
visited.  As a result, in presence of a cyclic node, its redundant
nature wasn't being recognized, and so the diff tree node was not
being flagged as being redundant.  Diff reports were then cluttered by
redundant references to changes involving cyclic types.

	* include/abg-comparison.h (enum visiting_kind): Rename
	enumerator DO_NOT_MARK_VISITED_NODES_AS_TRAVERSED into
	DO_NOT_MARK_VISITED_NODES_AS_VISITED.
	(diff_context::diff_has_been_visited): Rename
	diff_context::diff_has_been_traversed into this.
	(diff_context::mark_diff_as_visited): Rename
	diff_context::mark_diff_as_traversed into this.
	(diff_context::forget_visited_diffs): Rename
	diff_context::forget_traversed_diffs into this.
	(diff_context::forbid_visiting_a_node_twice): Rename
	diff_context::forbid_traversing_a_node_twice into this.
	(diff_context::visiting_a_node_twice_is_forbidden): Rename
	diff_context::traversing_a_node_twice_is_forbidden into this.
	(diff::is_traversing): Move this from protected to public.
	* src/abg-comparison.cc (diff_context::priv::visited_diff_nodes_):
	Rename diff_context::priv::traversed_diff_nodes_ into this.
	(diff_context::priv::forbid_visiting_a_node_twice_): Rename
	diff_context::priv::forbid_traversing_a_node_twice_ into this.
	(diff_context::priv::priv): Adjust.
	(diff_context::diff_has_been_visited): Rename
	diff_context::diff_has_been_traversed into this.  Adjust.
	(diff_context::mark_diff_as_visited): Rename
	diff_context::mark_diff_as_traversed into this.  Adjust.
	(diff_context::forget_visited_diffs): Rename
	diff_context::forget_traversed_diffs into this.  Adjust.
	(diff_context::forbid_visiting_a_node_twice): Rename
	diff_context::forbid_traversing_a_node_twice into this.
	(diff_context::visiting_a_node_twice_is_forbidden): Rename
	diff_context::traversing_a_node_twice_is_forbidden into this.
	(diff_context::maybe_apply_filters): Adjust.
	(diff::end_traversing): Remove the 'mark_as_traversed' parameter
	of this.  Remove the visited-marking code.
	(diff::traverse): This is the crux of the changes of this patch.
	Avoid traversing a node that is being traversed, but one can visit
	a node being visited.  Also, traversing a node means visiting it
	and visiting its children nodes.
	(diff::is_filtered_out):  Simplify logic for filtering redundant
	code.  Basically all nodes that are redundant are filtered.  All
	the complicated logic that was due when diff nodes were shared is
	not relevant anymore.
	(corpus_diff::priv::categorize_redundant_changed_sub_nodes)
	(propagate_categories, apply_suppressions)
	(diff_node_printer::diff_node_printer, print_diff_tree)
	(categorize_redundant_changed_sub_nodes)
	(clear_redundancy_categorization)
	(clear_redundancy_categorization): Adjust.
	(redundancy_marking_visitor::visit_begin): Adjust.  Also, if the
	current diff node is already being traversed (that's a clyclic
	node) then mark it as redundant.
	* src/abg-comp-filter.cc (apply_filter): Adjust.
	* tests/data/test-diff-filter/test16-report-2.txt: New test input data.
	* tests/data/test-diff-filter/libtest25-cyclic-type-v{0,1}.so: New
	test input binaries.
	* tests/data/test-diff-filter/test25-cyclic-type-v{0,1}.cc: Source
	code for the test input binaries.
	* tests/data/test-diff-filter/test25-cyclic-type-report-0.txt: New
	test input data.
	* tests/data/test-diff-filter/test25-cyclic-type-report-1.txt:
	Likewise.
	* tests/test-diff-filter.cc (in_out_specs): Add the new test
	inputs above to the list of test input data over which to run this
	test harness.
	* tests/data/Makefile.am: Add the new test files above to source
	distribution.
	* tests/data/test-diff-filter/test16-report.txt: Adjust.
	* tests/data/test-diff-filter/test17-0-report.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-24 22:48:40 +01:00
Dodji Seketeli
f3344623d3 Tighten the condition for creating a cloned function from DWARF
So, apparently, the DWARF reader can be too eager to clone functions
whose DIE have a DW_AT_abstract_origin.  It seems to be that there are
cases where the second DIE (the one that has the DW_AT_abstract_origin
attribute) has the same linkage name than the first one.  In that
case, no cloning should happen.  And this should fix
https://sourceware.org/bugzilla/show_bug.cgi?id=17861.

	* src/abg-dwarf-reader.cc (build_ir_node): Re-indent.  Also,
	consider that when a DIE C refers to a DIE A via the
	DW_abstract_origin attribute, C represents a clone of A, only if C
	and A have *different* linkage names.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-20 12:37:56 +01:00
Dodji Seketeli
af0923b1b0 Fix the output of the array diff report
While working on something else, I realized the report of the array
diff change wasn't referring to the pretty representation of the array
when talking about the changes of array element type; rather it was
just referring to the array name.  I think referring to the pretty
representation of the array is more helpful.  This patch does just
that.

	* src/abg-comparison.cc (array_diff::report): Refer to the pretty
	representation of the array when talking about changes of the
	array element type.
	* src/abg-ir.cc (equals): In the overload for array_type, use the
	equality operator that knows how to handle null pointers to
	element type.  This avoids crashes when the pointer to element
	type is null.
	* tests/data/test-diff-dwarf/test10-report.txt: Adjust.
	* tests/data/test-diff-filter/test24-compatible-vars-report-1.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-19 15:00:44 +01:00
Dodji Seketeli
63c81f028d Do not install the generated documentation by default
* doc/manuals/Makefile.am: Do not install the generated
	documentation by default

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-14 18:46:06 +01:00
Dodji Seketeli
3ea7c4682e Make sure to install html docs & gziped info on make install
* doc/manuals/Makefile.am: Make sure Make sure to install html
	docs & gziped info on make install

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-14 14:36:20 +01:00
Dodji Seketeli
527d7ab218 Do not install the abinilint program
This program is meant to be used by libabigail developers to debug its
ini file parsing facilities.  So there is no need to install.

	* tools/Makefile.am: Add abinilint to the noinst_PROGRAMS primary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-14 13:20:46 +01:00
Dodji Seketeli
3d969dbe05 Small grammar fix in a manpage title
* doc/manuals/conf.py: Fix the grammar of the title of the abidiff
	man page.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 18:33:38 +01:00
Dodji Seketeli
5059907727 Generate texinfo documentation properly
There was a texinfo documentation that was being generated up to now,
but I haven't really looked at it.  Now that I have handled man pages
generation, I thought I'd give the texinfo generation a closer look
and ensure it's in a correct shape.  This patch cleans the generation
process up, changes the documentation markup so that it looks OK in
the generated texinfo file and handles the install of the generated
texinfo.

	* doc/manuals/Makefile.am: Generate texinfo doc, install it and
	uninstall it.
	* doc/manuals/libabigail-tools.rst: Do not use the :doc: syntax to
	refer to documents because it doesn't seem to work with sphinx
	right now.  Rather, use a table of content.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 18:33:23 +01:00
Dodji Seketeli
69c9f1fbcd Fix man pages installation
The man pages are created only if the user ran 'make man' in
doc/manuals.  So installing the man pages should be conditional on the
presence of the man pages.

	* doc/manuals/Makefile.am: Install the man pages only if they are
	generated.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 12:13:22 +01:00
Dodji Seketeli
1516a78cae Bump the candidate version of the library to 1.0
I think the current status of the source code is closer to a 1.0
status than a 1.0 one.

	* configure.ac: Bump version to 1.0.0

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 11:34:15 +01:00
Dodji Seketeli
b951add9f5 Do not forget to install the Manpages
* doc/manuals/Makefile.am: Add the man pages to the man7_MANS
	automake primary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 11:29:11 +01:00
Dodji Seketeli
b25f1bd7e7 Adjust archive-related code for the recent addition of tools_utils::*
What was in the abigail::tools namespace got recently moved in the
abigail::tools_unit namespace.  I forgot to adjust the client code
related to the archive support because that code is now compiled by
default on my main hacking box.  This patch fixes that.

	* tests/Makefile.am: tools/libtoolsutils.la is no more.
	* tests/test-write-read-archive.cc (main): Adjust.
	* tools/abiar.cc (extract_tus_from_archive): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 11:02:10 +01:00
Dodji Seketeli
e7e2d24c5c Generate Manpages for abidiff, abidw, abilint
* doc/manuals/conf.py: Define man pages for abidiff, abidw,
	abilint and an introductory one for libabigail.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-13 10:34:57 +01:00
Dodji Seketeli
19013fd110 Sort functions & variables diff nodes in the diff tree
Since the work on un-sharing diff tree nodes, it looks like some
reports of regression tests on i686 order functions and variables in
different orders, leading to test failures on 32 bits platforms
because they are different fromthe 64 bits platforms that we use as a
reference.  This patch sorts (lexicographically) the children diff
nodes of a given diff node in general, and also sorts the set of diff
nodes for functions and variables that have sub-type changes, in a
given corpus_diff.  That way, the result of the diff report should be
sorted the same way, whatever the platform.

	* include/abg-comparison.h (function_decl_diff_sptrs_type)
	(var_diff_sptrs_type): New typedefs.
	(corpus_diff::{changed_functions, changed_variables}): Declare new
	methods.
	* src/abg-comparison.cc (sort_string_function_decl_diff_sptr_map)
	(sort_string_var_diff_sptr_map): Forward declare these static
	functions there were already defined later.
	(struct diff_less_than_functor): Define new comparison functor.
	(diff::append_child_node): Sort the children diff nodes of a given
	diff node.
	(corpus_diff::priv::changed_fns_map_): Renamed the data member
	corpus_diff::priv::changed_fns_ into this.
	(corpus_diff::priv::changed_fns_): New data member that is a
	sorted vector of changed functions.
	(corpus_diff::priv::{lookup_tables_empty, clear_lookup_tables}):
	Adjust changed_fns_ -> changed_fns_map_ and changed_vars_ ->
	changed_vars_map_.
	(corpus_diff::priv::ensure_lookup_tables_populated): Likewise.
	Sort the changed functions and changed variables.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Adjust
	changed_fns_ -> changed_fns_map_ and changed_vars_ ->
	changed_vars_map_.  Also, walk the changed functions and variables
	diff nodes in their sorted order.
	(corpus_diff::priv::{categorize_redundant_changed_sub_nodes,
	clear_redundancy_categorization, maybe_dump_diff_tree}): Walk the
	changed functions and variables diff nodes in their sorted order.
	* include/abg-ir.h
	(function_decl::get_pretty_representation_of_declarator):
	Declarenew method.
	* src/abg-ir.cc
	(function_decl::get_pretty_representation_of_declarator): Define
	new function.  Its content got split out of ...
	(function_decl::get_pretty_representation): ... this one.
	* src/abg-comparison.cc (corpus_diff::chain_into_hierarchy):
	Consider the sorted the children nodes of a diff tree node.
	(corpus_diff::append_child_node): Keep the children nodes of a
	diff tree node sorted.
	(corpus_diff::{changed_functions, changed_variables, length,
	report}): Adjust.
	(corpus_diff::{changed_functions_sorted,
	changed_variables_sorted}): Define new functions.
	(function_comp::operator()): First compare the qualified function
	names along with the parameter declarations, then the rest.
	(sort_string_function_decl_diff_sptr_map)
	(sort_string_var_diff_sptr_map): Adjust.
	* tests/data/test-abicompat/test0-fn-changed-report-0.txt: Adjust.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: Adjust.
	* tests/data/test-diff-suppr/test8-redundant-fn-report-0.txt:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-09 14:45:11 +01:00
Dodji Seketeli
3c22bdae88 Fix logic of function parmeters diff redundancy detection
When looking at something else, I noticed that the code that detects
that a diff node for a function parameter was being redundant with
respect to another diff node for a parameter of the same function had
a bug; if a function parameter diff node (for a function that has more
than one parameter diff node) carried a change, then that diff node
was always considered to be redundant with another parameter diff node
of the same function.  This patch fixes that.

	* src/abg-comparison.cc (redundancy_marking_visitor::visit_begin):
	For a given function parameter diff node N, we were comparing it
	against the other parmeter diff nodes of the function.  This
	change ensures that we do not compare N against itself.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-09 14:11:02 +01:00
Dodji Seketeli
7c2a0940e2 Update copyright year for tests/test-abicompat.cc
* tests/test-abicompat.cc: Update copyright year.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-09 14:09:16 +01:00
Dodji Seketeli
f9b21d7f80 Enhance the format of the diff tree dumping report
This patch changes the format of the diff tree dumping report emitted
by abidiff --dump-diff-treee to make it more hierachical and also add
two new properties: the address of the diff tree node and the address
of its canonical diff tree node.

	* src/abg-comparison.cc (diff_node_printer::do_indent): New
	method.
	(diff_node_printer::visit): Use diff_node_printer::do_indent().
	Print the addresses of the diff tree node and its canonical node.
	Add some vertical spaces and some indenting to make the report
	more readable.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-09 14:04:59 +01:00
Dodji Seketeli
322b0e7769 Expose a new libabigail::tools_utils namespace
The utilities present in this namespace were previously living in
tools/abg-tools-utils.h and tools/abg-tools-utils.cc.  They were not
exported and were meant to be useful to the tools writting in the
tools/ directory.  I realized that these utilities might be useful to
clients of the libabigail library in general so I am making them
available generally.  Note that the initial name of the namespace was
libabigail::tools; so renaming it to libabigail::tools_utils required
that I adjust some client code.  I have also cleaned up the code,
interfaces and their apidoc a little bit.

	* include/abg-tools-utils.h: Moved tools/abg-tools-utils.h in
	here.  Renamed the namespace tools into tools_utils.  Inject
	std::ostream, std::istream, std::ifstream, and std::string types
	into the tools_utils namespace.  Adjust the function declarations
	accordingly.  Remove the useless dirname() function declaration.
	* include/Makefile.am: Add abg-tools-utils.h to the list of
	exported headers.
	* src/abg-tools-utils.cc: Moved tools/abg-tools-utils.cc in here.
	Renamed the namespace tools into tools_utils.
	(get_stat): Add apidoc.
	(is_dir): Cleanup apidoc.
	(dir_name); Cleanup parameter name.
	(guess_file_type): Cleanup parameter type.
	* src/Makefile.am: Add abg-tools-utils.cc to the list of exported
	headers.
	* tools/Makefile.am: Do not build the temporary library
	libtoolsutils.la anymore as abg-tools-utils.{h,cc} have moved out
	of this directory.
	* tools/abicompat.cc (parse_command_line, main): Adjust for tools
	-> tools_utils namespace change.
	* tools/abidiff.cc (parse_command_line, main): Likewise.
	* tools/abidw.cc (parse_command_line, main): Likewise.
	* tools/abilint.cc (parse_command_line, main): Likewise.
	* tests/test-abicompat.cc (main): Adjust for tools -> tools_utils
	namespace change.
	* tests/test-abidiff.cc (main): Likewise.
	* tests/test-alt-dwarf-file.cc (main): Likewise.
	* tests/test-core-diff.cc (main): Likewise.
	* tests/test-diff-dwarf.cc (main): Likewise.
	* tests/test-diff-filter.cc (main): Likewise.
	* tests/test-diff-suppr.cc (main): Likewise.
	* tests/test-lookup-syms.cc (main): Likewise.
	* tests/test-read-dwarf.cc (main): Likewise.
	* tests/test-read-write.cc (main): Likewise.
	* tests/Makefile.am: Do not reference the libtoolsutils.la private
	library anymore.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-08 12:28:14 +01:00
Dodji Seketeli
76837d1cbf Update copyright years
* include/abg-comp-filter.h: Update copyright years.
	* 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-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-sptr-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-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus.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-ir.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.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-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.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-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tools/abg-tools-utils.cc: Likewise.
	* tools/abg-tools-utils.h: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-07 17:52:10 +01:00
Dodji Seketeli
929db0a880 Detect and report changes in ELF architecture
Libabigail does not take in account the architecture of the ELF file
it reads.  This patch changes that to represent the ELF architecture
as a string, detect when that architecture changes accross two corpora
being compared and emit a report about that change.

	* configure.ac: Detect the presence of libebl.a and add it to the
	list of library we depend on to build libabigail.  Report when
	libelf.so is not found.
	* include/abg-comparison.h:
	(diff_context::show_architecture_change): Declare new accessors.
	(corpus_diff::architecture_changed): Declare new method.
	* include/abg-corpus.h (corpus::{get,set}_architecture_name):
	Declare new accessors.
	* src/abg-comparison.cc
	(diff_context::priv::show_architecture_change_): New data member.
	(diff_context::priv::priv): Initialize it.
	(diff_context::show_architecture_change): Define new accessors.
	(function_decl_diff::report): Report when the size/alignment of
	the function address changes.
	(corpus_diff::priv::architectures_equal_): New data member.
	(corpus_diff::priv::priv): Initialize it.
	(corpus_diff::priv::emit_diff_stats): Take in account changes of
	architecture.
	(corpus_diff::architecture_changed): Define new method.
	(corpus_diff::length): Take in account changes of architecture.
	(corpus_diff::report): Report about changes of architecture.
	(compute_diff): In the overload for corpus_diff_sptr, detect
	changes fo architecture.
	* src/abg-corpus.cc (corpus_priv::architecture_name): Define new
	data member.
	(corpus::{get,set}_architecture_name): Define new method.
	* src/abg-dwarf-reader.cc: Include elfutils/libebl.h to use
	ebl_openbackend() and ebl_backend_name()
	(read_context::elf_architecture_): Define new data member.
	(read_context::elf_architecture): Define new accessor.
	(read_context::{load_elf_architecture, load_remaining_elf_data}):
	Define new methods.
	(read_corpus_from_elf): Use ctxt.load_remaining_elf_data() in lieu
	of ctxt.load_dt_soname_and_needed.  Stick the architecture into
	the corpus.
	* src/abg-reader.cc (read_corpus_from_input): Read the
	'architecture' XML property.
	* src/abg-writer.cc (write_corpus_to_native_xml): Write the
	'architecture' XML property.
	* tests/data/test-diff-dwarf/libtest-23-diff-arch-v0-32.so: New
	test input file.
	* tests/data/test-diff-dwarf/libtest-23-diff-arch-v0-64.so:
	Likewise.
	* tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test-23-diff-arch-v0.cc: Source code
	for the binary test input files above.
	* tests/data/Makefile.am: Add the new test input files to the
	source distribution.
	* tests/test-diff-dwarf.cc (in_out_specs): Add the new test input
	data to the set of input data to run this test harness over.
	* tests/test-read-dwarf.cc (main): Do not take the architecture in
	account during comparisons.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-07 17:52:10 +01:00
Sinny Kumari
20df3be7eb Include libabigail-website.doxy file in EXTRA_DIST
Without having doc/website/libabigail-website.doxy file
included in source distribution, make html-doc was giving error.

	* doc/Makefile.am: Include website/libabigail-website.doxy
	file in EXTRA_DIST

Signed-off-by: Sinny Kumari <skumari@redhat.com>
2015-01-06 15:40:18 +01:00
Dodji Seketeli
f5f5de375a Delete ltsugar.m4 and pkg.m4 files from m4/
I somehow forgot these autotools-generated files in the source code
repository.  Removed thus.

	* m4/ltsugar.m4: Removed.
	* m4/pkg.m4: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-01-06 09:54:45 +01:00
Dodji Seketeli
05615c95d8 Enable parallel tests
* configure.ac (AM_INIT_AUTOMAKE): Enable parallel tests by
	switching on the parallel-tests option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-28 11:37:49 +01:00
Dodji Seketeli
0e1d9f9892 Add a --dump-diff-tree to abidiff for debugging purposes
I have felt the need to emit a textual representation of the diff
nodes tree maintained by the comparison engine for changed functions
and variables.  This patch adds that functionality.

	* include/abg-comparison.h (enum visiting_kind): Add new
	DO_NOT_MARK_VISITED_NODES_AS_TRAVERSED enumerator.
	(diff_context::{default_output_stream, error_output_stream,
	dump_diff_tree}): Declare new accessors.
	(diff::end_traversing): Take a new boolean flag.
	(print_diff_tree): Add new overload for diff_sptr.
	* src/abg-comparison.cc
	(diff_context::priv::{default_output_stream_,
	error_output_stream_, dump_diff_tree_}): New data members.
	(priv::priv): Initialize them.
	(diff_context::{default_output_stream_, error_output_stream_,
	dump_diff_tree, dump_diff_tree}): Define new accessors.
	(diff::end_traversing): Take a new flag that control whether or
	not to mark the current diff node as having been traversed.
	(diff::traverse): Take in account the visiting kind carried by the
	visitor to determine if the visited node should be marked as being
	traversed.
	(corpus_diff::priv::maybe_dump_diff_tree): Define new member
	function.
	(corpus_diff::report): Call it.
	(diff_node_printer::visit): Pretty print the diff node just once.
	(print_diff_tree): Define a new overload for diff_sptr.
	* tools/abidiff.cc (options::dump_diff_tree): New data member.
	(options::options): Initialize it.
	(display_usage): Add a help string for the new --dump-diff-tree
	command line switch.
	(parse_command_line): Parse the new --dump-diff-tree command line
	switch.
	(set_diff_context_from_opts): Set the diff context according to
	the --dump-diff-tree presence.
	* doc/manuals/abidiff.rst: Add a bullet point for the new
	--dump-diff-tree command line switch.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-28 11:36:52 +01:00
Dodji Seketeli
5895bcf031 Fix typos in the abicompat manual
* doc/manuals/abicompat.rst: Fix typos.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-27 10:23:58 +01:00
Dodji Seketeli
f8213ce3d5 Fix a typo in the abidiff manual
* doc/manuals/abidiff.rst: Fix a typo.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-27 10:20:56 +01:00
Dodji Seketeli
2afa86fec1 Fix redundancy in abidiff manual
* doc/manuals/abidiff.rst: Remove the redundant bullet point about
	the --drop-fn command line switch.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-27 10:18:42 +01:00