Commit Graph

1813 Commits

Author SHA1 Message Date
Matthias Maennich
c06c45f345 Update tests/.gitignore to ignore runtesttoolsutils
* tests/.gitignore: ignore runtesttoolsutils

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-07-09 17:33:58 +02:00
Matthias Maennich
42cd02a9be Drop requirement to compile with GNU extensions
__gnu_cxx::stdio_filebuf is a GNU extension only available in certain
std libraries. It is not e.g. in libc++. In order to be able to compile
with using libc++, replace the usage of __gnu_cxx::stdio_filebuf with
standard C++ methods. In this case, reopen the temporary file with a
std::fstream and expose that stream rather than the previously exposed
std::iostream.

	* include/abg-tools-utils.h (get_stream): Change return type to
	  std::fstream
	* src/abg-corpus.cc: remove unused #include of ext/stdio_filebuf.h
	* src/abg-tools-utils (temp_file::priv): remove filebuf_ member,
	  and replace iostream_ by fstream_ with changing the shared_ptr
	  type accordingly
	  (temp_file::priv::priv): initialize fstream_ based on
	  temporary file name
	  (temp_file::priv::~priv): adjust destruction accordingly
	  (temp_file::is_good): test the fstream rather than the fd
	  (temp_file::get_stream): adjust return type to std::fstream
	  and adjust implementation based on the changes in temp_file::priv
	* src/Makefile.am: remove gnu extension from c++ standard flag
	* tests/Makefile.am: likewise

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-09 17:16:59 +02:00
Dodji Seketeli
bb01e648ef Misc indent cleanup
* src/abg-dwarf-reader.cc (addr_elf_symbol_sptr_map_sptr): Fix a
	typo in the comment of this typedef.
	* src/abg-ir.cc (hash_type_or_decl): Fix typo in a comment.
	* src/abg-writer.cc (write_translation_unit): Remove useless
	vertical space.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-09 09:21:24 +02:00
Dodji Seketeli
eff603b4c3 [xml-writer] Remove a useless kludge
* src/abg-writer.cc (write_context::type_is_emitted): Remove
	useless kludge from here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 17:16:59 +02:00
Dodji Seketeli
7699dfc921 [xml-writter] Speedup function_type::get_cached_name
It looks like due to a typo, we are never caching the name of the
function_type, so we are computing it all the time, *OOOPS*.  So this
is having an impact when comparing instance of function_type during
de-duplication at abixml writting time.

Things are faster now, thanks to this patch.

	* src/abg-ir.cc (function_type::get_cached_name): Really cache the
	computed name of function_type instances.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 17:11:30 +02:00
Dodji Seketeli
65318dacfb [xml-writter] Avoid using RTTI when dynamically hashing types
When we dynamically hash types in the abixml writter, we use
hash_type_or_decl.  This function uses runtime type identification to
determine if the (type) artifact is a decl or a type, and based on
that, choose how to compute its hash value.  Profiling shows that
using the RTTI in hash_type_or_decl at this point is a hotspot.

Because we know that the type ABI is a *type*, we obviously can avoid
using RTTI there.

The patch thus implements a hash_type function, and uses that in the
xml writter.  Emitting the abixml output is faster with this patch.

	* include/abg-fwd.h (hash_type): Declare new function.
	* src/abg-ir.cc (hash_type): Define new function.
	* src/abg-writer.cc (type_hasher::operator()): Use the new
	  hash_type rather than the old hash_type_or_decl.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 16:59:03 +02:00
Dodji Seketeli
c940a229c9 Implement a poor-man's RTTI for performance
Profiling showed that a number of use of dynamic_cast are a speed
bottleneck.

This patch implements a poor-man's RTTI that allows us to implement a
form of dynamic_cast that is specific to the types of the internal
reprenstation that are in the namespace abigail::ir.  It speeds up
things greatly.

Basically, the base type of all ABI artifacts
(abigail::ir::type_or_decl_base) now contains three new data members.
The first one contains a bitmap that identifies the type of artifact.
The second one contains a pointer to the dynamic type sub-object of
the current instance of the artifact.  The last one contains either a
pointer to the type_base sub-object of the current instance of ABI
artifact if it's a type, or a pointer to the type_decl sub-object of
the current instance.

Together these three data members allow the patch to implement the
abigail::ir::{is_type(), is_decl(), is_<type_kind>_type} functions
that we need to make the code base noticeably faster when using abidw
on a big vmlinux binary.

	* include/abg-fwd.h (is_type_decl): Replace the overloads
	that takes a type_base* and/or a decl_base* by one that takes a
	type_or_decl_base*.
	* include/abg-ir.h (type_or_decl_base::type_or_decl_kind): Define
	new enum.
	(type_or_decl_base::{kind, runtime_type_instance,
	type_or_decl_base_pointer}): Declare new accessors.
	(operator{|,|=,&,&=): Declare new operators for the new
	type_or_decl_base::type_or_decl_kind enum.
	(global_scope::global_scope): Move the definition of this
	constructor to ...
	* src/abg-ir.cc (global_scope::global_scope): ... here.
	(type_or_decl_base::priv::{kind_, rtti_, type_or_decl_ptr_}):
	Add new data members.
	(type_or_decl_base::priv::priv): Take a
	type_or_decl_base::type_or_decl_kind enum.
	(type_or_decl_base::priv::kind): Define new accessors.
	(operator{|,|=,&,&=): Define new operators for the new
	type_or_decl_base::type_or_decl_kind enum.
	(type_or_decl_base::type_or_decl_base): Take a
	type_or_decl_base::type_or_decl_kind enum.
	(type_or_decl_base::{kind, runtime_type_instance,
	type_or_decl_base_pointer}): Define new accessors.
	(decl_base::decl_base, scope_decl::scope_decl)
	(type_base::type_base, scope_type_decl::scope_type_decl)
	(class_or_union::class_or_union) : Adjust to set the runtime type
	identifier of the instances of these types.
	(global_scope::global_scope, type_decl::type_decl)
	(qualified_type_def::qualified_type_def)
	(pointer_type_def::pointer_type_def)
	(reference_type_def::reference_type_def
	array_type_def::subrange_type::subrange_type)
	(array_type_def::array_type_def, enum_type_decl::enum_type_decl)
	(typedef_decl::typedef_decl, var_decl::var_decl)
	(function_type::function_type, method_type::method_type)
	(function_decl::function_decl)
	(function_decl::parameter::parameter, method_decl::method_decl)
	(class_decl::class_decl, class_decl::base_spec::base_spec)
	(union_decl::union_decl, template_decl::template_decl)
	(type_tparameter::type_tparameter)
	(non_type_tparameter::non_type_tparameter)
	(template_tparameter::template_tparameter)
	(type_composition::type_composition)
	(function_tdecl::function_tdecl, function_tdecl::function_tdecl)
	(class_tdecl::class_tdecl):
	Likewise and call runtime_type_instance() here to set the runtime
	type instance pointers of the current instance.
	(is_decl, is_type, is_class_type, is_pointer_type): Adjust to use
	the new poor-man's rtti machinery.
	(is_type_decl): Replace the overloads that takes a type_base*
	and/or a decl_base* by one that takes a type_or_decl_base*.
	(pointer_type_def::operator==, class_decl::operator==): Use the
	poor-man's rtti machinery to replace dynamic_cast.
	hash_type_or_decl: Replace dynamic_cast<const type_base> by
	is_type() and dynamic_cast<const decl_base*> by is_decl().

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 16:52:59 +02:00
Dodji Seketeli
35312fa92a [dwarf-reader] Make sure to canonicalize anonymous types
For a reason, anonymous types are not canonicalized.  I think this is
due to the fact that because they have no name,
read_context::lookup_type_from_die(die) used by maybe_canonicalize_type()
falls short in trying to canonicalize the *DIE*.

So later, at comparison time, things can be really slow because we
can't do canonical comparison; we ressort to structural comparison.

This patch ensures that even anonymous types are canonicalized.

	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Add two new
	overloads.  One that takes type_base_sptr, one that takes a
	Dwarf_Die* and type_base_sptr.  These force canonicalization for
	anonymous types.
	(build_function_type): Schedule function types for
	canonicalization.
	(build_ir_node_from_die): For struct/classes and unions, use the
	new overload of maybe_canonicalize_type to schedule
	canonicalization.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: 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/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>
2019-07-08 09:50:29 +02:00
Dodji Seketeli
c8ba373e65 [dwarf-reader] Constify the first parameter of maybe_canonicalize_type
In preparation for some coming patches, I figured it'd be more type
safe to make the Dwarf_Die parameter of maybe_canonicalize_type be a
const pointer.  The patch subsequently adjusts code that needs adjusting.

	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Make the
	first parameter const.
	(read_context::{get_canonical_die, lookup_artifact_from_die,
	lookup_type_from_die, schedule_type_for_late_canonicalization}):
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 09:26:43 +02:00
Dodji Seketeli
2209df1b90 Make abidiff --harmless show harmless changes in unions
Since the previous commit filters out harmless changes inside unions,
this one allows those changes to be reported whenever the user runs
abidiff with the --harmless option.

The patch just displays the "before" and "after" of the union because
some of the harmless changes are not tracked anymore.

Because we want to display the before and after of the union we use
the function get_class_or_union_flat_representation.  The patch adds a
"qualified_name" boolean parameter to that function so that we can
choose to display union members names in a non-qualified fashion,
which is the natural way of displaying those names in the context of a
union (or class) representation.  Because
get_class_or_union_flat_representation uses
type_or_decl_base::get_pretty_representation, the patch has also added a
"qualified_name" boolean parameter to that function so that we can
choose to display names in a non-qualified manner.

	* include/abg-fwd.h (get_class_or_union_flat_representation): Add
	a "qualified_name" boolean parameter.
	* include/abg-ir.h ({type_or_decl_base, decl_base, type_decl,
	namespace_decl, array_type_def::subrange_type, array_type_def,
	enum_type_decl, typedef_decl, var_decl, function_decl,
	function_decl::parameter, function_type, method_type, class_decl,
	union_decl}::get_pretty_representation): Likewise.
	* src/abg-ir.cc ({type_or_decl_base, decl_base, type_decl,
	namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl,
	typedef_decl, var_decl, function_decl, function_decl::parameter,
	function_type, method_type, class_decl, union_decl,
	}::get_pretty_representation): Adjust the code to emit qualified
	or non-qualified names depending on the new "qualified_name"
	boolean parameter.
	(get_class_or_union_flat_representation): Likewise.
	* src/abg-default-reporter.cc (default_reporter::report): Use
	get_class_or_union_flat_representation with the new
	"qualified_name" boolean set to false.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Adjust.
	* tests/test-diff-filter.cc (in_out_specs): Run the test harness
	on test-PR24731-v{0,1}.o make abidiff use the --harmless option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-26 12:08:55 +02:00
Dodji Seketeli
a11a0068ea Bug 24731 - Wrongly reporting union members order change
When union data members are re-ordered, abidiff reports the
re-ordering as if it was a meaningful ABI change.

This patch teaches Libabigail to categorize that benign type layout
change as a HARMLESS_UNION_CHANGE_CATEGORY kind of change and ignore it.

	* include/abg-comp-filter.h (union_diff_has_harmless_changes):
	Declare new function and ...
	* src/abg-comp-filter.cc (union_diff_has_harmless_changes):
	... define it here.
	(categorize_harmless_diff_node): Use the new
	union_diff_has_harmless_changes here.
	* include/abg-comparison.h (HARMLESS_UNION_CHANGE_CATEGORY): Add a
	new enumerator to diff_category enum.  Adjust the value of the
	other enumerators.
	* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
	Add the new HARMLESS_UNION_CHANGE_CATEGORY in here.
	(operator<<(ostream& o, diff_category c)): Support the new
	HARMLESS_UNION_CHANGE_CATEGORY.
	* tests/data/test-diff-filter/test-PR24731-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test-PR24731-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v0.c: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v0.o: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v1.c: Likewise.
	* tests/data/test-diff-filter/test-PR24731-v1.o: Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	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>
2019-06-26 11:09:43 +02:00
Dodji Seketeli
bf100fcb41 Fully account for anonymous-ness of scopes when comparing decl names
When comparing internal decl names (as part of decl comparison), we
need to take into account the fact that a given decl might be
anonymous and that it might have anonymous scopes in its tree of
containing scopes.

For instance, "__anonymous_struct__1::foo" and
"__anonymous_struct__2::foo" are considered equivalent.

So are "__anonymous_struct__1::foo::__anonymous_struct__2::bar" and
"__anonymous_struct__10::foo::__anonymous_struct__11::bar".

But "__anonymous_struct__1::bar::__anonymous_struct__2::baz" and
"__anonymous_struct__10::foo::__anonymous_struct__11::bar" are not.

This patch introduces the function tools_utils::decl_names_equal that
compares fully qualified names by taking into account anonymous
component names.

That function is thus used in the equals() function overload for
decl_base types.  Because tools_utils::decl_names_equal compares strings the
usual way (character by character) it's slower than comparing
instances of interned_string in a O(1) time.  So the patch carefully
tries to use tools_utils::decl_names_equal sparringly; that is, it
uses it only when we are looking at decls that have some anonymous
scope.  That way, we use the fast interned_string comparison most of
the time.  By doing this, we barely see any performance degradation
while running abidw --noout on a full blown vmlinux binary.

	* include/abg-ir.h (decl_base::{get_has_anonymous_parent,
	set_has_anonymous_parent,
	get_is_anonymous_or_has_anonymous_parent}): Declare new member
	functions.
	* src/abg-ir.cc (decl_base::priv::has_anonymous_parent_): Define
	new data member.
	(decl_base::priv): Initialize the new data member.
	(decl_base::{get_has_anonymous_parent, set_has_anonymous_parent,
	get_is_anonymous_or_has_anonymous_parent}): Define new member
	functions.
	(equals): In the overload for decl_base, use the new
	decl_names_equal for decls that have anonymous scopes.
	(scope_decl::add_member_decl): Propagate the
	decl_base::has_anonymous_parent_ property.
	* include/abg-tools-utils.h
	(get_anonymous_struct_internal_name_prefix)
	(get_anonymous_union_internal_name_prefix)
	(get_anonymous_enum_internal_name_prefix, decl_names_equal):
	Declare new functions.
	* src/abg-comp-filter.cc (has_harmless_name_change): Handle the
	case where the name change is actually from an anonymous name to
	another one, using the new decl_names_equal function.
	* src/abg-dwarf-reader.cc
	(get_internal_anonymous_die_prefix_name): Renamed
	get_internal_anonynous_die_base_name into this.  Use the new
	get_anonymous_{struct, union, enum}_internal_name_prefix functions
	here.
	(get_internal_anonymous_die_name, die_qualified_type_name)
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): Adjust.
	* src/abg-tools-utils.cc (get_anonymous_struct_internal_name_prefix)
	(get_anonymous_union_internal_name_prefix)
	(get_anonymous_enum_internal_name_prefix, decl_names_equal):
	Define new functions.
	* tests/test-tools-utils.cc: New test file.
	* tests/Makefile.am: Add new runtesttoolsutils test, built from
	test-tools-utils.cc.
	* tests/data/test-diff-dwarf/test46-rust-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-3.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-21 11:42:44 +02:00
Matthias Maennich
2651a3623a abg-reporter.h: add missing includes / using declarations
In order to build this (external!) header file stand-alone, it required
some minor fixes. I.e. adding some includes and using declarations.

	* include/abg-reporter.h: fix includes and using declarations

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-06-17 15:25:18 +02:00
Dodji Seketeli
f821382933 [dwarf-reader] Fix indentation in compare_dies_string_attribute_value
While looking at something else, I realized that
compare_dies_string_attribute_value had some indentation that was off.

Fixed thus.

	* src/abg-dwarf-reader.cc (compare_dies_string_attribute_value):
	Fix indentation.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-17 14:56:50 +02:00
Dodji Seketeli
133d43ad19 [dwarf-reader] Optimize speed of compare_as_decl_dies
Profiling shows that the *number of calls* to
compare_dies_string_attribute_value by compare_as_decl_dies represents
a hotspot.  That is, compare_dies_string_attribute_value itself
doesn't necessarily takes long, but it's being called "too much",
especially when compare_as_decl_dies is called for DIEs representing
classes/structs.

This patch thus reduces the calls to
compare_dies_string_attribute_value from 3 to 1 for classes/structs.

This optimization makes abidw's reading be 10% faster (from ~5min:15s
to ~ 4min:45s) on a fullblow vmlinux.  Note that abidw writting time
hasn't been yet optimized.

	* src/abg-dwarf-reader.cc (die_is_class_type): Take a const
	pointer to Dwarf_Die.
	(compare_as_decl_dies): For classes/structs, call
	compare_dies_string_attribute_value just once to compare the
	DW_AT_name attribute values.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-17 14:56:43 +02:00
Dodji Seketeli
23744b4b8e [dwarf-reader] Better use of linkage name for fn decl de-duplication
When looking at a C program, during function decl DIE de-duplication
at we can rely on linkage names of function declarations to quickly
determine if two function decls are equal, in a given binary.

This patch uses that observation to speed up function decl DIE
de-duplication.  abidw --noout vmlinux goes from 8 to 5 minutes with
this.

	* src/abg-dwarf-reader.cc (read_context::{die_is_in_c,
	die_is_in_c_or_cplusplus}): Define new member functions.
	(fn_die_equal_by_linkage_name): Define new static function.
	(compare_dies): In the case for for DW_TAG_subprogram, use the new
	fn_die_equal_by_linkage_name.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 18:28:12 +02:00
Dodji Seketeli
6149fb02d0 [dwarf-reader] Re-use function types inside a given TU
Whenever we see a function type inside a translation unit, if it
matches one that has already been seen -- i.e, one that has the same
textual representation -- we should be able to re-use that same
function type without having to compare their types to be sure they
are the same, as part of the type canonicalization process.

This slittly increases analysis speed (by a few tens of seconds on a
total of 8 minutes) by decreasing the load on type canonicalization
when anlyzing vmlinux.  It also slightly reduces memory consumption,
so I am getting it in for now.

	* src/abg-dwarf-reader.cc (istring_fn_type_map_type): Declare new
	typedef.
	(die_is_function_type): Define new static function.
	(read_context::per_tu_repr_to_fn_type_maps_): Define new data
	member ...
	(read_context::per_tu_repr_to_fn_type_maps): ... and its accessor.
	(read_context::{associate_die_repr_to_fn_type_per_tu,
	lookup_fn_type_from_die_repr_per_tu}): Define new member
	functions.
	(build_function_type): Use the new
	read_context::lookup_fn_type_from_die_repr_per_tu and
	read_context::associate_die_repr_to_fn_type_per_tu functions,
	instead of read_context::lookup_type_from_die.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.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/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 18:28:11 +02:00
Dodji Seketeli
2528644c03 [dwarf-reader] const-ify Dwarf_Die* use in many places
This is useful to prepare a subsequent patch that uses
get_die_pretty_type_representation with a const Dwarf_Die*.  Trying to
const-ify the use of Dwarf_Die* in that function leads to a cascade of
const-ification.  Much needed anyway.

	* src/abg-dwarf-reader.cc (get_parent_die, get_scope_die)
	(die_is_anonymous, die_is_type, die_is_decl, die_is_namespace)
	(die_is_pointer_type, pointer_or_qual_die_of_anonymous_class_type)
	(die_is_reference_type, die_is_pointer_or_reference_type)
	(die_is_qualified_type, die_has_object_pointer)
	(die_is_at_class_scope, die_unsigned_constant_attribute)
	(die_signed_constant_attribute, die_attribute_is_signed)
	(die_attribute_is_unsigned, die_attribute_has_no_signedness)
	(die_name, die_location, 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_function_type_is_method_type)
	(die_pretty_print_type, die_pretty_print_decl, die_pretty_print)
	(maybe_canonicalize_type, build_subrange_type)
	(build_subranges_from_array_type_die, compare_dies)
	(read_context::get_container)
	(read_context::compute_canonical_die_offset)
	(read_context::get_or_compute_canonical_die)
	(read_context::get_die_source)
	(read_context::get_die_qualified_type_name)
	(read_context::get_die_pretty_representation)
	(read_context::get_die_language, read_context::odr_is_relevant)
	(read_context::set_canonical_die_offset)
	(read_context::associate_die_to_type, die_is_anonymous)
	(die_string_attribute, die_constant_attribute)
	(die_attribute_has_form, die_linkage_name)
	(die_decl_file_attribute, die_die_attribute, die_size_in_bits)
	(die_is_decl, die_is_namespace)
	(pointer_or_qual_die_of_anonymous_class_type, die_is_array_type)
	(die_is_pointer_reference_or_typedef_type)
	(die_peel_pointer_and_typedef, die_function_type_is_method_type)
	(die_virtuality, die_is_virtual)
	(compare_dies_string_attribute_value, compare_dies_cu_decl_file)
	(die_location_expr, die_member_offset)
	(get_internal_anonynous_die_base_name, compare_as_decl_dies)
	(compare_as_type_dies): Const-ify the Dwarf_Die* parameter(s) of
	these functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 18:28:04 +02:00
Dodji Seketeli
073608f47d Take anonymous scopes into account when comparing decls
This is another attempt at handling anonymous decls comparison.  It's
not the full blown method that I'd like, but this one seems to be fast
enough.  In this method, we take the immediate scope (and whether it's
anonymous or not) of the anonymous decl into account.

	* include/abg-interned-str.h (interned_string::clear): Add new
	member function.
	* src/abg-ir.cc (equals): In the overload for decl_base, consider
	the scope of the current (anonymous) decl.  If that scope is
	anonymous then take that into account as well.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Adjust.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-13 17:54:45 +02:00
Matthias Maennich
fb70149cb1 .clang-format: Add more options for match existing coding style
Add options for constructor intializers, using declarations and
consecutive declarations.

Even though sorting using declarations could be useful, it changes too
much existing code as of now.

	* .clang-format: Add options for ConstructorInitializers
	Set SortUsingDeclarations=false
	Set AlignConsecutiveDeclarations=true

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:34:31 +02:00
Matthias Maennich
b7a99e2299 .gitignore: Add libabigail-?.* *.orig files
- Artifacts produced by `make dist` should be ignored.
- Artifacts produced by git merge resolution should be ignored.

	* .gitignore: add entries for distribution artifacts
	* .gitignore: add *.orig files

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:34:23 +02:00
Matthias Maennich
1e67db0797 abg-writer: drop deprecated API
Drop the deprecated overloads for write_translation_unit, write_corpus,
write_corpus_group. Also remove the deprecation facilities as they are
not used anymore.

	* include/abg-fwd.h (ABG_DEPRECATED): Remove this macro.
	* include/abg-writer.h (write_translation_unit, write_corpus)
	(write_corpus_group): Drop the deprecated overloads of these
	declarations.
	* src/abg-writer.cc (write_translation_unit, write_corpus)
	(write_corpus_group): Drop the deprecated overloads of these
	definitions.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
f3f7537b6e abidw: add option to only emit file names (--short-locs)
Various emitted directories contain machine specific information and
therefore break reproducibility of abidw's output across different
build paths.

Hence introduce --short-locs to only emit file names.

Thanks to earlier changes, adding an option boils down to adding it to
set_opts and to the write_context along with some auxiliary functions
for setting and getting.

	* include/abg-writer.h (set_short_locs): Declare new function.
	(set_common_options): Use it.
	set_opts
	* src/abg-writer.cc (write_context::m_short_locs): New data
	member.
	(write_context::write_context): Initialize it.
	(write_context::{g,s}et_short_locs): Define new accessors.
	(write_location, write_translation_unit, write_corpus): Honour the
	new write_context::get_short_locs property.
	(set_short_locs): Define new function.
	* tools/abidw.cc (options::short_locs): New data member.
	(display_usage): Help string for the new --no-show-locs option.
	(parse_command_line): Parse the new --no-show-locs option.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
bf9e8b9448 abidw: add option to omit the compilation directory
The compilation directory contains machine specific information
therefore breaks reproducibility of abidw's output across different
build paths. Hence introduce --no-comp-dir-path (as in the xml
attribute). Internally I decided to not carry on the duplication of
'dir' and 'path' and used 'comp_dir'.

Thanks to earlier changes, adding an option boils down to adding it to
set_common_options and to the write_context along with some auxiliary
functions for setting and getting.

write_translation_unit uses the flag in the write_context and omits the
comp-dir-path if asked for.

	* include/abg-writer.h (set_write_comp_dir): Declare new function.
	(set_common_options): Use it.
	* src/abg-writer.cc (write_context::m_write_comp_dir): Define new
	data member.
	(write_context::write_context): Initialize it.
	(write_context::{g,s}et_write_comp_dir): Define new member
	accessors.
	(set_write_comp_dir): Define new free-form getter.
	(write_translation_unit): Teach to respect write_comp_dir flag of
	write_context.
	* tools/abidw.cc (options::write_corpus_path): Define new data
	member.
	(options::options): Initialize it.
	(display_usage): Add doc string for a new command line option: --no-comp-dir-path.
	(parse_command_line): Parse the new command line option --no-comp-dir-path.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
fca2661581 Make write_architecture and write_corpus_path flags in the write_context
Having write_context carry corresponding flags for output sensitive
command line options, is useful to ensure these options are not lost in
chains for write_* calls. In particular, these options can have various
meanings depending on the context (corpus, corpus_group, etc.)

Hence add them to the write_context along with getters and setters and
make the writers aware of their existence. We do not need to modify the
corpus or corpus group's path or architecture any longer as they get
ignored for a different reason now.

Finally, drop the flag handling in abidw as it is already done via
set_opts, which learned about these new flags.

	* include/abg-writer.h (set_write_architecture)
	(set_write_corpus_path): Declare new getter functions.
	(write_corpus): Take a new "member_of_group" argument.
	(set_common_options): Use set_write_{architecture, corpus_path}
	here.
	* src/abg-writer.cc (write_context::m_write_{architecture,
	corpus_path}}): Add new data members.
	(write_context::write_context): Initialize the new data members.
	(write_context::{s,g}et_write_{architecture, corpus}): Define new
	accessors.
	(set_write_{architecture, corpus}): Define new free-form getter
	functions.
	(write_corpus): Add flag to make aware if written as part of a
	group.
	* tools/abidw.cc (load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml): Drop obsolete option
	handling as xml_writer::set_common_options now takes care of it.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>

ldiff --git a/include/abg-writer.h b/include/abg-writer.h
index 200b5f7..729b455 100644
--- a/include/abg-writer.h
+++ b/include/abg-writer.h
@@ -53,6 +53,11 @@ set_show_locs(write_context& ctxt, bool flag);
 void
 set_annotate(write_context& ctxt, bool flag);

+void
+set_write_architecture(write_context& ctxt, bool flag);
+
+void
+set_write_corpus_path(write_context& ctxt, bool flag);

 /// A convenience generic function to set common options (usually used
 /// by Libabigail tools) from a generic options carrying-object, into
@@ -69,6 +74,8 @@ set_common_options(write_context& ctxt, const OPTS& opts)
 {
   set_annotate(ctxt, opts.annotate);
   set_show_locs(ctxt, opts.show_locs);
+  set_write_architecture(ctxt, opts.write_architecture);
+  set_write_corpus_path(ctxt, opts.write_corpus_path);
 }

 void
@@ -105,7 +112,10 @@ write_corpus_to_archive(const corpus_sptr corp,
 			const bool annotate = false);

 bool
-write_corpus(write_context& ctxt, const corpus_sptr& corpus, unsigned indent);
+write_corpus(write_context&	ctxt,
+	     const corpus_sptr& corpus,
+	     unsigned		indent,
+	     bool		member_of_group = false);

 bool ABG_DEPRECATED
 write_corpus(const corpus_sptr& corpus, unsigned indent, write_context& ctxt);

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
344138e6b4 abidw: Consolidate setting options
When setting options meant to be used for the write_context, it is easy
to forget to change all relavant locations. In order to consolidate
that, introduce a set_opts function that sets various known options.

We benefit from earlier refactoring as now the write_context is passed
around to carry options for writers. Hence we can be sure, that if we
set up the context correctly (and do not use deprecated functionality),
the respective write_* function will see the options set in the context.

	* include/abg-writer.h (set_common_option): Declare new function.
	* tools/abidw.cc (load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml): Use the newly
	introduced set_common_option.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
6c07e82933 write_context: allow mutating the ostream used
Allowing the mutation of the ostream, allows heavy reuse of the
write_context as this is the distinction in most places where
write_context is used.

Hence, fixup various users of write_context and use common objects where
applicable.

	* include/abg-writer.h (set_ostream): Declare new function.
	* src/abg-writer.cc (write_context::m_ostream): Make this data
	member be a pointer rather than a reference.
	(write_context::{write_context, get_ostream): Adjust.  member.
	(write_context::set_ostream): Define new member function.
	(set_ostream): Define new free-form function.
	* tools/abidw.cc (load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml): Use the feature of
	mutating the ostream and reuse the write_context in most cases.

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
6aeed171c1 abg-writer: Refactor write_corpus_group API
Introduce a new call overload for write_corpus_group that follows the
parameter order context, object (i.e. corpus_group), indent.

Deprecate all other overloads that were part of the API and mostly
forward them to the new overload. That effort is made to ensure
write_context is always provided. write_context allows access to all
options that influence the output format.

	* include/abg-writer.h (write_corpus_group): Introduce new
	overload write_corpus_group(ctxt, corpus_group, indent) and
	deprecate all others.
	* src/abg-writer.cc (write_corpus_group): Likewise for the
	definitions and adjust.
	* tools/abidw.cc (load_kernel_corpus_group_and_write_abixml):
	Migrate to new API of write_corpus_group()

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
948f27480f abg-writer: Refactor write_corpus API
Introduce a new overload for write_corpus that follows the parameter
order context, object (i.e. corpus), indent.

Deprecate all other overloads that were part of the API and mostly
forward them to the new overload. That effort is made to ensure
write_context is always provided. write_context allows access to all
options that influence the output format.

	* include/abg-writer.h (write_corpus): Introduce new overload
	write_corpus(ctxt, corpus, indent) and deprecate all others.
	* src/abg-writer.cc (write_corpus): Likewise for the definitions
	and adjust.
	* tests/test-read-dwarf.cc (test_task::perform): Use the new
	write_corpus which requires a write_context.
	* tools/abidw.cc (load_corpus_and_write_abixml, ): Likewise.
	* tools/abilint.cc (main): Likewise. Also simplify logic around the
	locations as they now can be expressed with less code.

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
f5907c7e74 abg-writer: Refactor write_translation_unit API
Introduce a new overload for write_translation_unit that follows the
parameter order context, object (i.e. translation unit), indent.

Deprecate all other overloads that were part of the API and mostly
forward them to the new one. That effort is made to ensure write_context
is always provided. write_context allows access to all options that
influence the output format.

	* include/abg-writer.h (write_translation_unit): Declare a new
	overload write_translation_unit(ctxt, tu, indent) and deprecate
	all others.
	* src/abg-writer.cc (write_translation_unit): Likewise in the
	definitions.
	(write_corpus, dump, write_translation_unit): Adjust.
	* tools/abilint.cc (main): use new write_translation_unit() API

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
b0f123c18e Add deprecation facilities
Add the macro 'ABG_DEPRECATED' to mark APIs as to be removed in a next
major release. APIs marked with that flag are supposed to work as
before, but might come with downsides. E.g. they could perform worse or
provide only limited functionality. All deprecated functions shall come
with a hint to equivalent functionality within the non-deprecated part
of the API.

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

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
06494ba89a abg-writer: Simplify 'annotate' propagation
'annotate' is one of many flags that could potentially influence the
way, output is written. Remove the default parameter from
write_context's constructor and let users explicitely set that flag on
the context.

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

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-22 14:33:45 +02:00
Matthias Maennich
9c84181f99 Add .clang-format approximation
Add .clang-format definitions that are an approximation of the current
coding style. As I understand it, the current style is based on what GNU
Emacs implements for C++. Hence these rules might not be entirely
accurate, but a good-enough approximation to allow contributers to
follow the coding style more easily.

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

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

	* .clang-format: New File.

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-20 10:03:49 +02:00
Dodji Seketeli
f754d81116 Bug 24552 - abidiff fails comparing a corpus against a corpus group
In this problem report, the issue is that when comparing two corpus
groups, especially when looking up function/variable symbols, the
get_fun_symbol_map() and get_var_symbol_map() member functions used
are corpus::get_{fun,var}_symbol_map, rather than
corpus_group::get_{fun, var}_symbol_map.  Note that the type
corpus_group inherits from the type corpus.  That leads to unexpected
comparison results, especially for symbols.

This patch fixes this by making the corpus::get_{fun, var}_symbol_map
member function be virtual and by using it during the lookup of
function/variable symbols.  That way, the right symbol map gets used.

	* include/abg-corpus.h (corpus{_group}::get_{fun,
	var}_symbol_map): Make these member functions virtual.
	* src/abg-corpus.cc (corpus::lookup_{function, variable}_symbol):
	Use the virtual corpus::get_{fun, var}_symbol_map() member
	function to get the symbols of the current corpus or corpus_group.
	* tests/data/Makefile.am: Add the new test input material below to
	source distribution.
	* tests/data/test-abidiff/test-PR24552-report0.txt: New test input.
	* tests/data/test-abidiff/test-PR24552-v0.abi: Likewise.
	* tests/data/test-abidiff/test-PR24552-v1.abi: Likewise.
	* tests/test-abidiff.cc (main): Support comparing corpus groups.
	(specs): Add the new test inputs to the harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-16 18:10:08 +02:00
Dodji Seketeli
f15b1ea634 Bug 24560 - Assertion failure on an abixml with an anonymous type
When reading an abixml file, we should not try to re-use an anonymous
class, union or enum because by construction two anonymous unions of
the same (internal) name don't necessarily designate the same type.
We already do that in the ELF/DWARF reader so we need to update the
abixml reader too.

Fixed thus.

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-15 12:46:56 +02:00
Dodji Seketeli
1930f3caf7 Handle Linux kernel binaries with no __ksymtab section
Some Linux kernel binaries can have no __ksymtab section.  It's
possible that only have a __ksymtab_gpl section or no __ksymtab_gpl
either.  And apparently they can also have a __ksymtab* section full
of zeroes.

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-13 16:57:55 +02:00
Dodji Seketeli
d403118cd0 Fix logic of get_binary_load_address
The value of the of the pointer to program header returned by
gelf_getphdr is always the same, assuming the value of the last
parameter to gelf_getphdr stays the same.  What changes is what is
pointed to by that pointer.  So rather than storing the the program
header (to determine the lowest load address among several program
headers returned by gelf_getphdr) we need to store the load address
pointed to by the pointer to the program header.

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-10 14:10:25 +02:00
maennich@google.com
9402e26a8f Bug 24431 Treat __ksymtab as int32_t for v4.19+ kernels
Calculating the relocation for values in __ksymtab with GElf_Addr (i.e.
uint64_t), makes the calculation rely on overflows for negative offsets.
Address that by treating these as 32bit signed values for the v4.19+
__ksymtabs and calculate the offset with them. This also allows, similar
an earlier commit, to drop the distinction between 64bit and 32bit
kernels.

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

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-10 07:34:45 +02:00
maennich@google.com
a8bec92de2 Bug 24431 Read 32bit values when testing for the v4.19 symbol table format
Reading into uint64_t when reading the symbol table values drops the
sign and subsequently offset calculations will only be correct if either
the offset is positive or if the calculation overflows.

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

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

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

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-10 07:21:24 +02:00
maennich@google.com
2af6990560 dwarf-reader: templatize read_int_from_array_of_bytes
Making the return value type a template type allows for signed types to
be passed and successfully interpreted.

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

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-10 07:16:01 +02:00
maennich@google.com
89777e1f2c dwarf-reader: Fix comments for try_reading_first_ksymtab_entry_using_{pre_,}v4_19_format
Swap the descriptive comments for the two functions.

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

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-05-10 07:11:00 +02:00
Dodji Seketeli
2cf9a18e8c Better handle several anonymous types of the same kind
This is a follow-up patch for the commit:

   43d56de Handle several member anonymous types of the same kind

It allows support for severan anonymous types even when these are not
members of a class/unions.

The patch introduces the concept of a scoped name.  It's a qualified
name for a decl made of the name of the decl appended to the
*unqualified* name of its scope.  Unlike for qualified names, the
scoped name won't have a "__anonymous_*__" string in its name if its
directly containing scope is not anonymous; a qualified name might
still have that string in its name because the decl has a parent scope
(not necessarily its directly containing scope though) that is
anonymous.

The patch goes on to update the logic for comparison of decls that are
anonymous.  For a decl which direct scope is *NOT* anonymous, the
scoped name is what's used in the comparison.  Otherwise, only the
name of the decl is used.

The patch also updates how we detect changes in data members and
member types, in the comparison engine.  It now uses the names of the
data members, rather than their qualified name.  This is in the scope
of the current class/union anyway.  The improvement is that the fact
that the class/union itself is anonymous (even if its anonymous name
changes to another anonymous name) won't have any spurious impact on
the detection of name change of the members.

The patch considers the change of an anonymous decl name which
anonymous name changes to another anonymous name as being harmless.

The patch updates the logic of category propagation in the comparison
engine.  Although a public typedef to private underlying type needs to
stay public and thus not propagate the PRIVATE_TYPE_CATEGORY from its
child diff node to himself, it still needs to suppress the changes to
the private underlying diff node that were suppressed (because of the
private-ness), unless that typedef has local changes.

	* include/abg-ir.h (decl_base::get_scoped_name): Declare new
	member function.
	(scope_decl::get_num_anonymous_member_{classes, unions, enums}):
	Declare new virtual member functions.
	(class_decl::get_num_anonymous_member_{classes, unions, enums}):
	Adjust to make these virtual.  It's not necessary but I feel
	redundancy is a kind of self-documentation here.
	* src/abg-comp-filter.cc (has_harmless_name_change): Consider
	anonymous name changes as harmless.
	* src/abg-comparison.cc
	(class_or_union_diff::ensure_lookup_tables_populated): Consider
	the names of the members rather than their qualified names.
	(suppression_categorization_visitor::visit_end): Suppress the
	changes to the private underlying diff node that were suppressed
	because of the private-ness, unless that typedef has local
	changes.
	* src/abg-dwarf-reader.cc (build_enum_type)
	(add_or_update_class_type, add_or_update_union_type): Handle
	anonymous types in namespaces as well, not just in class/unions.
	* src/abg-ir.cc (decl_base::priv::scoped_name_): Define new data
	member.
	(decl_base::get_scoped_name): Define new member function.
	(equals): For the decl_base overload, use scoped name in the
	comparison, unless the decl belongs to an anonymous type.  For the
	class_or_union_diff, only consider scoped_name during comparison.
	Avoid name comparison between anonymous types.
	(scope_decl::get_num_anonymous_member_{classes, unions, enums}):
	Define new member functions.
	(types_have_similar_structure): Do not compare names between
	anonymous types.
	(qualified_name_setter::do_update): Update scoped names too.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-dwarf/test43-PR22913-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test46-rust-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test33-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test44-anonymous-data-member-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-09 15:19:05 +02:00
Dodji Seketeli
43d56de89b Handle several member anonymous types of the same kind
When there are several anonymous types (e.g, anonymous classes, unions
or enums) in a given class or union, libabigail's internals do
struggle.

An anonymous class, for instance, is named __anonymous_struct__.  When
there are more than one of these inside a given class, then we can't
name and look them up, because they all have the same name.

Incidentally, when add_or_update_class_type completes a class type
that was initially constructed before, it fails to determine that an
anonymous member type of that class was already present in that
context.  It thus wrongly duplicates anonymous structs/unions/enums in
there and that leads to spurious textual (abixml) representation
differences later, where duplicated anonymous member types would
appear intermittently, depending on the order in which the class was
built.

This patch addresses this general issue by naming anonymous member
types in a way that allows several of them to exist. That is, if there
are two anonymous structs in a class, they are going to be named
__anonymous_struct__ and __anonymous_struct__1.  We do follow a
similar scheme for anonymous unions and enums. This is handled by the
DWARF reader that builds the internal representation.

While looking at this issue, I also fixed a tangent bug; some DWARF
emitters wrongly *define* types in the scope of a
DW_TAG_subroutine_type or DW_TAG_array_type.  We handle that by
actually defining those types in the scope of that subroutine or
array.  But then it appears that if that scope itself a class and if
the type defined is an anonymous type, then putting that anonymous
type in the class scope might interfere with the *naming* of the
existing legit anonymous types of that scope.  I decided to put those
anonymous types in the containing namespace instead.  We'll see how
that goes in real time use.

The patch also updates lots of existing tests and adds a new one.

	* include/abg-ir.h
	(class_or_union::get_num_anonymous_member_{classes, unions,
	enums}): Declare new member functions.
	* src/abg-dwarf-reader.cc (get_internal_anonynous_die_base_name)
	(build_internal_anonymous_die_name)
	(get_internal_anonymous_die_name, is_anonymous_type_die): Define
	new static functions.
	(die_qualified_type_name): Use the new
	get_internal_anonymous_die_name.
	(get_scope_for_die): Fix this to put anonymous types that were
	wrongly emitted into the scope of DW_TAG_subroutine_type or
	DW_TAG_array_type by buggy DWARF emitters into the enclosing
	namespace, rather than into the enclosing class/union.
	(build_enum_type): Take the scope of the enum to have a chance to
	properly name potential anonymous enums.
	(lookup_class_typedef_or_enum_type_from_corpus): Take an anonymous
	member type index for when the DIE we are lookup up represents an
	anonymous type.  Support proper building of the internal anonymous
	name of the anonymous type we are lookup up.
	(add_or_update_class_type): Use the new
	get_internal_anonynous_die_base_name and
	build_internal_anonymous_die_name functions.  Support making sure
	that the anonymous member type we are adding to the class wasn't
	already there, especially for cases where we are updating a class
	type.
	(add_or_update_union_type): Use the new
	get_internal_anonynous_die_base_name and
	build_internal_anonymous_die_name functions.
	(build_ir_node_from_die): Adjust the use of build_enum_type to
	pass it the scope of the enum type we are building.
	* src/abg-ir.cc	(lookup_union_type): Add a new overload.
	(lookup_class_or_typedef_type): Use the new overload of
	lookup_union_type above to support looking up union types too.
	(class_or_union::get_num_anonymous_member_{classes, unions,
	enums}): Define new member functions.
	* src/abg-reporter-priv.cc (represent): Detect when anonymous
	types of anonymous data members have their internal names change,
	probably because anonymous member types were inserted in the scope.
	* tests/data/Makefile.am: Add the new test-anonymous-members-0.*
	test input files to the source distribution.
	* tests/data/test-annotate/test-anonymous-members-0.cc: New test
	input file.
	* tests/data/test-annotate/test-anonymous-members-0.o: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/test-annotate.cc (int_out_specs): Add the new test inputs
	to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-07 14:31:16 +02:00
Dodji Seketeli
eafa097433 Use canonical types hash maps for type IDs in abixml writer
This patch stores canonical types in the hash maps that are used in
the abixml writer to compute the type IDs.  This limits the
possibility that two types that are equivalent (especially when one is
a declaration-only class) end-up in the same abixml.

	* src/abg-writer.cc (write_context::{type_has_existing_id,
	get_id_for_type}): Save the canonical type of the type in the map,
	not the type itself.
	(write_context::{type_is_emitted}): Use the canonical type rather
	than the type itself.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 17:52:39 +02:00
Dodji Seketeli
04d61a726d Don't try to de-duplicate all anonymous struct DIEs
Trying to de-duplicate anonymous struct DIEs can lead to subtle
issues, because there can be two different naming typedefs designating
two anonymous structs that are equivalent, in the same translation
unit.  In that case, de-duplicating the two leaf anonymous structs
DIEs leads to non-resolvable conflict.

This patch avoids de-duplicating anonymous structs DIEs and rather
de-duplicates (naming) typedefs.

	* include/abg-fwd.h (is_typedef): Remove the overloads for
	type_base_sptr and decl_base_sptr.  Replace those with an overload
	for type_or_decl_base_sptr.
	* src/abg-ir.cc (is_typedef): Do the same for the definitions.
	* src/abg-dwarf-reader.cc (add_or_update_class_type)
	(add_or_update_union_type): Do not de-duplicate anonymous
	struct/union DIEs.
	(build_typedef_type): Try to de-duplicate typedefs DIEs.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 16:59:35 +02:00
Dodji Seketeli
451d34d1ad Canonicalize types non tied to any DWARF DIE
During DWARF reading, it can happen that some types are created that
are not tied to a given DIE.  This happens for instance when editing
the internal representation of types to better reflect the intent of
the code rather than the letter of the code; more precisely this
happens when a qualified array is edited to represent an array of
qualified elements, for instance.  In that case, the qualified element
type is created by the DWARF analyser.  And in the present incarnation
of the code, we forget to canonicalize that type.

The fact that that type is not canonicalized leads to cases where two
equivalent types can still be present in a translation unit in the
resulting abixml representation, without the abixml writer noticing
it.  That duplication can lead to unnecessary cycles in the type graph
where passes can either take one side or the other of the cycle; and
that leads to subtle heisen-changes in the emitted abixml representation.

This patch thus canonicalizes those newly created types.

	* src/abg-dwarf-reader.cc
	(read_context::extra_types_to_canonicalize_): Add new data member.
	(read_context::{initialize, clear_types_to_canonicalize}): Adjust.
	(read_context::extra_types_to_canonicalize): Create new accessor.
	(read_context::schedule_type_for_late_canonicalization): Add new
	overload for type_base_sptr.
	(read_context::perform_late_type_canonicalizing): Perform the
	canonicalization of the types created by the DWARF analyzer, but
	that are not tied to any DIE.
	(maybe_strip_qualification): Take a read_context&.  Schedule newly
	created types (during type edition) for late canonicalization.
	(build_ir_node_from_die): Adjust the call to
	maybe_strip_qualification to pass a read_context.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 16:28:42 +02:00
Mark Wielaard
fb6b2a5f4c Don't try to read a build_id as string in find_alt_debug_info_link.
The GCC8 address sanitizer found an issue in find_alt_debug_info_link.
It tried to convert a build-id byte sequence into a string. But the
build-id byte sequence is not a zero terminated sequence of chars.
So it could run off way past the section data.

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

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

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

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-18 18:21:01 +02:00
Mark Wielaard
1c358a5022 Fix an undefined behaviour in has_var_type_cv_qual_change
* src/abg-comp-filter.cc: (has_var_type_cv_qual_change):
	Initialize the ch_kind variable before using it.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-18 16:24:15 +02:00
Dodji Seketeli
39f02b6747 Add --enable-{asan,ubsan} configure options
Add options to enable building with -fsanitize=address or
-fsanitize=undefined.

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-18 15:46:34 +02:00
Dodji Seketeli
e6ec049520 abg-tools-utils.cc: Plug a leak in find_file_under_dir
We were forgetting to call fts_close on a file hierarchy returned by
fts_open.  Plugged thus.

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-18 14:44:30 +02:00