Commit Graph

67 Commits

Author SHA1 Message Date
Dodji Seketeli
610d87c29b Represent undefined corpus interfaces to analyze app compatibility
In the text below, the term interface means the "declaration of either
a function or a global variable".

To analyze the compatibility between an application and a dependent
library, one has essentially to analyze the interfaces of the
application that have undefined symbols (aka undefined interfaces from
the application) and see how they relate to the same interfaces coming
from the library but with symbols that are defined and exported from
the library (aka defined/exported interfaces from the library).

An interface that is undefined in the application and defined in the
library is an interface that the application consumes from the
library.

In other words an undefined interface from an application is an
interface that the application expects and an interface that is
exported by a library is an interface that the library provides.

If comparing the expected interface against the provided interface
yields a meaningful difference, then that might mean there is an
incompatibility between the application and the library on that
interface.

This patch uses this scheme to re-implement the weak mode of ABI
compatibility between an application and a library.

The patch adds the concept of undefined functions and variables to the
ABI corpus.  Then it teaches the DWARF reader how to construct the IR
for these undefined interfaces.  Then it revisits the weak mode of
operation of abicompat to make it compare the interfaces expected from
the application against the corresponding interfaces provided by
library.  The patch also teaches the weak mode abicompat how to detect
incompatibilities between the interfaces that plugin expects and the
interfaces provided by the application.

This patch makes the CTF front-end construct undefined interfaces.  A
subsequent patch is needed to construct undefined interfaces from the
BTF front-end however.

	* include/abg-corpus.h (corpus::{lookup_variable,
	get_undefined_functions, get_undefined_variables}): Declare new
	member functions.
	(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
	Make this return a boolean.
	* include/abg-fe-iface.h (fe_iface::options_type): Add a new
	load_undefined_interfaces enumerator.
	(fe_iface::add_fn_to_exported_or_undefined_decls): Rename
	maybe_add_fn_to_exported_decls into this.
	(fe_iface::add_var_to_exported_or_undefined_decls): Rename
	maybe_add_var_to_exported_decls into this.
	* src/abg-btf-reader.cc (reader::build_ir_node_from_btf_type):
	Adjust call to maybe_add_fn_to_exported_decls as
	add_fn_to_exported_or_undefined_decls.  Similarly, adjust call to
	maybe_add_var_to_exported_decls as
	add_var_to_exported_or_undefined_decls.
	* src/abg-corpus-priv.h (corpus::priv::undefined_{fns,vars}): Add
	new member variables.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
	Return a bool iff the decl was added to the set of exported decls.
	(corpus::{lookup_variable, get_undefined_functions,
	get_undefined_variables}): Define new member functions.
	(corpus::sort_{functions,variables}): Sort the undefined decls
	too.
	* (corpus::lookup_{function,variable}_symbol): Lookup the symbol
	also among undefined symbols, not just among defined symbols.
	* src/abg-ctf-reader.cc (reader::process_ctf_archive): Adjust call
	to maybe_add_fn_to_exported_decls as
	add_fn_to_exported_or_undefined_decls.  Similarly, adjust call to
	maybe_add_var_to_exported_decls as
	add_var_to_exported_or_undefined_decls. Also, sort functions &
	variables in the corpus.
	* src/abg-dwarf-reader.cc (die_name_and_linkage_name): Define new
	static function.
	(reader::fixup_functions_with_no_symbols): Adjust call to
	maybe_add_fn_to_exported_decls as
	add_fn_to_exported_or_undefined_decls.
	(reader::{is_decl_die_with_undefined_symbol,
	load_undefined_interfaces}): Define new member functions.
	(build_translation_unit_and_add_to_ir): Analyze DIEs of interfaces
	that have undefined symbols if we were asked to load undefined
	interfaces.
	(variable_is_suppressed): Add a boolean parameter to tell if the
	var is decl-only.  Use that decl-only flag to determine if the
	variable is suppressed.  A non-member decl-only variable won't be
	suppressed if we were asked to load undefined interfaces.
	(build_or_get_var_decl_if_not_suppressed): Add a boolean parameter
	to tell if the var is decl-only.
	(potential_member_fn_should_be_dropped): A potential non-virtual
	member function with no symbol is now dropped on the floor
	regardless of it has a mangled name or not.
	(build_var_decl): If the var has an undefined symbol, then set
	that symbol.
	(build_function_decl): If the function has an undefined symbol,
	then set that symbol.
	(build_ir_node_from_die): Add a var or function with undefined
	symbol to the set of undefined vars or functions of the current
	corpus.
	* src/abg-fe-iface.cc
	(fe_iface::add_fn_to_exported_or_undefined_decls): Renamed
	fe_iface::maybe_add_fn_to_exported_decls into this.  If the
	function has an undefined symbol then add the function to the set
	of undefined functions.
	(fe_iface::add_var_to_exported_or_undefined_decls): Renamed
	fe_iface::maybe_add_var_to_exported_decls into this.  If the
	variable has an undefined symbol then add the variable to the set
	of undefined variables.
	* src/abg-ir.cc (elf_symbol::is_variable): Undefined symbol with
	type STT_NOTYPE are actually for undefined variables.
	(maybe_adjust_canonical_type): It's here, after type
	canonicalization that a member function is added to either the set
	of defined & exported functions, or to the set of functions with
	undefined symbols.
	* src/abg-reader.cc (build_function_decl, build_class_decl)
	(build_union_decl, handle_var_decl): Adjust.
	* src/abg-symtab-reader.cc
	(symtab::{lookup_undefined_function_symbol,
	lookup_undefined_variable_symbol, function_symbol_is_undefined,
	variable_symbol_is_undefined,
	collect_undefined_fns_and_vars_linkage_names}): Define new member
	functions.
	(symtab::symtab): Initialize the new
	cached_undefined_symbol_names_ data member.
	* src/abg-symtab-reader.h
	(symtab::{lookup_undefined_function_symbol,
	lookup_undefined_variable_symbol, function_symbol_is_undefined,
	variable_symbol_is_undefined,
	collect_undefined_fns_and_vars_linkage_names}): Declare new member
	functions.
	(symtab::{undefined_variable_linkage_names_,
	cached_undefined_symbol_names_}): Define new data members.
	(symtab::load_): Consider undefined symbol of type STT_NOTYPE as
	being undefined global variables.  It's what I am seeing in ELF
	binaries.
	* src/abg-symtab-reader.h
	(symtab::{lookup_undefined_function_symbol,
	lookup_undefined_variable_symbol, function_symbol_is_undefined,
	variable_symbol_is_undefined}): Declare new member functions.
	(symtab::{undefined_function_linkage_names_,
	undefined_variable_linkage_names_}): Define new member variables.
	* src/abg-writer.cc (write_var_decl, write_function_decl): Emit a
	reference to a symbol only when the symbol is defined.
	* tools/abicompat.cc (report_function_changes)
	(report_variable_changes)
	(compare_expected_against_provided_functions)
	(compare_expected_against_provided_variables): Define new static
	functions.
	(perform_compat_check_in_weak_mode): Use the new static functions
	above. Compare interfaces expected by the application corpus
	against interfaces provided by the library.  Report the changes.
	Do that in the reverse direction as well.
	(read_corpus): Instruct the corpus reader to load the set of
	undefined interfaces too.
	* tests/data/test-abicompat/test6-var-changed-app: Remove file.
	* tests/data/test-abicompat/test6-var-changed-app.cc: Likewise.
	* tests/data/test-abicompat/libtest6-undefined-var.so: Add new
	binary input file.
	* tests/data/test-abicompat/test6-undefined-var.cc: Add sourcefile
	for the binary input file above.
	* tests/data/test-abicompat/test6-var-changed-report-2.txt: New
	reference output file.
	* tests/data/Makefile.am: Update the list of distributed files
	accordingly.
	* tests/data/test-abicompat/libtest5-fn-changed-libapp-v0.so:
	Adjust.
	* tests/data/test-abicompat/libtest5-fn-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest6-var-changed-libapp-v0.so:
	Likewise.
	* tests/data/test-abicompat/libtest6-var-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest7-fn-changed-libapp-v0.so:
	Likewise.
	* tests/data/test-abicompat/libtest7-fn-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so:
	Likewise.
	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so:
	Likewise.
	* tests/data/test-abicompat/libtest9-fn-changed-v0.so: Likewise.
	* tests/data/test-abicompat/libtest9-fn-changed-v1.so: Likewise.
	* tests/data/test-abicompat/test5-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test6-var-changed-libapp-v0.cc:
	Likewise.
	* tests/data/test-abicompat/test6-var-changed-libapp-v1.cc:
	Likewise.
	* tests/data/test-abicompat/test6-var-changed-report-0.txt:
	Likewise.
	* tests/data/test-abicompat/test6-var-changed-report-1.txt:
	Likewise.
	* tests/data/test-abicompat/test7-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test7-fn-changed-report-1.txt:
	Likewise.
	* tests/data/test-abicompat/test7-fn-changed-report-2.txt:
	Likewise.
	* tests/data/test-abicompat/test8-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v1.c:
	Likewise.
	* tests/data/test-abicompat/test9-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-app.cc: Likewise.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test1.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.ab: Likewise.i
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/test0-from-fc20-to-fc23-dbus-glib-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/test2-dbus-glib-0.100.2-2.fc20--dbus-glib-0.106-1.fc23-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/test3-dbus-glib-0.100.2-2.fc20.i686--dbus-glib-0.106-1.fc23.i686-report-0.txt:
	Likewise.
	* tests/data/test-fedabipkgdiff/vte291-0.39.1-1.fc22.x86_64--vte291-0.39.90-1.fc22.x86_64-report-0.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/PR26261/PR26261-exe.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.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/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/test-abicompat.cc (in_out_specs): Adjust.
	* tests/test-read-ctf.cc (test_task_ctf::perform): Do not load
	undefined interfaces, by default.
	* tests/test-symtab.cc (Symtab::SimpleSymtabs)
	(Symtab::SymtabWithWhitelist, Symtab::AliasedFunctionSymbols):
	Adjust the expected undefined variable symbols counts.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-14 16:26:54 +01:00
Dodji Seketeli
4b39942467 ir,corpus,comparison: Const-iffy the access to corpus interfaces
In preparation to subsequent patches that perform manipulations of the
corpus interfaces, it appears that we need to add const access to
those corpus interfaces.

	* include/abg-comparison.h (typedef string_function_ptr_map): Make
	this typedef use a const function_decl*, not just a
	function_decl*.
	(typedef string_var_ptr_map): Make this typedef use a const
	var_decl*, not just a var_decl*.
	* include/abg-corpus.h (typedef corpus::functions): Make this
	typedef be a vector<const function_decl*>, not just a
	vector<function_decl*>.
	(corpus::exported_decls_builder::fn_id_maps_to_several_fns):
	Adjust declaration to const function_decl*.
	* include/abg-fwd.h (typedef istring_var_decl_ptr_map_type)
	(typedef istring_function_decl_ptr_map_type): Move these typedefs to
	abg-ir.h.
	(get_function_id_or_pretty_representation): Use const function_decl*.
	* include/abg-ir.h (typedef istring_var_decl_ptr_map_type)
	(typedef istring_function_decl_ptr_map_type): Move these here from
	abg-fwd.h.  Also make these use const var_decl* and const.
	function_decl.
	* src/abg-comparison-priv.h (sort_string_function_ptr_map)
	(sort_string_var_ptr_map): Use vector<const function_decl*> and
	vector<const var_decl*> rather than their non-const variants.
	* src/abg-comparison.cc (sort_string_function_ptr_map)
	(sort_string_var_ptr_map): Likewise.
	(corpus_diff::priv::{ensure_lookup_tables_populated,
	apply_supprs_to_added_removed_fns_vars_unreachable_types}):
	Adjust.
	* src/abg-corpus-priv.h (corpus::priv::{fns,vars}): Make these
	data members use vector<const function_decl*> and vector<const
	var_decl*> types.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::fn_id_maps_to_several_fns)
	(corpus::maybe_drop_some_exported_decls): Adjust.
	(corpus_group::priv::{fns,vars}): Make these data members use
	vector<const function_decl*> and vector<const var_decl*> types.
	* src/abg-default-reporter.cc (default_reporter::report): In the
	overload for const corpus_diff&, adjust.
	* src/abg-ir.cc (get_function_id_or_pretty_representation):
	Adjust.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
	overload for const corpus_diff&, adjust.
	* tools/abicompat.cc (perform_compat_check_in_normal_mode):
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-03-01 14:19:05 +01:00
Dodji Seketeli
3f2afc7a71 dwarf-reader,corpus: Use interned string to lookup corpus interfaces by ID.
This patch speeds up the lookup of a function or variable using the
function/variable ID.  This patch is in preparation of many more
function lookup made during ABIXML emitting by patches coming up in
the future.

	* include/abg-corpus.h (corpus::lookup_functions): Take an
	interned_string instead of an std::string.  Add an overload for
	const char* string too, for debugging purposes.
	* src/abg-corpus-priv.h (istr_fn_ptr_set_map_type)
	(istr_var_ptr_map_type): Define new typedefs.
	(corpus::exported_decls_builder::priv::{id_fns_map_,
	id_var_map_}): Use the new istr_fn_ptr_set_map_type and
	istr_var_ptr_map_type types for these data members.
	(corpus::exported_decls_builder::priv::{id_fns_map, id_var_map,
	add_fn_to_id_fns_map, var_id_is_in_id_var_map, add_var_to_map,
	add_var_to_exported}): Adjust.
	(corpus::priv::lookup_functions): Declare new member function.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_var_to_exported_vars): Adjust.
	(corpus::priv::lookup_functions): Define new member function.  The
	code here comes from the code that was in
	corpus::lookup_functions.  This is a factorization of
	corpus::lookup_functions.
	(corpus::lookup_functions): Take an interned_string instead of the
	previous.  Factorize the code that was here into the new
	corpus::priv::lookup_functions.
	* src/abg-dwarf-reader.cc
	(reader::symbol_already_belongs_to_a_function): Adjust the call to
	corpus::lookup_functions to use an interned_string.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2024-02-12 17:49:25 +01:00
Dodji Seketeli
a30a3146b5 corpus,tools-utils: Support loading a corpus, its deps & other binaries
In preparation of implementing the support for "Handling split
libraries", this patch implements the functions
tools_utils::{get_comma_separated_args_of_option,
find_file_under_dirs, add_binaries_into_corpus_group,
add_dependencies_into_corpus_group,
stick_corpus_and_binaries_into_corpus_group,
stick_corpus_and_dependencies_into_corpus_group, get_dependencies}.

Given an ABI corpus, these functions enable adding arbitrary binaries
and dependencies found in a set of directories to form a corpus group.

	* include/abg-corpus.h (corpus_group::has_corpus): Declare new
	member function.
	* include/abg-tools-utils.h (get_comma_separated_args_of_option)
	(find_file_under_dirs, get_dependencies)
	(add_binaries_into_corpus_group)
	(add_dependencies_into_corpus_group)
	(stick_corpus_and_binaries_into_corpus_group)
	(stick_corpus_and_dependencies_into_corpus_group): Declare new
	functions.
	* src/abg-corpus.cc (corpus_group::priv::corpora_path): Add new
	data member.
	(corpus_group::add_corpus):  Do not add a corpus that was already
	added to the group.  Update the set of paths of added corpora so
	that we can detect if a corpus has already been added.
	* src/abg-tools-utils.cc (find_file_under_dir): If the file found
	is a symbolic link, return it.  Otherwise if the symbolic link is
	not the file we were looking for, then skip it, rather than
	following it, in case it's a directory.
	(get_comma_separated_args_of_option, find_file_under_dirs)
	(get_dependencies, add_binaries_into_corpus_group)
	(add_dependencies_into_corpus_group)
	(stick_corpus_and_binaries_into_corpus_group)
	(stick_corpus_and_dependencies_into_corpus_group): New functions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-07-07 13:34:39 +02:00
Dodji Seketeli
b987db9bcb Bug 29912 - Better support an ELF symbol alias that designates several functions
When an ELF symbol alias designates two different functions,
Libabigail can be confused as to which function to consider.

This confusion indirectly leads to showing spurious changes in the
return type of some functions when an ELF symbol designates more than
one function.

In other words, when an ELF symbol designates two (or more) functions,
the comparison engine needs a way to tell the two functions apart.  It
needs an other way to identify the functions.

This patch fixes the confusion by using the pretty representation of
the functions in those cases.

Please note that to replicate the issue reported in this bug, here is
the command I used:

    $ fedabipkgdiff --debug --self-compare -a --from fc37 smesh

	* include/abg-corpus.h (corpus::lookup_functions): Return a set of
	functions rather than a vector of functions where a function can
	be present more than once.  This allows to determine if a symbol
	designates more than one function.
	(corpus::exported_decls_builder::priv_): Make this public so that
	some outside code can access it.
	(corpus::exported_decls_builder::fn_id_maps_to_several_fns):
	Declare new function.
	(corpus::exported_decls_builder::maybe_add_fn_to_exported_fns):
	Remove useless const here.
	* include/abg-fwd.h (get_function_id_or_pretty_representation):
	Declare new function.
	* include/abg-ir.h
	(elf_symbol::get_alias_with_default_symbol_version): Declare new
	member function.
	* src/abg-comparison.cc
	(corpus_diff::priv::ensure_lookup_tables_populated): Use the new
	get_function_id_or_pretty_representation rather than
	function_decl::get_id() to identify a function.
	* src/abg-corpus-priv.h (str_fn_ptr_set_map_type): Define this new
	typedef of unordered_map<string, std::unordered_set<function_decl*> >.
	(corpus::exported_decls_builder::priv::id_fns_map_): Change the
	type of this to the new str_fn_ptr_set_map_type.
	(corpus::exported_decls_builder::priv::{id_fns_map, fn_id_is_in_id_fns_map,
	fn_is_in_fns, fn_is_in_id_fns_map}): Adjust to using a set of
	functions rather than a vector.
	(corpus::exported_decls_builder::fn_is_in_fns_by_repr): Define new
	static function.
	(corpus::exported_decls_builder::add_fn_to_exported): Remove
	useless const.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::fn_id_maps_to_several_fns):
	Define new function.
	(corpus::exported_decls_builder::maybe_add_fn_to_exported_fns):
	Remove useless const.
	(corpus::lookup_functions): Return a set of functions rather than
	a vector of functions where a function can be present more than
	once.  This allows to determine if a symbol designates more than
	one function.
	* src/abg-dwarf-reader.cc
	(reader::symbol_already_belongs_to_a_function): Adjust.
	* src/abg-fe-iface.cc (fe_iface::maybe_add_fn_to_exported_decls):
	Adjust.
	* src/abg-ir.cc (get_function_id_or_pretty_representation): Define
	new function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-03-20 15:16:57 +01:00
Dodji Seketeli
b5ab4d2009 abidiff: Add extensive logging
While looking at something else I felt the need for having
"abidiff --verbose" emit more timing information.  I have thus added
a lot more logging around.

	* include/abg-comparison.h ({diff, corpus_diff,
	diff_context}::do_log): Declare member functions.
	* include/abg-corpus.h (corpus::do_log): Likewise.
	* src/abg-comparison-priv.h (diff_context::priv::do_log_): Add new
	data member.
	(diff_context::priv::priv): Initialize the new data member.
	* src/abg-comparison.cc ({diff, corpus_diff,
	diff_context}::do_log): Define member functions.
	(diff_context::maybe_apply_filters): Add timing logs to applying
	filters and propagating categories.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Add
	timing logs to applying and propagating filters to changed
	functions, variables, unreachable & leaf type changes,
	suppressions application.
	* src/abg-corpus-priv.h (corpus::priv::do_log): Add new data
	member.
	(corpus::priv::priv): Initialize it.
	* src/abg-corpus.cc (corpus::do_log): Define member functions.
	* src/abg-reader.cc (reader::do_log): Likewise.
	(reader::read_corpus): Add timing log around the invocation of
	perform_late_type_canonicalizing.
	* tools/abidiff.cc (set_diff_context_from_opts): Set logging.
	(main): Add timing logging for diff computing, changes analysis &
	report generation.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-03-02 18:31:43 +01:00
Dodji Seketeli
12641b1130 Add support for BTF
This adds support for the BTF debug information format.  It provides a
new BTF front-end which can be instantiated by the function
tools::create_best_elf_based_reader().

For now, the BTF front-end supports the basic types (integers,
pointers, qualified types, typedefs, struct and unions and function
pointers) for functions and variables as emitted for the C language by
GCC.  It seems to be able to support the BTF debug information emitted
for the vmlinux kernel by the pahole tool as well.

When configured with the --enable-btf option, the WITH_BTF
pre-processor macro is defined, enabling the BTF support.  That option
is turned on by default if the /usr/include/bpf/btf.h header is found
on the system.  To disable this, one can use the --disable-btf option.

The abidw and abidiff programs have been adapted to use the BTF
front-end when provided with the '--btf' option, or if BTF debug
information is the only one present in the binary.

	* configure.ac: If the header /usr/include/bpf/btf.h exists, then
	define the WITH_BTF pre-processor macro, unless --disable-btf was
	provided.
	* doc/manuals/abidiff.rst: Document the new --btf option.
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/kmidiff.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-btf-reader.h: New header file.  Contains the
	declaration of the new btf::reader class.
	* src/abg-btf-reader.cc: New source file.  Contains the
	definitions of the new btf::reader class.
	* include/Makefile.am: Add the new include/abg-btf-reader.h header
	file to source distribution.
	* include/abg-corpus.h (enum origin): Add a new BTF_ORIGIN
	enumerator.
	* include/abg-tools-utils.h (file_has_btf_debug_info): Declare new
	function.
	* src/abg-tools-utils.cc (file_has_btf_debug_info): Define new
	function.
	(create_best_elf_based_reader): Adapt to support BTF input.  If
	the user requested the BTF front-end, instantiate it.  Otherwise,
	if the input file has only BTF debug info, instantiate the BTF
	front end.
	* include/abg-elf-reader.h (elf::reader::find_btf_section):
	Declare new member function.
	(elf::reader::{function, variable}_symbol_is_exported): Add new
	overloads.
	* src/abg-elf-reader.cc (reader::priv::btf_section): New data
	member.
	(reader::find_btf_section): Define new member function.
	* src/Makefile.am: Add the new abg-ctf-reader.cc file to source
	distribution.
	* tools/abidw.cc (options::use_btf): New data member.
	(display_usage): Add a help string for the new --btf option.
	(parse_command_line): Support the new --btf option.
	(load_corpus_and_write_abixml):  If the user asked to use the btf
	front-end then use that one.
	* tools/abidiff.cc (options::use_btf): New data member.
	(options::options): Initialize it.
	(display_usage):: Add a help string to the new --btf options.
	(parse_command_line): Support the new --btf options.
	(main): If the user asked to use the btf front-end, then use that
	one.
	* tools/abidw.cc (options::use_btf): New data member.
	(options::options): Initialize it.
	(parse_command_line): Add a help string to the new --btf options.
	(load_corpus_and_write_abixml): If the user asked to use the btf
	front-end, then use that one.
	* tools/kmidiff.cc (options::use_btf): New data member.
	(options::options): Initialize it.
	(display_usage): Add a help string to the new --btf options.
	(parse_command_line): Add a help string to the new --btf options.
	(main): If the user asked to use the btf front-end, then use that
	one.
	* tools/abipkgdiff.cc (options::use_btf): New data member.
	(options::options): Initialize it.
	(display_usage): Add a help string to the new --btf options.
	(parse_command_line): Add a help string to the new --btf options.
	(compare, compare_to_self)
	(compare_prepared_linux_kernel_packages): If the user asked to use
	the btf front-end, then use that one.
	* tests/data/test-read-btf/test{0,1}.o: New binary test input
	file.
	* tests/data/test-read-btf/test{0,1}.c: Source code of the binary
	input file above.
	* tests/data/test-read-btf/test{0,1}.o.abi: Reference ABIXML
	output.
	* tests/data/test-abidiff-exit/btf/test0-report-{1,2}.txt: New
	test reference output.
	* tests/data/test-abidiff-exit/btf/test0-v{0,1}.o: New binary test
	input.
	* tests/data/test-abidiff-exit/btf/test0-v{0,1}.c: The source
	files of the binary inputs above.
	* tests/test-read-btf.cc: New test file to run the btf/abixml
	tests.
	* tests/Makefile.am: Add the new test files to the source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-01-06 21:05:53 +01:00
Dodji Seketeli
64e7901956 Update copyright year for 2023
Update the copyright years for 2023, using the script update-copyright.sh.

	* update-copyright.sh: Update the copyright years in this script.
	* include/abg-comp-filter.h: Update copyright year for 2023.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-ctf-reader.h: Likewise.
	* include/abg-cxx-compat.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-elf-based-reader.h: Likewise.
	* include/abg-elf-reader.h: Likewise.
	* include/abg-fe-iface.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-regex.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-ctf-reader.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-elf-based-reader.cc: Likewise.
	* src/abg-elf-helpers.cc: Likewise.
	* src/abg-elf-helpers.h: Likewise.
	* src/abg-elf-reader.cc: Likewise.
	* src/abg-fe-iface.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-regex.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-symtab-reader.cc: Likewise.
	* src/abg-symtab-reader.h: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-cxx-compat.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-dot.cc: Likewise.
	* tests/test-elf-helpers.cc: Likewise.
	* tests/test-ini.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-kmi-whitelist.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-ctf.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-svg.cc: Likewise.
	* tests/test-symtab-reader.cc: Likewise.
	* tests/test-symtab.cc: Likewise.
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/kmidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-01-01 18:19:30 +01:00
Dodji Seketeli
7bd6983052 Make Front Ends first class citizens
This patch is a reorganization of the code to better support the need
for having several different front-ends.

In the libabigail pipeline of operation, a front-end is the part of
the pipeline that analyses the input file.  For instance, to analyse
an ELF file, there is going to be one front-end.  To analyse an ABIXML
file, there is going to be another front-end.

The middle-end is the part of the pipeline that interacts with the
internal representation of ABIs.  The middle-end knows how to analyse,
compare ABI corpora provide an internal representation of the
comparison result and analyse it as well.

The back-end would be the part of the front-end that knows how to
serialize internal representations of ABIs and ABI comparison results.

One could thus imagine a front-end that understands the DWARF debug
info format embedded in an ELF file.  Another front-end would be
dedicated to the CTF debug info format, and so on.

Front-ends can share capabilities.  For instance, DWARF and CTF
front-ends are ELF based front end.  As such, they share capabilities
to understand the ELF format.  They don't share much with the ABIXML
front-end, however, as it's based on XML, which has almost nothing in
common with ELF.

To support this organization of concepts, this patch introduces a new
hierarchy of types in the form of C++ classes.

All front-ends implements the "Front End Interface".  As such, they
all inherit the abigail::fe_iface class.

That class provides properties and behaviours that are shared by all
front-ends that libabigail supports today.  Namely, that class
provides access to some of the options that are relevant to operating
the front-end, to the ABI corpus or corpus group being constructed and
to the suppression specifications that are considered.  It also
provides an abstract interface to perform the actual loading of the
ABI corpus.  That abstract interface has to be implemented by every
single concrete front-end that is provided in libabigail.

Then, there is the "ELF Reader" front-end.  Its class name is
abigail:🧝:reader.  It inherits the abigail::fe_iface class and
implements the fe_iface::load_corpus() so that the ELF properties of
the ELF file be loaded and exposed in the ABI corpus as returned by
the fe_iface::corpus() accessor.  This ELF reader front-end also
provides lots of capabilities that are specific to accessing ELF
content.

Then, there is a common base class for ELF-based front-ends to come,
named abigail::elf_based_reader, which inherits the abigail:🧝:reader
class.  The purpose of this base class is to provide common properties
and behaviours that are necessary to implement things like a DWARF or
a CTF front-end, or any other front-end to support an ELF-based debug
info format.

Then, there is a CTF front-end which class is named
abigail::ctf::reader.  It inherits the abigail::elf_based_reader class
and implements the fe_iface::load_corpus() interface to load and
analyse the CTF-specific properties of the ELF file.  To do this,
abigail::ctf::reader::load_corpus() re-uses the abigail:🧝:load_corpus() member
function to load the generic ELF parts of the ABI corpus.  This reader
then constructs the internal representation of the ABI corpus and
passes it to the middle-end for further analysis.

Then, there is a DWARF front-end which class is named
abigail::dwarf::reader.  It inherits the abigail::elf_based_reader
class and implements the fe_iface::load_corpus() interface to load and
analyse the DWARF-specific properties of the ELF file.  To do this,
abigail::dwarf::reader re-uses the abigail:🧝:load_corpus() member
function to load the generic ELF parts of the ABI corpus, just like
what the CTF front-end does.  And then, just like the CTF front-end,
this reader then constructs the internal representation of the ABI
corpus and passes it to the middle-end for further analysis.

Lastly, there is an ABIXML front-end which class is named
abigail::abixml::reader.  It inherits the abigail::fe_iface class
directly.  Note that unlike the two previous front-ends, this one
doesn't inherit the elf_based_reader base class, for reasons that
should be obvious to the astute reader by now.  So, this front-end
implements the abigail::fe_iface::load_corpus() abstract interface to
load the properties for the ABI corpus represented in the ABIXML
format, construct the internal representation and pass it to the
middle-end for further analysis.

The code of the tools got adapted to use these front-ends.

The support of CTF is still guarded by #ifdef WITH_CTF pre-processor
macros, but the one cool side effect is that the amount of guarded
code is reduced.  Basically, it's only the creation of the CTF
front-end that is guarded.  After its creation, what is returned is an
instance of abigail::elf_based_reader::reader, exactly like what is
returned by the creation of a DWARF front-end.  Thus, the rest of the
code is exactly the same, regardless of the kind of front-end.  I
believe this results in a more elegant and maintainable code.

As a proof-of-concept, this patch also provides the
create_best_elf_based_reader function.  This function analyses the ELF
file and depending on the kind of debug info it provides, returns the
right front-end for it.  Maybe at some point, all the #ifdef WITH_CTF
guard pre-processing macros will be constrained in a single function
like this one that will take the decision of instantiating the right
front-end.  The rest of the code will be as generic as it gets.

The patch adjusts the reference abixml files produced by the CTF
front-end because it now emits the <elf-needed> XML element which was
not emitted before.  This is done because the CTF front-end inherits
the elf-reader which reads the "elf-needed" property from the binary,
without explicit intervention from the CTF front-end.

The patch passes 'make distcheck' on all the supported platforms.

	* include/abg-fwd.h (build_internal_underlying_enum_type_name):
	Move this here from src/abg-dwarf-reader.cc.
	* include/abg-elf-reader-common.h: Delete this file.  Its content
	is going to be put in the new include/abg-elf-reader.h.
	* src/abg-elf-reader-common.cc: Likewise.
	* include/abg-{elf-based-reader, elf-reader, fe-iface}.h: Add new
	files.
	* src/abg-fe-iface.cc: Likewise.
	* include/Makefile.am: Add the new file abg-fe-iface.h,
	abg-elf-based-reader.h and abg-elf-reader.h to source distribution
	and remove include/abg-elf-reader-common.h from source
	distribution.
	* src/abg-ir.cc (build_internal_underlying_enum_type_name): Move
	this here from abg-dwarf-reader.cc so that it can be used by other
	readers.
	* include/abg-reader.h (abigail::abixml::reader): Rename the
	namespace abigail::xml_reader into this one.
	(read_context, create_native_xml_read_context)
	(read_context_get_path, read_corpus_from_native_xml)
	(read_corpus_from_native_xml_file)
	(read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file): Remove.
	(read_translation_unit_from_file)
	(read_translation_unit_from_buffer)
	(read_translation_unit_from_istream)
	(read_translation_unit)
	(consider_types_not_reachable_from_public_interfaces)
	(get_types_from_type_id, get_artifact_used_by_relation_map)
	(load_canonical_type_ids): Take an fe_iface&, not a read_context.
	(create_reader): Declare new function that returns a
	fe_iface_sptr.
	(read_corpus_from_abixml, read_corpus_from_abixml_file)
	(read_corpus_group_from_abixml)
	(read_corpus_group_from_abixml_file): Declare new functions.
	* src/abg-reader.cc (namespace abixml): Rename the
	xml_reader namespace into this.
	(abixml::reader_sptr): New typedef.
	(abixml::reader): Rename read_context into this.  Make it
	inherit the fe_iface interface.
	(abixml::reader::{m_path, m_env, m_corpus, m_corpus_group,
	m_exported_decls_builder, m_supprs}): Remove these data members
	that are now part of the fe_iface parent type.
	(abixml::reader::{set_environment, get_corpus, set_corpus,
	set_corpus_group, maybe_add_fn_to_exported_decls,
	maybe_add_var_to_exported_decls,
	maybe_check_abixml_canonical_type_stability,
	suppression_matches_function_sym_name,
	suppression_matches_variable_name,
	suppression_matches_variable_sym_name}): Remove.
	(read_corpus_from_input): Remove.  Actually the code of this went
	into abixml::reader::read_context().
	(abixml::reader::get_libxml_reader): Rename the get_reader
	member function into this.
	(abixml::add_reader_suppressions): Rename
	add_read_context_suppressions into this.
	(abixml::reader::read_corpus): Implement this virtual
	member function if the fe_iface parent interface.
	(maybe_set_naming_typedef, advance_cursor)
	(handle_version_attribute, walk_xml_node_to_map_type_ids)
	(read_elf_needed_from_input, read_symbol_db_from_input)
	(get_or_read_and_add_translation_unit, build_needed)
	(read_elf_needed_from_input, add_read_context_suppressions)
	(maybe_set_artificial_location, maybe_set_naming_typedef)
	(build_namespace_decl, build_elf_symbol)
	(build_elf_symbol_from_reference, build_elf_symbol_db)
	(build_function_parameter, build_function_decl)
	(build_function_decl_if_not_suppressed, function_is_suppressed)
	(type_is_suppressed, build_var_decl_if_not_suppressed)
	(variable_is_suppressed, variable_is_suppressed, build_var_decl)
	(build_type_decl, build_qualified_type_decl)
	(build_pointer_type_def, build_reference_type_def)
	(build_function_type, build_subrange_type, build_array_type_def)
	(build_enum_type_decl_if_not_suppressed, build_enum_type_decl)
	(build_typedef_decl, build_class_decl_if_not_suppressed)
	(build_union_decl_if_not_suppressed, build_class_decl)
	(build_union_decl, build_function_tdecl, build_class_tdecl)
	(build_type_tparameter, build_type_composition)
	(build_non_type_tparameter, build_non_type_tparameter)
	(build_template_tparameter, build_template_parameter, build_type)
	(handle_type_decl, handle_namespace_decl)
	(handle_qualified_type_decl, handle_pointer_type_def)
	(handle_reference_type_def, handle_function_type)
	(handle_array_type_def, handle_enum_type_decl)
	(handle_typedef_decl, handle_var_decl, handle_function_decl)
	(handle_class_decl, handle_union_decl, handle_function_tdecl)
	(read_translation_unit_from_istream): Take or use an
	abixml::reader rather than a read_context.
	(read_translation_unit, read_translation_unit_from_input)
	(consider_types_not_reachable_from_public_interfaces)
	(get_types_from_type_id, get_artifact_used_by_relation_map)
	(read_corpus_group_from_input, read_translation_unit)
	(handle_element_node, read_location, read_artificial_location)
	(load_canonical_type_ids) : Take an fe_iface&, not a read_context.
	(create_abixml_reader): Rename create_native_xml_read_context
	into this.  Make it return a fe_iface_sptr.
	(read_corpus_from_abixml): Rename read_corpus_from_abixml into
	this.
	(read_corpus_from_abixml_file): Rename
	read_corpus_from_native_xml_file into this.
	(read_context_get_path): Remove.
	* include/abg-tools-utils.h
	(abigail::tools_utils::{file_has_dwarf_debug_info,
	file_has_ctf_debug_info}): Declare new functions.
	(create_best_elf_based_reader): Declare new function.
	* include/abg-corpus.h (corpus::add): Pass the translation unit by
	reference.
	(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
	Take a const parameter.
	* src/abg-corpus-priv.h
	(corpus::exported_decls_builder::priv::add_{fn,var}_to_exported):
	Take a const parameter and adjust.
	* src/abg-corpus.cc
	(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
	Take a const parameter.
	(corpus::add): Take a reference to translation_unit_sptr.
	* include/abg-suppression.h (abigail::fe_iface): Forward-declare
	this.
	(abigail::{suppression_sptr, suppressions_type}): Declare these
	types here.
	(abigail::suppr::{suppression_can_match,
	suppression_matches_function_name,
	suppression_matches_function_sym_name,
	suppression_matches_variable_name,
	suppression_matches_variable_sym_name,
	suppression_matches_type_name_or_location,
	is_elf_symbol_suppressed, is_elf_symbol_suppressed,
	is_function_suppressed, is_variable_suppressed,
	is_type_suppressed}): Declare these functions here.
	* src/abg-suppression-priv.h (function_is_suppressed)
	(variable_is_suppressed, type_is_suppressed)
	(is_elf_symbol_suppressed): Remove these template functions.
	* src/abg-suppression.cc (suppression_matches_function_name)
	(suppression_matches_function_sym_name): Remove.
	(variable_is_suppressed, suppression_can_match)
	(suppression_matches_function_name)
	(suppression_matches_function_sym_name)
	(suppression_matches_variable_name)
	(suppression_matches_variable_sym_name)
	(suppression_matches_type_name_or_location)
	(is_elf_symbol_suppressed, is_elf_symbol_suppressed)
	(is_function_suppressed, is_variable_suppressed)
	(is_type_suppressed): New functions.
	* include/abg-ctf-reader.h (abigail::ctf::{read_context,
	create_read_context, read_corpus,
	read_and_add_corpus_to_group_from_elf,
	set_read_context_corpus_group, reset_read_context, dic_type_key}):
	Remove.
	(ctf::{create_reader, reset_reader}): Declare new
	functions.
	* src/abg-ctf-reader.cc (read_context): Remove.
	(process_ctf_typedef, process_ctf_base_type)
	(build_ir_node_for_variadic_parameter_type)
	(process_ctf_function_type, process_ctf_sou_members)
	(process_ctf_forward_type, process_ctf_struct_type)
	(process_ctf_union_type, process_ctf_array_type)
	(process_ctf_qualified_type, process_ctf_pointer_type)
	(process_ctf_enum_type, fill_ctf_section)
	(lookup_symbol_in_ctf_archive, dic_type_key): Forward-declare
	these static functions.
	(ctf::reader): New class that is the abstraction
	of the CTF reader.  It extends the abigail::elf_based_reader
	class.  This is a renaming of the
	abigail::ctf::read_context class.
	(ctf::reader::{elf_handler, elf_fd,
	elf_handler_dbg, elf_fd_dbg, symtab, debug_info_root_paths_,
	debug_info_root_paths_}): Remove these data members as they are
	now properties of the abigail::elf_reader class, which is a parent
	class of this abigail::ctf::reader class.
	(ctf::reader::{exported_decls_builder,
	maybe_add_fn_to_exported_decls, current_corpus_group,
	has_corpus_group, main_corpus_from_current_group,
	current_corpus_is_main_corpus_from_current_group,
	should_reuse_type_from_corpus_group}): Remove these accessors
	that can now be used from the parent classes abigail::{elf_reader,
	elf_based_reader}.
	(ctf::reader::reader): This now delegates to the constructor of
	elf_based_reader.  It doesn't pass any argument to initialize()
	anymore.
	(ctf::reader::initialize): Add an overload with no
	parameter.  In the other overload, do not take a pointer to an
	environment as no new environment can be passed to the instance of
	reader that is being reset.  Adjust the code of the initializer to
	reflect all the data members that got removed.
	(ctf::{env, find_ctfa_file, slurp_elf_info,
	process_ctf_archive, process_ctf_type, lookup_type, read_corpus,
	~reader}): New member functions.  Most of these were free-form
	functions that took ctf::read_context as first parameter.
	In read_corpus, do not set the corpus::LINUX_KERNEL_BINARY_ORIGIN
	origin as that is now done by elf::reader when it reads the
	binary.
	(lookup_type): Remove.  These are now member functions of the
	ctf::reader class.
	(process_ctf_typedef, process_ctf_base_type)
	(build_ir_node_for_variadic_parameter_type)
	(process_ctf_function_type, process_ctf_sou_members)
	(process_ctf_forward_type, process_ctf_struct_type)
	(process_ctf_union_type, process_ctf_array_type)
	(process_ctf_qualified_type, process_ctf_pointer_type): Take a
	ctf::reader rather an ctf::read_context.  Adjust the
	content of the functions.
	(process_ctf_type, lookup_type, process_ctf_archive): Remove these
	and turn them into member functions of ctf::reader.
	(open_elf_handler, close_elf_handler, find_alt_debuginfo): Remove
	these ELF handling functions as ELF handling is now done by the
	elf_reader parent class.
	(fill_ctf_section): Take a const pointer to Elf_Scn.
	(slurp_elf_info, find_ctfa_file): Remove this and make it be a
	member of ctf::reader.  Also, make it handle only CTF
	reader specific pieces.  slurp_elf_info now delegates the reading
	of generic ELF properties to elf::reader by calling
	elf::reader::read_corpus().
	(create_read_context, read_corpus, set_read_context_corpus_group)
	(read_and_add_corpus_to_group_from_elf): Remove these functions.
	(create_reader, reset_reader): Create new functions
	(dic_type_key): Make this static.
	* include/abg-dwarf-reader.h (abigail::dwarf::elf_type):
	Move this enum into the namespace abigail::elf_reader in the file
	include/abg-elf-reader.h.
	(abigail::dwarf::{read_context, read_context_sptr,
	create_read_context, read_context_get_path, reset_read_context,
	add_read_context_suppressions, set_read_context_corpus_group,
	read_corpus_from_elf, read_and_add_corpus_to_group_from_elf,
	read_and_add_corpus_to_group_from_elf,
	add_read_context_suppressions, refers_to_alt_debug_info,
	has_alt_debug_info, get_soname_of_elf_file, get_type_of_elf_file,
	set_debug_info_root_path, get_debug_info_root_path,
	get_show_stats, set_show_stats, set_drop_undefined_syms,
	set_do_log, set_environment, get_environment}): Remove.
	* src/abg-dwarf-reader.cc (struct dwfl_deleter, dwfl_sptr)
	(addr_elf_symbol_sptr_map_type, address_set_type)
	(address_set_sptr): Delete these types.
	(read_context::options_type): Remove.  The data members of this
	type got moved to struct fe_iface::options_type.
	(find_alt_debug_info_link, find_alt_debug_info_path)
	(find_alt_debug_info, lookup_data_tag_from_dynamic_segment)
	(elf_file_type, refers_to_alt_debug_info, has_alt_debug_info)
	(get_soname_of_elf_file, get_type_of_elf_file) : Remove these ELF
	specific functions from here; move them to the elf_reader
	namespace.
	(dwarf::reader): Create new class that extends
	elf_based_reader.  dwarf::read_context is renamed into this
	type, actually.
	(dwarf::reader::die_source_dependant_container_set::get_container):
	Adjust.
	(dwarf::reader::{supprs_, dwarf_version_,
	offline_callbacks_, debug_info_root_paths_, handle_, dwarf_,
	alt_fd_, alt_dwarf_, alt_debug_info_path_, elf_module_,
	elf_handle_, elf_path_, symtab_section_, cur_corpus_group_,
	cur_corpus_, dt_needed_, dt_soname_, elf_architecture_,
	exported_decls_builder_, options_, drop_undefined_syms_}): Remove
	these ELF-related data members to move them into the elf_reader
	namespace.
	(maybe_propagate_canonical_type)
	(build_translation_unit_and_add_to_ir, build_ir_node_from_die)
	(add_or_update_class_type, add_or_update_union_type)
	(build_ir_node_for_void_type)
	(build_ir_node_for_variadic_parameter_type, build_function_decl)
	(function_is_suppressed, build_or_get_fn_decl_if_not_suppressed)
	(build_var_decl, build_or_get_var_decl_if_not_suppressed)
	(variable_is_suppressed)
	(propagate_canonical_type)
	(get_parent_die, get_scope_die, die_is_at_class_scope)
	(die_location, die_qualified_type_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, die_location)
	(die_loc_and_name, die_is_effectively_public_decl)
	(maybe_cache_type_comparison_result)
	(get_cached_type_comparison_result)
	(maybe_get_cached_type_comparison_result, die_is_at_class_scope)
	(die_function_type_is_method_type, die_member_offset)
	(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_pretty_print_type)
	(die_pretty_print_decl, die_pretty_print)
	(at_least_one_decl_only_among_odr_relevant_dies)
	(compare_as_type_dies, compare_as_decl_and_type_dies)
	(fn_die_equal_by_linkage_name, try_canonical_die_comparison)
	(maybe_propagate_canonical_type, propagate_canonical_type)
	(compare_dies, compare_dies_during_canonicalization)
	(find_import_unit_point_between_dies, get_parent_die)
	(get_scope_die, find_lower_bound_in_imported_unit_points)
	(build_translation_unit_and_add_to_ir)
	(build_namespace_decl_and_add_to_ir, build_type_decl)
	(build_enum_underlying_type, build_enum_type)
	(finish_member_function_reading)
	(maybe_finish_function_decl_reading)
	(lookup_class_or_typedef_from_corpus)
	(is_function_for_die_a_member_of_class)
	(add_or_update_member_function, add_or_update_class_type)
	(add_or_update_union_type, build_qualified_type)
	(schedule_array_tree_for_late_canonicalization)
	(maybe_strip_qualification, build_pointer_type_def)
	(build_reference_type, build_function_type, build_subrange_type)
	(build_subranges_from_array_type_die, build_array_type)
	(build_typedef_type, build_or_get_var_decl_if_not_suppressed)
	(build_var_decl, function_is_suppressed)
	(build_or_get_fn_decl_if_not_suppressed, variable_is_suppressed)
	(type_is_suppressed, type_is_suppressed)
	(get_opaque_version_of_type, create_default_fn_sym)
	(build_function_decl, maybe_canonicalize_type)
	(build_ir_node_from_die)
	(build_ir_node_for_variadic_parameter_type): Take a reference to
	the new dwarf::reader rather than to the previous
	read_context.  Adjust the function body.
	(return_comparison_result): Adjust.
	(dwarf::reader::reader): Adjust this from
	read_context::read_context.
	(dwarf::reader::initialize): Adjust from
	dwarf::read_context::initialize.
	(dwarf::reader::create): New factory static member
	function.
	(dwarf::reader::~reader): This doesn't have to clear
	anything for now.
	(dwarf::reader::read_corpus): New virtual member function
	which implements the fe_iface::read_corpus pure virtual interface.
	This now delegates the reading of the generic ELF properties to
	elf::reader by calling elf::reader::read_corpus().
	Newer front-ends will be able to do the same.
	(dwarf::reader::reset_corpus): New member function.
	(dwarf::reader::read_debug_info_into_corpus): Adjust.  This
	is now a member function.  Also, do not set the
	corpus::LINUX_KERNEL_BINARY_ORIGIN here as it's now set by the
	elf::reader when it loads the binary.
	(dwarf::reader::{env, drop_undefined_syms,
	drop_undefined_syms, dwarf_elf_handle, dwarf_per_die_source,
	elf_path, compute_canonical_die_offset, get_die_source,
	get_die_from_offset, get_die_qualified_name,
	get_die_pretty_type_representation, get_die_qualified_type_name,
	get_die_pretty_representation, odr_is_relevant,
	set_canonical_die_offset, get_canonical_die_offset,
	erase_canonical_die_offset, die_wip_classes_map,
	die_wip_function_types_map, compare_before_canonicalisation,
	resolve_declaration_only_classes, resolve_declaration_only_enums,
	symbol_already_belongs_to_a_function,
	fixup_functions_with_no_symbols, canonicalize_types_scheduled,
	tu_die_imported_unit_points_map, die_parent_map,
	find_symbol_table_section, get_variable_address,
	exported_decls_builder, load_all_types, load_in_linux_kernel_mode,
	show_stats, do_log, build_die_parent_maps): Adjust.
	(offset_pairs_stack_type::rdr_): Changed the ctxt_ into this.
	(offset_pairs_stack_type::offset_pairs_stack_type): Adjust.
	(offset_pairs_stack_type::{erase_redundant_type_pair_entry,
	cancel_canonical_propagated_type}): Adjust.
	(dwarf::reader::{get_suppressions, offline_callbacks,
	create_default_dwfl, dwfl_handle, elf_module, elf_handle,
	add_debug_info_root_paths, add_debug_info_root_path,
	find_alt_debug_info, dwarf, alt_dwarf, alt_debug_info_path,
	current_corpus, reset_current_corpus, current_corpus_group,
	has_corpus_group, main_corpus_from_current_group,
	current_corpus_is_main_corpus_from_current_group,
	should_reuse_type_from_corpus_group, function_symbol_is_exported,
	variable_symbol_is_exported, symtab, dt_needed, dt_soname,
	elf_architecture, is_elf_symbol_suppressed,
	load_dt_soname_and_needed, load_elf_architecture,
	load_elf_properties, maybe_add_fn_to_exported_decls,
	maybe_add_var_to_exported_decls}): Remove these member functions
	as they got moved into the elf_reader namespace or into the
	fe_iface class.
	(dwarf::read_context::{suppression_can_match,
	suppression_matches_function_sym_name,
	suppression_matches_function_name,
	suppression_matches_variable_name,
	suppression_matches_variable_sym_name,
	suppression_matches_type_name_or_location}): Move these into the
	suppr namespace.  Make it take an additional parameter that is
	reference fe_iface.
	(dwarf::reader::load_debug_info): Remove.  This became
	merged into dwarf::read_debug_info_into_corpus.
	(dwarf::{set_debug_info_root_path,
	get_debug_info_root_path, get_show_stats, set_drop_undefined_syms,
	set_do_log}): Remove.
	(add_read_context_suppressions)
	(set_read_context_corpus_group, read_corpus_from_elf): Remove.
	(read_debug_info_into_corpus): This became a member function of
	dwarf::reader.
	(create_reader): Renamed create_read_context into this.
	Make it return an elf_based_reader_sptr, like the other front-end
	factory functions.  Adjust.
	(reset_dwarf_reader): Renamed reset_read_context into this.
	Adjust.
	(read_corpus_from_elf): Adjust.
	* src/abg-elf-based-reader.cc: New file.
	* src/abg-elf-helpers.h (struct dwfl_deleter, dwfl_sptr)
	(addr_elf_symbol_sptr_map_type, address_set_sptr): Move these
	types here from abg-dwarf-reader.cc
	(initialize_dwfl_callbacks, lookup_data_tag_from_dynamic_segment):
	* src/abg-elf-helpers.cc (lookup_data_tag_from_dynamic_segment)
	(lookup_data_tag_from_dynamic_segment, initialize_dwfl_callbacks)
	(create_new_dwfl_handle, get_soname_of_elf_file): New functions
	that got moved here from the factorizing of abg-dwarf-reader.cc
	and abg-ctf-reader.cc.
	* src/abg-tools-utils.cc (file_has_dwarf_debug_info)
	(file_has_ctf_debug_info): New functions.
	(load_generate_apply_suppressions): Take an elf_based_reader, not
	a dwarf::read_context.
	(maybe_load_vmlinux_dwarf_corpus): Adjust the body to use the new
	front-end types.
	* src/Makefile.am: Add the new files src/abg-{fe-iface,
	elf-based-reader, elf-reader}.cc to source distribution. Remove
	src/abg-elf-reader-common.cc.
	* tools/Makefile.am: Factorize linking to libabigail.so by using
	LDADD.
	* tools/abicompat.cc (read_corpus, main): Adjust.
	* tools/abidiff.cc (set_suppressions)
	(set_native_xml_reader_options, handle_error, main): Adjust.
	* tools/abidw.cc (set_suppressions, load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml): Adjust.
	* tools/abilint.cc (build_type_use_tree, show_how_type_is_used)
	(set_suppressions, main): Adjust.
	* tools/abipkgdiff.cc (elf_file::type, compare, compare_to_self)
	(create_maps_of_package_content)
	(compare_prepared_userspace_packages)
	(self_compare_prepared_userspace_package): Adjust.
	* tools/abisym.cc: Adjust invocation to
	abigail::dwarf::lookup_symbol_from_elf, from
	abigail::dwarf_reader::lookup_symbol_from_elf.
	* tools/kmidiff.cc (main): Adjust.
	* tests/print-diff-tree.cc (main): Adjust.
	* tests/test-abidiff.cc (main): Likewise.
	* tests/test-diff-dwarf.cc (main): Likewise.
	* tests/test-ir-walker.cc (main): Likewise.
	* tests/test-read-ctf.cc (test_task_ctf::perform): Likewise.
	* tests/test-read-dwarf.cc: Remove the useless "using" statements.
	* tests/test-read-write.cc: Likewise.
	* tests/test-symtab.cc (read_corpus, TEST_CASE)
	(assert_symbol_count): Adjust.
	* tests/data/test-read-ctf/test0.abi: Adjust.
	* tests/data/test-read-ctf/test0.hash.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.hash.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-11-18 18:12:38 +01:00
Dodji Seketeli
2bb45265d3 Use environment by reference.
This patch simplifies how the environment is created and passed around
the functions that create front ends.  With this change, the
environment can simply be allocated on the stack and passed by
reference to the libabigail pipeline.

At the core of this change, type_or_decl_base::priv now carries a
const reference to an environment rather than a pointer.  The side
effect is that type_or_decl_base can no longer be copied.  This is not
a problem because throughout the years I could see that the use case
to copy ABI artifacts is just not there.  Similarly, elf_symbol::priv
carries a const reference to environment now, no more a pointer.
Getters, setters and code that use the environment from the ABI
artifacts are updated accordingly.

The DWARF front-end can now be created by code that looks like this,
for instance:

    vector<char**> debug_info_paths;
    abigail::ir::environment env;

    abigail::ctf_reader::read_context_sptr reader =
      abigail::dwarf_reader::create_read_context("elf/file/to/analyze",
						 debug_info_paths, env);

    elf_reader::status reading_status;
    corpus_sptr abi_corpus =
      abigail::dwarf_reader::read_corpus_from_elf(reader, reading_status);

	/* then do something with the resulting abi_corpus*/

Note how, you don't need to use the "new" operator to instantiate the
"env" object of type environment.  It can sit on the stack and it's
passed to the read_corpus_from_elf function by reference.

In other words, the internal representation types have been changed to
refer to the environment by reference, rather than requiring a pointer
to it.

	* include/abg-corpus.h (corpus::corpus)
	(corpus_group::corpus_group): Take environment&, not environment*
	as parameter.
	(corpus::{get_environment, set_environment}): Take or return
	environment&, not environment*.
	* src/abg-corpus.cc (corpus::corpus): Likewise.
	(corpus::{get_environment, set_environment}): Likewise.
	(corpus::add): Don't update the environment of the translation
	unit.
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces, init_format_version,
	add_corpus}): Adjust for accessing a reference to environment,
	rather than a pointer.
	* include/abg-ctf-reader.h (create_read_context): Take or return
	environment&, not environment*.
	* src/abg-ctf-reader.cc (read_context::ir_env): Make this a
	reference to environment, not pointer anymore.
	(read_context::read_context): Initialize the reference to
	environment.
	(read_context::initialize): Do not re-set the environment.
	(process_ctf_base_type)
	(build_ir_node_for_variadic_parameter_type)
	(process_ctf_enum_type, read_corpus): Adjust for accessing a
	reference to environment, rather than a pointer.
	(create_read_context, reset_read_context): Take environment&, not
	environment*.
	* include/abg-dwarf-reader.h (create_read_context)
	(reset_read_context, read_corpus_from_elf)
	(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf):
	Likewise.
	* src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab)
	(lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab)
	(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf):
	Likewise.
	(read_context::options_type::env): Make this be a reference to
	environment, not a pointer.
	(read_context::options::options): Remove the default constructor.
	Add a new one to initialize the environment data member.
	(read_context::read_context): Take environment&, not environment*.
	Initialize the options_ data member.
	(read_context::initialize): Do not take or initialize an
	environment anymore.
	(read_context::env): Return or take environment&, not
	environment*.
	(read_context::{get_die_qualified_name,
	get_die_qualified_type_name, get_die_pretty_type_representation,
	get_die_pretty_representation, compare_before_canonicalisation})
	(build_translation_unit_and_add_to_ir, build_function_type)
	(build_typedef_type, read_debug_info_into_corpus)
	(read_debug_info_into_corpus, build_ir_node_from_die)
	(build_ir_node_for_variadic_parameter_type, has_alt_debug_info):
	Adjust to use an environment&, not a pointer.
	(create_default_fn_sym, create_read_context)
	(read_corpus_from_elf, lookup_symbol_from_elf)
	(lookup_public_function_symbol_from_elf): Take environment&, not
	environment*.
	(reset_read_context): Do not take or reset environment* anymore.
	* include/abg-fwd.h (type_or_void): Likewise.
	* include/abg-ir.h (translation_unit::translation_unit): Likewise.
	(translation_unit::{get_environment, set_environment}): Likewise.
	(elf_symbol::elf_symbol): Likewise.
	(elf_symbol::create): Remove the overload that takes no
	parameter.  Then for overload that take parameters then take
	environment&, not environment*.
	(elf_symbol::get_environment): Take environment&, not
	environment*.
	(type_or_decl_base::type_or_decl_base): Make the copy constructor
	and assignment operator private.
	(type_or_decl_base::{s,g}et_environment): Take or return
	environment& not environment*.
	(type_or_decl_base::set_environment_for_artifact): Erase these
	methods.
	(decl_base::decl_base): Make copy constructor private.  Take or
	return environment&, not environment* for the other constructors.
	(scope_decl::scope_decl): Take or return environment&, not
	environment*.
	(type_base::type_base): Likewise.
	(scope_type_decl::scope_type_decl): Likewise.
	(namespace_decl::namespace_decl): Likewise.
	(qualified_type_def::qualified_type_def): Likewise.
	(pointer_type_def::pointer_type_def): Likewise.
	(reference_type_def::reference_type_def): Likewise.
	(array_type_def::subrange_type::subrange_type): Likewise.
	(enum_type_def::enumerator::enumerator): Likewise.
	(enum_type_def::enumerator::{get_name, get_qualified_name}):
	Return a string&, no more interned_string&.  As the enumerator
	don't have an enumerator anymore, there is no way to intern the
	string anymore.  Hopefully this won't incur a performance loss.
	(typedef_decl::typedef_decl, function_type::function_type)
	(method_type::method_type, template_decl::template_decl)
	(function_tdecl::function_tdecl, class_tdecl::class_tdecl)
	(class_or_union::class_or_union, class_decl::class_decl)
	(union_decl::union_decl): Take or return environment&, not
	environment*.
	* include/abg-reader.h (read_translation_unit_from_file)
	(read_translation_unit_from_buffer)
	(read_translation_unit_from_istream)
	(create_native_xml_read_context, create_native_xml_read_context)
	(read_corpus_from_native_xml, read_corpus_from_native_xml_file)
	(read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file): Likewise.
	* include/abg-tools-utils.h
	(build_corpus_group_from_kernel_dist_under): Likewise.
	* src/abg-tools-utils.cc (maybe_load_vmlinux_dwarf_corpus)
	(maybe_load_vmlinux_ctf_corpus)
	(build_corpus_group_from_kernel_dist_under): Likewise.
	* include/abg-writer.h (create_write_context): Likewise.
	* src/abg-writer.cc (id_manager::m_env, id_manager::id_manager)
	(id_manager::get_environment, id_manager::get_id)
	(id_manager::get_id_with_prefix): Adjust.
	(write_context::m_env, write_context::write_context)
	(write_context::get_environment, write_context::get_config)
	(write_context::get_id_for_type, write_context::decl_is_emitted)
	(write_context::record_decl_as_emitted, create_write_context)
	(write_class_decl): Likewise.
	* src/abg-comparison.cc (compute_diff): Stop ensuring that the two
	artifacts being compare are in the same environment.  Now that the
	environment is passed by reference, the potential for
	accendentally comparing artifacts coming from different
	environments is very low, given how the API is used in practice.
	This is in the overloads for decl_base_sptr, type_base_sptr,
	var_decl_sptr, pointer_type_def_sptr, array_type_def_sptr,
	reference_type_def_sptr, qualified_type_def_sptr,
	enum_type_decl_sptr, class_decl_sptr, class_decl::base_spec_sptr,
	union_decl_sptr, scope_decl_sptr, function_decl::parameter_sptr,
	function_type_sptr, function_decl_sptr, type_decl_sptr,
	typedef_decl_sptr, translation_unit_sptr, corpus_sptr.
	* src/abg-corpus-priv.h (corpus::priv::env): Make this be a
	reference to environments, not a pointer.
	(corpus::priv::priv): Pass environment&, not environment*.
	* src/abg-ir-priv.h (translation_unit::priv::env_): Make this an
	environment&, not an environment* anymore.
	(translation_unit::priv::priv): Take an environment&, not an
	environment*.
	(environment::priv::{confirm_ct_propagation_for_types_dependant_on,
	confirm_ct_propagation,
	cancel_ct_propagation_for_types_dependant_on,
	mark_as_being_compared, unmark_as_being_compared,
	comparison_started, mark_as_being_compared, comparison_started}):
	Adjust to use an environment&, not a pointer.
	* src/abg-ir.cc (class environment_setter): Remove this class.
	(push_composite_type_comparison_operands)
	(pop_composite_type_comparison_operands, try_canonical_compare)
	(return_comparison_result, translation_unit::{get_global_scope,
	bind_function_type_life_time}): Adjust.
	(translation_unit::{translation_unit, get_environment}): Take or
	get an environment&, not an environment*.  Remove the getter that
	returns an environment*.
	(elf_symbol::priv::env_): Make this an environment&, not an
	environment*.
	(elf_symbol::priv::priv): Adjust.
	(elf_symbol::elf_symbol): Remove the default constructor.  Change
	the one that takes an environment.
	(elf_symbol::create): Remove the default one.  Adjust the one that
	takes an environment.
	(elf_symbol::get_environment): Adjust.
	(elf_symbol::set_environment_for_artifact): Remove.
	(environment::{get_void_type, get_variadic_parameter_type}):
	Adjust.
	(type_or_decl_base::priv::env_): Make this be a const
	environment&, not a const environment*.
	(type_or_decl_base::priv::priv): Adjust.
	(type_or_decl_base::type_or_decl_base): Remove the default and
	copy constructor.
	(type_or_decl_base::{set_environment, operator=})
	(set_environment_for_artifact): Remove.
	(type_or_decl_base::get_environment): Adjust.
	(decl_base::{decl_base, set_name, set_naming_typedef,
	set_linkage_name}): Adjust.
	(get_decl_name_for_comparison, strip_typedef)
	(strip_useless_const_qualification): Adjust.
	(scope_decl::{scope_decl, add_member_decl, insert_member_decl}):
	Adjust.
	(get_generic_anonymous_internal_type_name, get_type_name)
	(get_name_of_pointer_to_type, get_name_of_reference_to_type)
	(get_name_of_qualified_type, get_function_type_name)
	(get_method_type_name, is_void_pointer_type, lookup_basic_type)
	(lookup_union_type, lookup_union_type_per_location)
	(lookup_enum_type, lookup_typedef_type, lookup_pointer_type)
	(lookup_type, lookup_basic_type_per_location)
	(lookup_basic_type_per_location, lookup_basic_type)
	(lookup_class_type, lookup_class_types)
	(lookup_class_type_per_location, lookup_union_type)
	(lookup_enum_type, lookup_enum_types)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map)
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit)
	(demangle_cplus_mangled_name, type_or_void)
	(types_defined_same_linux_kernel_corpus_public)
	(compare_types_during_canonicalization)
	(type_base::get_canonical_type_for, type_base::type_base)
	(type_base::get_cached_pretty_representation)
	(type_decl::type_decl, type_decl::get_qualified_name): Adjust.
	(scope_type_decl::scope_type_decl)
	(namespace_decl::namespace_decl, qualified_type_def::build_name)
	(qualified_type_def::qualified_type_def)
	(qualified_type_def::get_qualified_name)
	(qualified_type_def::set_underlying_type)
	(pointer_type_def::pointer_type_def)
	(pointer_type_def::set_pointed_to_type)
	(reference_type_def::reference_type_def)
	(reference_type_def::set_pointed_to_type)
	(array_type_def::subrange_type::subrange_type)
	(array_type_def::array_type_def, array_type_def::update_size)
	(array_type_def::set_element_type)
	(array_type_def::append_subranges)
	(array_type_def::get_qualified_name, enum_has_non_name_change):
	Adjust.
	(enum_type_decl::enumerator::priv::env_): Remove this pointer to
	env.  This is because the enumerator must be copy-able.  As the
	enumerator doesn't have an env anymore, it can't intern strings.
	So the enumerator name and qualified name is not going to be
	interned.  If that incurs a performance hit, we'll reconsider this
	decision.  For now, it seems to work OK.  As it simplifies things,
	I am keeping this for now.
	(enum_type_decl::enumerator::priv::{name, qualified_name}): Make
	this be string, not interned_string.
	(enum_type_decl::enumerator::get_environment): Remove.
	(enum_type_decl::enumerator::priv::priv): Adjust.
	(enum_type_decl::enumerator::enumerator)
	(enum_type_decl::enumerator::operator=)
	(enum_type_decl::enumerator::get_name)
	(enum_type_decl::enumerator::get_qualified_name)
	(enum_type_decl::enumerator::set_name): Likewise.
	(typedef_decl::typedef_decl): Adjust.
	(var_decl::get_id, var_decl::get_qualified_name): Adjust.
	(function_type::function_type, method_type::method_type)
	(function_decl::get_pretty_representation_of_declarator)
	(function_decl::set_symbol): Likewise.
	(function_decl::get_id, function_decl::parameter::get_type)
	(function_decl::parameter::get_type_name)
	(function_decl::parameter::get_type_pretty_representation)
	(function_decl::parameter::get_name_id)
	(class_or_union::class_or_union, class_decl::class_decl)
	(class_decl::add_base_specifier, union_decl::union_decl)
	(union_decl::union_decl, template_decl::template_decl)
	(class_tdecl::class_tdecl)
	(maybe_cancel_propagated_canonical_type)
	(dump_classes_being_compared)
	(dump_fn_types_being_compared, copy_member_function)
	(maybe_propagate_canonical_type, keep_type_alive)
	(is_non_canonicalized_type, qualified_name_setter::do_update):
	Likewise.
	(equals): Adjust the overloads for var_decl, function_type,
	class_or_union, class_decl, union_decl.
	* src/abg-reader.cc (read_context::m_env): Make this be an
	environment&, not an environment*.
	(read_context::read_context): Adjust
	(read_context::set_environment): Remove.
	(read_context::{get_environment,
	maybe_check_abixml_canonical_type_stability}): Adjust.
	(read_corpus_from_input, read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file)
	(read_translation_unit_from_file)
	(read_translation_unit_from_buffer, read_translation_unit)
	(maybe_map_type_with_type_id, build_namespace_decl)
	(build_elf_symbol, build_function_parameter, build_function_decl)
	(build_function_type, build_enum_type_decl, build_class_decl)
	(build_union_decl, build_function_tdecl, build_class_tdecl)
	(build_type_tparameter, read_translation_unit_from_istream)
	(create_native_xml_read_context, read_corpus_from_native_xml):
	Likewise.
	* src/abg-symtab-reader.h (symtab::load): Likewise.
	* src/abg-symtab-reader.cc (symtab::load): Likewise.
	* tests/print-diff-tree.cc (main): Likewise.
	* tests/test-abidiff.cc (main): Likewise.
	* tests/test-diff-dwarf.cc (main): Likewise.
	* tests/test-ir-walker.cc (main): Likewise.
	* tests/test-read-ctf.cc (test_task_ctf::perform): Likewise.
	* tests/test-symtab.cc (read_corpus): Likewise.
	* tools/abicompat.cc (read_corpus, main): Likewise.
	* tools/abidiff.cc (main): Likewise.
	* tools/abidw.cc (load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml, main): Likewise.
	* tools/abilint.cc (main): Likewise.
	* tools/abipkgdiff.cc (compare, compare_to_self)
	(compare_prepared_linux_kernel_packages,  compare_task::perform):
	Likewise.
	* tools/abisym.cc (main): Likewise.
	* tools/kmidiff.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-11-18 15:22:49 +01:00
Dodji Seketeli
2d1e324727 Update year in copyright notice
* include/abg-comp-filter.h: Update year in copyright notice.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-ctf-reader.h: Likewise.
	* include/abg-cxx-compat.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-elf-reader-common.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-regex.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-ctf-reader.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-elf-helpers.cc: Likewise.
	* src/abg-elf-helpers.h: Likewise.
	* src/abg-elf-reader-common.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-regex.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-symtab-reader.cc: Likewise.
	* src/abg-symtab-reader.h: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-cxx-compat.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-elf-helpers.cc: Likewise.
	* tests/test-ini.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-kmi-whitelist.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-ctf.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-symtab-reader.cc: Likewise.
	* tests/test-symtab.cc: Likewise.
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/kmidiff.cc: Likewise.
	* update-copyright.sh: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-06-21 12:58:57 +02:00
Guillermo E. Martinez
e64d32bee3 ctf-reader: Add support to read CTF information from the Linux Kernel
This patch is meant to extract ABI information from the CTF data
stored in the Linux kernel build directory.  It depends on the
vmlinux.ctfa archive file.

In order to generate the CTF information, the Linux Kernel build
system must support the 'make ctf' command, which causes the compiler
to be run with -gctf, thus emitting the CTF information for the
Kernel.

The target 'ctf' in the Linux Makefile generates a 'vmlinux.ctfa' file
that will be used by the ctf reader in libabigail. The 'vmlinux.ctfa'
archive has multiple 'ctf dictionaries' called "CTF archive members".

There is one CTF archive member for built-in kernel modules (in
`vmlinux') and one for each out-of-tree kernel module organized in a
parent-child hierarchy.

There is also a CTF archive member called `shared_ctf' which is a
parent dictionary containing shared symbols and CTF types used by more
than one kernel object.  These common types are stored in 'types_map'
in the ctf reader, ignoring the ctf dictionary name.  The CTF API has
the machinery for looking for a shared type in the parent dictionary
referred to in a given child dictionary. This CTF layout can be dumped
by using the objdump tool.

Due to the fact that the _same_ ctf archive is used to build the
vmlinux corpus the corpora of the kernel module (which, by the way,
all belong to the same corpus group), the high number of open/close on
the CTF archive is very time consuming during the ctf extraction.

So, the performance is improved up to 300% (from ~2m:50s to ~50s) by
keeping the ctf archive open for a given group, and thus, by using the
same ctf_archive_t pointer while building all the various corpora.

We just invoke `reset_read_context' for each new corpus.  Note that
the `read_context::ctfa` data member should be updated if the
corpus::origin data member is set to `LINUX_KERNEL_BINARY_ORIGIN' and
the file to be process is not 'vmlinux'.

Note that `ctf_close' must be called after processing all group's
members so it is executed from the destructor of `reader_context'.

The basic algorithm used to generate the Linux corpus is the
following:

   1. Looking for: vmlinux, *.ko objects, and vmlinux.ctfa files. The
   first files are used to extract the ELF symbols, and the last one
   contains the CTF type information for non-static variables and
   functions symbols.

   2. `process_ctf_archive' iterates on public symbols for vmlinux and
   its modules, using the name of the symbol, ctf reader search for CTF
   information in its dictionary, if the information was found it
   builds a `var_decl' or `function_decl' depending of `ctf_type_kind'
   result.

This algorithm is also applied to ELF files (exec, dyn, rel), so
instead of iterating on all ctf_types it just loops on the public
symbols.

	* abg-elf-reader-common.h: Include ctf-api.h file.
	(read_and_add_corpus_to_group_from_elf, set_read_context_corpus_group)
	(reset_read_context, dic_type_key): Declare new member functions.
	* include/abg-ir.cc (types_defined_same_linux_kernel_corpus_public): Use
	bitwise to know the corpus `origin'.
	* src/abg-ctf-reader.cc: Include map, algorithms header files.
	(read_context::type_map): Change from unordered_map to std::map storing
	ctf dictionary name as part of the key.
	(read_context::is_elf_exec): Add new member variable.
	(read_context::{cur_corpus_, cur_corpus_group_}): Likewise.
	(read_context::unknown_types_set): Likewise.
	(read_context::{current_corpus_group, main_corpus_from_current_group,
	has_corpus_group, current_corpus_is_main_corpus_from_current_group,
	should_reuse_type_from_corpus_group}): Add new member functions.
	(read_context::{add_unknown_type, lookup_unknown_type, initialize}):
	Likewise.
	(read_context::{add_type, lookup_type}): Add new `ctf_dict_t' type
	argument.
	(ctf_reader::{process_ctf_typedef, process_ctf_base_type,
	process_ctf_function_type, process_ctf_forward_type,
	process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type,
	process_ctf_qualified_type, process_ctf_enum_type}): Add code to `reuse'
	types already registered in main corpus `should_reuse_type_from_corpus_group'.
	Use new `lookup_type' and `add_type' operations on `read_context::types_map'.
	Replace function calls to the new ctf interface. Add verifier to not build
	types duplicated by recursive calling chain.
	(ctf_reader::process_ctf_type): Add code to return immediately if the
	ctf type is unknown. Add unknown types to `unknown_types_set'.
	(ctf_reader::process_ctf_archive): Change comment.
	Add code to iterate over global symbols, searching by symbol name in the
	ctf dictionary using `ctf_lookup_{variable,by_symbol_name}' depending of
	the ELF file type and corpus type, creating a `{var,fuc}_decl' using the
	return type of `ctf_type_kind'.  Also close the ctf dict and call
	`canonicalize_all_types'.
	(slurp_elf_info): Set `is_elf_exec' depending of ELF type.  Also return
	success if corpus origin is Linux and symbol table was read.
	(ctf_reader::read_corpus): Add current corpus.  Set corpus origin to
	`LINUX_KERNEL_BINARY_ORIGIN' if `is_linux_kernel' returns true.  Verify
	the ctf reader status, now the ctf archive is 'opened' using
	`ctf_arc{open,bufopen}' depending if the corpus origin has
	`corpus::LINUX_KERNEL_BINARY_ORIGIN' bit set. Use
	`sort_{function,variables}' calls after extract ctf information.
	`ctf_close' is called from `read_context' destructor.
	(read:context::{set_read_context_corpus_group, reset_read_context,
	read_and_add_corpus_to_group_from_elf, dic_type_key): Add new member
	function implementation.
	* include/abg-tools-utils.h (build_corpus_group_from_kernel_dist_under):
	Add `origin' parameter with default `corpus::DWARF_ORIGIN'.
	* src/abg-tools-utils.cc: Use `abg-ctf-reader.h' file.
	(maybe_load_vmlinux_dwarf_corpus): Add new function.
	(maybe_load_vmlinux_ctf_corpus): Likewise.
	(build_corpus_group_from_kernel_dist_under): Update comments.
	Add new `origin' argument. Use `maybe_load_vmlinux_dwarf_corpus'
	or `maybe_load_vmlinux_ctf_corpus' according to `origin' value.
	* src/abg-corpus.h (corpus::origin): Update `origin' type
	values in enum.
	* src/abg-corpus-priv.h (corpus::priv): Replace `origin' type
	from `corpus::origin' to `uint32_t'.
	* src/abg-corpus.cc (corpus::{get,set}_origin): Replace data
	type from `corpus::origin' to `uint32_t'.
	* tools/abidw.cc (main): Use of --ctf argument to set format debug.
	* tests/test-read-ctf.cc: Add new tests to harness.
	* tests/data/test-read-ctf/test-PR27700.abi: New test expected
	  result.
	* tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-many.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi: Likewise.
	* tests/data/test-read-common/test-PR26568-2.o: Adjust.
	* tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-B.c: Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-B.o: Likewise.
	* tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise.
	* tests/data/test-read-ctf/test-callback.abi: Likewise.
	* tests/data/test-read-ctf/test-callback2.abi: Likewise.
	* tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi:
	Likewise.
	* tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-ctf.o.abi: Likewise.
	* tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise.
	* tests/data/test-read-ctf/test-enum.o.abi: Likewise.
	* tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise.
	* tests/data/test-read-ctf/test-functions-declaration.abi: Likewise.
	* tests/data/test-read-ctf/test-list-struct.abi: Likewise.
	* tests/data/test-read-ctf/test0: Likewise.
	* tests/data/test-read-ctf/test0.abi: Likewise.
	* tests/data/test-read-ctf/test0.c: Likewise.
	* tests/data/test-read-ctf/test0.hash.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.abi: Likewise.
	* tests/data/test-read-ctf/test1.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.abi: Likewise.
	* tests/data/test-read-ctf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.abi: Likewise.
	* tests/data/test-read-ctf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.abi: Likewise.
	* tests/data/test-read-ctf/test4.so.hash.abi: Likewise.
	* tests/data/test-read-ctf/test5.o.abi: Likewise.
	* tests/data/test-read-ctf/test7.o.abi: Likewise.
	* tests/data/test-read-ctf/test8.o.abi: Likewise.
	* tests/data/test-read-ctf/test9.o.abi: Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-05-13 09:11:37 +02:00
Jose E. Marchesi via Libabigail
8c22f5fdc9 Add support for the CTF debug format to libabigail.
CTF (C Type Format) is a lightweight debugging format that provides
information about C types and the association between functions and
data symbols and types.  It is designed to be very compact and
simple.  More can be learned about it at https://ctfstd.org.

This patch introduces support in libabigail to extract ABI information
from CTF stored in ELF files.

A few notes on this implementation:

- The implementation is complete in terms of CTF support.  Every CTF
  feature is processed and handled to generate libabigail IR.  This
  includes basic types, typedefs, pointer, array and struct types.
  The CTF record of data objects (variables) and functions are also
  used in order to generate the corresponding libabigail IR artifacts.

- The decoding of CTF data is done using the libctf library which is
  part of binutils.  In order to link with it, binutils shall be built
  with --enable-shared for libctf.so to become available.

- This initial implementation is aimed to simplicity.  We have not
  tried to resolve any and every corner case that may require special
  handling.  We have observed that the DWARF front-end (which is
  naturally way more complex as the scope is way bigger) is plagued
  with hacks to handle such situations.  However, for the CTF support
  we prefer to proceed in a simpler and more modest way: we will
  handle these problems if/when we find them.  The fact that CTF only
  supports C (currently) certainly helps there.

- Likewise, in this basic support we are not handling symbol
  suppressions or other goodies that libabigail provides.  We are new
  to libabigail and ABI analysis, and at this point we simply don't
  have a clear picture about what is most useful/relevant to support
  or not.  With the maintainer's blesssing, we will tackle that
  functionaly after this basic support is applied upstream.

- The implementation in abg-ctf-reader.{cc,h} is pretty much
  self-contained.  As a result there is some duplication in terms of
  ELF handling with the DWARF reader, but since that logic is very
  simple and can be easily implemented, we don't consider this to be a
  big deal (for now.)  Hopefully the maintainers agree.

- The libabigail tools assume that ELF means to always use DWARF to
  generate the ABI IR.  We added a new command-line option --ctf to
  the tools in order to make them to use the CTF debug info instead.
  We are definitely not sure whether this is the best user interface.
  In fact I would be suprised if it was ;)

- We added support for --ctf to both abilint and abidiff.   We are not
  sure whether it would make sense to add support for CTF to the other
  tools.  Feedback welcome.

- We are pondering about what to do in terms of testing.  We have
  cursory tested this implementation using abilint and abidiff.  We
  know we are generating IR corpus that seem to be ok.  It would be
  good however to be able to run the libabigail testsuites using CTF.
  However the testsuites may need some non-trivial changes in order to
  make this possible.  Let's talk about that :)

	* configure.ac: Check for libctf.
	* src/abg-ctf-reader.cc: New file.
	* include/abg-ctf-reader.h: Likewise.
	* src/Makefile.am (libabigail_la_SOURCES): Add abg-ctf-reader.cc
	conditionally.
	* include/Makefile.am (pkginclude_HEADERS): Add abg-ctf-reader.h
	conditionally.
	* tools/abilint.cc (struct options): New option `use_ctf'.
	(display_usage): Documentation for --ctf.
	(parse_command_line): Handle --ctf.
	(main): Honour --ctf.
	* tools/abidiff.cc (struct options): New option `use_ctf'.
	(display_usage): Documentation for --ctf.
	(parse_command_line): Handle --ctf.
	(main): Honour --ctf.
	* doc/manuals/abidiff.rst: Document --ctf.
	* doc/manuals/abilint.rst: Likewise.

Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-02 12:43:14 +01:00
Matthias Maennich
86c06ad684 Consistently use std::unique_ptr for private implementations (pimpl)
In the absence of non-refcounting smart pointers before C++11,
std::shared_ptr was commonly used instead. Having bumped the standard to
C++11, allows us to use std::unique_ptr consistently avoiding any costs
involved with shared_ptr ref counting. Hence do that and add default
virtual destructors where required.

	* include/abg-comparison.h (diff_maps): use unique_ptr for priv_
	(diff_context): Likewise.
	(diff_traversable_base): Likewise.
	(type_diff_base): Likewise.
	(decl_diff_base): Likewise.
	(distinct_diff): Likewise.
	(var_diff): Likewise.
	(pointer_diff): Likewise.
	(reference_diff): Likewise.
	(array_diff): Likewise.
	(qualified_type_diff): Likewise.
	(enum_diff): Likewise.
	(class_or_union_diff): Likewise.
	(class_diff): Likewise.
	(base_diff): Likewise.
	(scope_diff): Likewise.
	(fn_parm_diff): Likewise.
	(function_type_diff): Likewise.
	(function_decl_diff): Likewise.
	(typedef_diff): Likewise.
	(translation_unit_diff): Likewise.
	(diff_stats): Likewise.
	(diff_node_visitor): Likewise.
	* include/abg-corpus.h (corpus): Likewise.
	(exported_decls_builder): Likewise.
	(corpus_group): Likewise.
	* include/abg-ini.h (property): Likewise.
	(property_value): Likewise.
	(string_property_value): Likewise.
	(list_property_value): Likewise.
	(tuple_property_value): Likewise.
	(simple_property): Likewise.
	(list_property): Likewise.
	(tuple_property): Likewise.
	(config): Likewise.
	(section): Likewise.
	(function_call_expr): Likewise.
	* include/abg-interned-str.h (interned_string_pool): Likewise.
	* include/abg-ir.h (environment): Likewise.
	(location_manager): Likewise.
	(type_maps): Likewise.
	(translation_unit): Likewise.
	(elf_symbol::version): Likewise.
	(type_or_decl_base): Likewise.
	(scope_decl): Likewise.
	(qualified_type_def): Likewise.
	(pointer_type_def): Likewise.
	(array_type_def): Likewise.
	(subrange_type): Likewise.
	(enum_type_decl): Likewise.
	(enum_type_decl::enumerator): Likewise.
	(typedef_decl): Likewise.
	(dm_context_rel): Likewise.
	(var_decl): Likewise.
	(function_decl::parameter): Likewise.
	(function_type): Likewise.
	(method_type): Likewise.
	(template_decl): Likewise.
	(template_parameter): Likewise.
	(type_tparameter): Likewise.
	(non_type_tparameter): Likewise.
	(template_tparameter): Likewise.
	(type_composition): Likewise.
	(function_tdecl): Likewise.
	(class_tdecl): Likewise.
	(class_decl::base_spec): Likewise.
	(ir_node_visitor): Likewise.
	* include/abg-suppression.h (suppression_base): Likewise.
	(type_suppression::insertion_range): Likewise.
	(type_suppression::insertion_range::boundary): Likewise.
	(type_suppression::insertion_range::integer_boundary): Likewise.
	(type_suppression::insertion_range::fn_call_expr_boundary): Likewise.
	(function_suppression): Likewise.
	(function_suppression::parameter_spec): Likewise.
	(file_suppression): Likewise.
	* include/abg-tools-utils.h (temp_file): Likewise.
	(timer): Likewise.
	* include/abg-traverse.h (traversable_base): Likewise.
	* include/abg-workers.h (queue): Likewise.
	* src/abg-comparison.cc (diff_context): add default destructor.
	(diff_maps): Likewise.
	(corpus_diff): Likewise.
	(diff_node_visitor): Likewise.
	(class_or_union_diff::get_priv): adjust return type.
	(class_diff::get_priv): adjust return type.
	* src/abg-corpus.cc (corpus): add default destructor.
	* src/abg-ir.cc (location_manager): Likewise.
	(type_maps): Likewise.
	(elf_symbol::version): Likewise.
	(array_type_def::subrange_type): Likewise.
	(enum_type_decl::enumerator): Likewise.
	(function_decl::parameter): Likewise.
	(class_decl::base_spec): Likewise.
	(ir_node_visitor): Likewise.

Signed-off-by: Matthias Maennich <maennich@google.com>
2021-07-16 11:16:47 +02:00
Matthias Maennich
7851ca2b91 abg-corpus: remove symbol maps and their setters
With the prework in previous commits, we are now able to drop the
public symbols maps in corpus::priv and replace them by private members
with access through getters. The getters use the new symtab
implementation to generate the maps on the fly. Setters are not required
anymore and are removed. Also remove redundant getters.

We could also remove the getters for the symbol maps and the local
caching variable and leave it all to lookup_symbol, but this is left for
a later change.

	* include/abg-corpus.h (corpus::set_fun_symbol_map): Remove
	method declaration.
	(corpus::set_undefined_fun_symbol_map): Likewise.
	(corpus::set_var_symbol_map): Likewise.
	(corpus::set_undefined_var_symbol_map): Likewise.
	(corpus::get_fun_symbol_map_sptr): Likewise.
	(corpus::get_undefined_fun_symbol_map_sptr): Likewise.
	(corpus::get_var_symbol_map_sptr): Likewise.
	(corpus::get_undefined_var_symbol_map_sptr): Likewise.
	* src/abg-corpus-priv.h (corpus::priv::var_symbol_map): make
	private and mutable
	(corpus::priv::undefined_var_symbol_map): Likewise.
	(corpus::priv::fun_symbol_map): Likewise.
	(corpus::priv::undefined_fun_symbol_map): Likewise.
	(corpus::priv::get_fun_symbol_map): New method declaration.
	(corpus::priv::get_undefined_fun_symbol_map): Likewise.
	(corpus::priv::get_var_symbol_map): Likewise.
	(corpus::priv::get_undefined_var_symbol_map): Likewise.
	* src/abg-corpus.cc (corpus::priv::get_fun_symbol_map): New
	method implementation.
	(corpus::priv::get_undefined_fun_symbol_map): Likewise.
	(corpus::priv::get_var_symbol_map): Likewise.
	(corpus::priv::get_undefined_var_symbol_map): Likewise.
	(corpus::is_empty): depend on symtab only.
	(corpus::set_fun_symbol_map): Remove method.
	(corpus::set_undefined_fun_symbol_map): Likewise.
	(corpus::set_var_symbol_map): Likewise.
	(corpus::set_undefined_var_symbol_map): Likewise.
	(corpus::get_fun_symbol_map_sptr): Likewise.
	(corpus::get_undefined_fun_symbol_map_sptr): Likewise.
	(corpus::get_var_symbol_map_sptr): Likewise.
	(corpus::get_undefined_var_symbol_map_sptr): Likewise.
	(corpus::get_fun_symbol_map): Use corpus::priv proxy method.
	(corpus::get_undefined_fun_symbol_map): Likewise.
	(corpus::get_var_symbol_map): Likewise.
	(corpus::get_undefined_var_symbol_map): Likewise.
	* src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Do not
	set corpus symbol maps anymore.
	* src/abg-reader.cc (read_corpus_from_input): Likewise.
	* tests/test-symtab.cc (assert_symbol_count): Do not access the
	corpus symbol maps through sptr anymore.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Adjust
	expected test output.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-04-02 15:48:01 +02:00
Matthias Maennich
ae094e349e Integrate new symtab reader into corpus and read_context
While reading the corpus in the read_context, also load the new type
symtab object side-by-side and set it accordingly in the resulting
corpus. This is still side by side and passive code that gets active in
the following changes. This is applicable for the dwarf reader as well
as for the reader that consumes XML.

	* include/abg-corpus.h (corpus::set_symtab): New method declaration.
	  (corpus::get_symtab): New method declaration.
	* include/abg-fwd.h (symtab_reader::symtab_sptr): New forward
	  declaration.
	* src/abg-corpus-priv.h (corpus::priv::symtab_): New data member.
	* src/abg-corpus.cc
	  (corpus::set_symtab): Likewise.
	  (corpus::get_symtab): Likewise.
	* src/abg-dwarf-reader.cc (read_context::symtab_): New data member.
	  (read_context::initialize): reset symtab_ as well
	  (read_context::symtab): new method that loads a symtab on
	  first access and returns it.
	  (read_debug_info_into_corpus): also set the new symtab object
	  on the current corpus.
	  (read_corpus_from_elf): Also determine (i.e. load) the new
	  symtab object and contribute to the load status.
	* src/abg-reader.cc (read_corpus_from_input): also set the new
	  type symtab when reading from xml.
	* tests/test-symtab.cc: Add test assertions.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2021-04-01 14:37:26 +02:00
Dodji Seketeli
23046152e0 Bump ABIXML format version to 2.0
After fixing the interpretation of the DW_AT_bit_offset attribute for
offset of bit field data members, serialized abixml might now be
incompatible with versions of Libabigail that use the previous
interpretation.

That means that comparing an abixml file generated with previous
versions of Libabigail against a corpus resulting from an analysis
performed with the current version of libabigail might yield spurious
changes due to the differences in the way we now interpret the
DW_AT_bit_offset.

Hence, this patch bumps the version of abixml files emitted from now
on to "2.0".  This version is deemed incompatible with the previous
"1.0" version.

Subsequently, an abixml file of the "1.0" format cannot be compared
against an abixml file of the "2.0" format, or against a binary
analyzed with a current version of Libabigail.

It's thus advised that abixml files of the "1.0" format version should
be re-generated with a current version of Libabigail, bumping their
format version number to the new "2.0".

	* include/abg-corpus.h (corpus::init_format_version): Declare new
	private method.
	(corpus::set_environment): Make this non-const.
	(corpus::{get,set}_format_{major,minor}_version_number): Declare
	new accessors.
	* src/abg-corpus.cc (corpus::init_format_version): Define new
	method.
	(corpus::set_environment): By default, initialize the format
	version number of the corpus to the one supported by Libabigail.
	(corpus::{get,set}_format_{major,minor}_version_number): Define
	new accessors.
	* include/abg-ir.h: Include abg-config.h to use the
	abigail::config.
	(environment::get_config): Declare new accessor.
	* src/abg-ir.cc (environment::priv::config_): Add new data member.
	(environment::get_config): Define new accessor.
	* src/abg-config.cc (config::config): Bump the format
	version number to "2.0".
	* src/abg-corpus-priv.h
	(corpus::priv::format_{major,minor}_version_number_): Add new data members.
	* src/abg-reader.cc (handle_version_attribute): Define new static
	function.
	(read_corpus_from_input, read_corpus_group_from_input): Use it to
	read the value of the "version" attribute and set the format
	version number of the corpus and corpus group accordingly.
	* src/abg-writer.cc (write_context::m_config): Remove the config
	object because we can now get it from the environment.
	(write_context::get_config): Get the config object from the
	environment.
	(write_translation_unit): Do not emit the version attribute on the
	translation unit element anymore.
	(write_version_info): Define static function.
	(write_corpus, write_corpus_group): Use it to emit version
	attribute on both the corpus and corpus group elements.
	* tools/abidiff.cc
	(emit_incomptatible_format_version_error_message): Define new
	static function.
	(main): Ensure that corpora and corpus groups being compared have
	the same major version number.
	* tests/update-test-output.py: Adjust syntax for python3.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi:
	Likewise.
	* tests/data/test-annotate/test0.abi: Likewise.
	* tests/data/test-annotate/test1.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/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test2.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test3.so.abi: Likewise.
	* tests/data/test-annotate/test4.so.abi: Likewise.
	* tests/data/test-annotate/test5.o.abi: Likewise.
	* tests/data/test-annotate/test6.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Likewise.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-v0.so.abi:
	Likewise.
	* tests/data/test-diff-suppr/libtest48-soname-abixml-v1.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/PR24378-fn-is-not-scope.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-1.o.abi: Likewise.
	* tests/data/test-read-dwarf/test-PR26568-2.o.abi: Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test1.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test3.so.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test4.so.abi: Likewise.
	* tests/data/test-read-dwarf/test4.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.abi: Likewise.
	* tests/data/test-read-dwarf/test5.o.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test7.so.hash.abi: Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test0.xml: Likewise.
	* tests/data/test-read-write/test1.xml: Likewise.
	* tests/data/test-read-write/test10.xml: Likewise.
	* tests/data/test-read-write/test11.xml: Likewise.
	* tests/data/test-read-write/test12.xml: Likewise.
	* tests/data/test-read-write/test13.xml: Likewise.
	* tests/data/test-read-write/test14.xml: Likewise.
	* tests/data/test-read-write/test15.xml: Likewise.
	* tests/data/test-read-write/test16.xml: Likewise.
	* tests/data/test-read-write/test17.xml: Likewise.
	* tests/data/test-read-write/test18.xml: Likewise.
	* tests/data/test-read-write/test19.xml: Likewise.
	* tests/data/test-read-write/test2.xml: Likewise.
	* tests/data/test-read-write/test20.xml: Likewise.
	* tests/data/test-read-write/test21.xml: Likewise.
	* tests/data/test-read-write/test22.xml: Likewise.
	* tests/data/test-read-write/test23.xml: Likewise.
	* tests/data/test-read-write/test24.xml: Likewise.
	* tests/data/test-read-write/test25.xml: Likewise.
	* tests/data/test-read-write/test26.xml: Likewise.
	* tests/data/test-read-write/test27.xml: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.
	* tests/data/test-read-write/test3.xml: Likewise.
	* tests/data/test-read-write/test4.xml: Likewise.
	* tests/data/test-read-write/test5.xml: Likewise.
	* tests/data/test-read-write/test6.xml: Likewise.
	* tests/data/test-read-write/test7.xml: Likewise.
	* tests/data/test-read-write/test8.xml: Likewise.
	* tests/data/test-read-write/test9.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-02-01 14:09:29 +01:00
Dodji Seketeli
c80f79271a Re-license the project to Apache v2 With LLVM Exception
Thanks to the previous work done, changing the license is just a
matter of changing the SPDX identifer from "LGPL-3.0-or-later" to
"Apache-2.0 WITH LLVM-exception".  Note that for the abigail.m4,
tests/test-dot.cc and tests/test-svg.cc the change was from
"GPL-3.0-or-later WITH GCC-exception-3.1" to "Apache-2.0 WITH
LLVM-exception".  include/abg-cxx-compat.h was changed from
"LGPL-2.0-or-later" to "Apache-2.0 WITH LLVM-exception".  Source code
of programs (as opposed to source code of the library) where generally
licensed under GPL-3.0-or-later; they are also now licensed
"Apache-2.0 WITH LLVM-exception".

This is what this patch does.

	* abigail.m4: Change the SPDX identifier from "GPL-3.0-or-later
	WITH GCC-exception-3.1" to "Apache-2.0 WITH LLVM-exception"
	* include/abg-cxx-compat.h: Change the SPDX identifier from
	"LGPL-2.0-or-later" to "Apache-2.0 WITH LLVM-exception".
	* .clang-format: Change the SPDX identifier from
	  "LGPL-3.0-or-later" to "Apache-2.0 WITH LLVM-exception".
	* Makefile.am: Likewise.
	* bash-completion/Makefile.am: Likewise.
	* bash-completion/abicompat: Likewise.
	* bash-completion/abidiff: Likewise.
	* bash-completion/abidw: Likewise.
	* bash-completion/abilint: Likewise.
	* bash-completion/abinilint: Likewise.
	* bash-completion/abipkgdiff: Likewise.
	* bash-completion/abisym: Likewise.
	* bash-completion/fedabipkgdiff: Likewise.
	* configure.ac: Likewise.
	* default.abignore: Likewise.
	* doc/Makefile.am: Likewise.
	* doc/api/libabigail.doxy: Likewise.
	* doc/manuals/Makefile.am: Likewise.
	* doc/website/libabigail-website.doxy: Likewise.
	* include/Makefile.am: Likewise.
	* include/abg-comp-filter.h: Likewise.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-regex.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-version.h.in: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* scripts/dot_to_png.sh: Likewise.
	* scripts/dot_to_svg.sh: Likewise.
	* scripts/make-verbose.sh: Likewise.
	* scripts/svg_to_plain_svg.sh: Likewise.
	* scripts/svg_to_png_and_pdf.sh: Likewise.
	* src/Makefile.am: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-elf-helpers.cc: Likewise.
	* src/abg-elf-helpers.h: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-regex.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/Makefile.am: Likewise.
	* tests/data/Makefile.am: Likewise.
	* tests/lib/catch.cc: Likewise.
	* tests/mockfedabipkgdiff.in: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/runtestcanonicalizetypes.sh.in: Likewise.
	* tests/runtestdefaultsupprs.py.in: Likewise.
	* tests/runtestdefaultsupprspy3.sh.in: Likewise.
	* tests/runtestfedabipkgdiff.py.in: Likewise.
	* tests/runtestfedabipkgdiffpy3.sh.in: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-annotate.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-cxx-compat.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-dot.cc: Change the SPDX identifier from
	"GPL-3.0-or-later WITH GCC-exception-3.1" to "Apache-2.0 WITH
	LLVM-exception"
	* tests/test-elf-helpers.cc: Change the SPDX identifier from
	"LGPL-3.0-or-later" to "Apache-2.0 WITH LLVM-exception"
	* tests/test-ini.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-kmi-whitelist.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-svg.cc: Change the SPDX identifier from
	"GPL-3.0-or-later WITH GCC-exception-3.1" to "Apache-2.0 WITH
	LLVM-exception".
	* tests/test-symtab.cc: Change the SPDX identifier from
	"LGPL-3.0-or-later" to "Apache-2.0 WITH LLVM-exception"
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tests/update-test-output.py: Likewise.
	* tools/Makefile.am: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/fedabipkgdiff: Likewise.
	* tools/kmidiff.cc: Likewise.
	* update-copyright.sh: Likewise.

Signed-off-by: Benjamin De Kosnik <bkoz@gnu.org>
Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Jan Engelhardt <jengelh@inai.de>
Signed-off-by: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Matthias Klose <doko@ubuntu.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
Signed-off-by: Roland McGrath <roland@hack.frob.com>
Signed-off-by: Sinny Kumari <ksinny@gmail.com>
Signed-off-by: Slava Barinov <v.barinov@samsung.com>
2020-12-02 11:49:13 +01:00
Matthias Maennich
58488c5f31 Replace individual license references with SPDX Identifiers
This patch replaces license headers with SPDX identifiers in all files
containing license headers.  For each file, the SPDX identifier
formally represents its current license.  Note that the list of SPDX
identifiers is available on the SPDX web site at
https://spdx.org/licenses.

For autoconf-archive/ax_prog_python_version.m4 however, there is a
little catch.  Dodji Seketeli wrote this ax_check_python_modules.m4.
Just like the other autoconf-archive macros, it makes sense to have it
under the FSF All Permissive license.  Actually, the terms of that
license was already in the file but then the license header was
wrongly set to GPLv2 with autoconf exception.  So I fixed that in this
commit by setting the SPDX identifier to FSFAP.

	* abigail.m4: Replace the license header with the SPDX identifier
	GPL-3.0-or-later WITH GCC-exception-3.1
	* autoconf-archive/ax_check_python_modules.m4: Correctly set the
	SPDX identifier to FSFAP.
	* autoconf-archive/ax_compare_version.m4: Replace the license
	header with the SPDX identifier FSFAP.
	* autoconf-archive/ax_prog_python_version.m4: Likewise.
	header with the SPDX identifier FSFAP.
	* autoconf-archive/ax_valgrind_check.m4: Likewise.
	* gen-changelog.py: Replace the license header with the SPDX
	identifier LGPL-2.0-or-later.
	* include/abg-comp-filter.h: Replace the license header with the
	SPDX identifier LGPL-3.0-or-later.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-cxx-compat.h: Replace the license header with the
	SPDX identifier LGPL-2.0-or-later.
	* include/abg-diff-utils.h: Replace the license header with the
	SPDX identifier LGPL-3.0-or-later
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-regex.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* install-sh: Replace the license header with the SPDX identifier MIT.
	* ltmain.sh: Replace the license header with the SPDX identifier
	GPL-2.0-or-later.  Note that this file has the libtool special
	exception which allows us to redistribute it under the general
	license of the project.
	* src/abg-comp-filter.cc: Replace the license header with the SPDX
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-elf-helpers.cc: Likewise.
	* src/abg-elf-helpers.h: Likewise.
	* src/abg-regex.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-sptr-utils.cc: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/lib/catch.cc: Likewise.
	* tests/lib/catch.hpp: Add an SPDX identifier BSL-1.0.
	* tests/mockfedabipkgdiff.in: Replace the license header with the
	SPDX identifier GPL-3.0-or-later.
	* tests/print-diff-tree.cc: Likewise.
	* tests/runtestfedabipkgdiff.py.in: Replaace the license header
	with the SPDW identifier GPL-3.0-or-later.
	* tests/test-abicompat.cc: Replace the license header with the
	SPDX identifier LGPL-3.0-or-later.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-annotate.cc: Likewise.
	* tests/test-cxx-compat.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-dot.cc: Replace the license header with the
	SPDX identifier GPL-3.0-with-GCC-exception.
	* tests/test-elf-helpers.cc: Replace the license header with the
	SPDX identifier LGPL-3.0-or-later.
	* tests/test-ini.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-kmi-whitelist.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-svg.cc: Replace the license header with the SPDX
	identifier GPL-3.0-with-GCC-exception.
	* tests/test-symtab.cc: Replace the license header with the SPDX
	identifier LGPL-3.0-or-later.
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/fedabipkgdiff: Replace the license header with the
	SPDX identifier GPL-3.0-or-later.
	* tools/kmidiff.cc: Likewise.

Signed-off-by: Benjamin De Kosnik <bkoz@gnu.org>
Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Jan Engelhardt <jengelh@inai.de>
Signed-off-by: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Matthias Klose <doko@ubuntu.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
Signed-off-by: Roland McGrath <roland@hack.frob.com>
Signed-off-by: Sinny Kumari <ksinny@gmail.com>
Signed-off-by: Slava Barinov <v.barinov@samsung.com>
2020-12-02 11:44:13 +01:00
Dodji Seketeli
cac59a176a Bug 26769 - Fix missing types in abixml output
The symptom of the issue at hand is that sometimes there can be types
missing from the abixml output.  This happens when analysing some C++
code bases.

The core of the issue is the following.  Support we have a type
"struct S" defined somewhere as:

    struct S // #0
    {
      int  dm1;
      char dm2;
    };

    S s;

Suppose that in another translation unit, we have the class 'S' being
extended to add a member type to it:

    struct S // #1
    {
      typedef int dm1_type;
    };

    typedef S::dm1_type Integer;
    Integer something;

When emitting the abixml for the codebase, the definition of the
typedef S::dm1_type can be missing.

Note that in location #1, struct S is considered declaration-only.
It's definition is in another translation unit, in location #0.

So the abixml writer emits the 'struct S' defined in location #0, but
forgets to emit the 'struct S' in #1, which is indirectly used for the
sole purpose of using its member type S::dm1_type.

This patch emits the S::dm1_type type that is mistakenly forgotten
today.

Now that the "struct S" of #1 is also emitted, a tangent problem is
uncovered: S in #0 can be wrongly thought to be equivalent to S in #1,
for ABI purposes
This is because of an ODR-based optimization that is used for C++.
That is, the two struct S can be wrongly considered equivalent just
because they have the same name.  Note that ODR means "One Definition Rule[1]"

This patch removes the ODR-based optimization and thus fixes many of
the issues uncovered by the previous changes.

The patch also uncovered that some non-static variables were sometimes wrongly
being added to the set of exported variables, while libabigail reads
corpora from abixml.  The patch fixes this as well.

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

	* include/abg-corpus.h (corpus::{record_canonical_type,
	lookup_canonical_type}): Remove function declarations.
	* src/abg-corpus-priv.h (corpus::priv::canonical_types_): Remove
	data member.
	* src/abg-corpus.cc (corpus::{record_canonical_type,
	lookup_canonical_type}): Remove functions.
	* src/abg-ir.cc (type_eligible_for_odr_based_comparison): Remove
	static function.
	(type_base::get_canonical_type_for): Don't perform the ODR-based
	optimization for C++ anymore.
	* src/abg-reader.cc
	(read_context&::maybe_add_var_to_exported_decls): Don't add a
	variable that hasn't been added to its scope.  Otherwise, it means
	we added a variable that wasn't yet properly constructed.  Also
	add a new overload for var_decl_sptr&.
	(build_var_decl): Do not add the var to its the set of exported
	declaration before we are sure it has been fully constructed and
	added to the scope it belongs.
	(build_class_decl): Only add *static* data members to the list of
	exported declarations.
	(handle_var_decl): A var decl seen here is a global variable
	declaration.  Add it to the list of exported declarations.
	* src/abg-writer.cc (write_context::decl_only_type_is_emitted):
	Constify parameter.
	(write_translation_unit): Do not forget to emit referenced types
	that were maybe not canonicalized.  Also, avoid using noop_deleter
	when it's not necessary.
	(write_namespace_decl): Do not forget to emit canonicalized types
	that are present in namespaces other than the global namespace.
	* tests/runtestslowselfcompare.sh.in: New test that compares
	libabigail.so against its own ABIXML representation.
	* tests/Makefile.am: Add the new test runtestslowselfcompare.sh to
	source distribution.  This test is too slow to be run during the
	course of 'make check'.  It takes more than 5 minutes on my slow
	box here.  Rather, it can be run using 'make check-self-compare'.
	I plan to run this before releases now.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test0.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/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test0.abi: Likewise.
	* tests/data/test-read-dwarf/test0.hash.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/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Likewise.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Likewise.
	* tests/data/test-read-write/test6.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-11-23 13:02:34 +01:00
Dodji Seketeli
1d6731c438 Update copyright year to 2020
We are in February 2020 so this is long overdue.

	* include/abg-comp-filter.h: Update copyright year to 2020.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-cxx-compat.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-sptr-utils.cc: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-dot.cc: Likewise.
	* tests/test-ini.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-svg.cc: Likewise.
	* tests/test-tools-utils.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/kmidiff.cc: Likewise.
	* update-copyright.sh: Fix the updating script to handle not just
	"Red Hat, Inc."

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-02-21 17:05:01 +01:00
Dodji Seketeli
c32b8ec9f3 Bug 24690 - Support comparing non-reachable types of a binary
This patch adds the ability to compare all types of a binary,
including those types that are not reachable from global functions and
variables.

This implies that for types that are not reachable from public
interfaces, we want compare them against each others directly, without
first comparing global functions/variables and walking the graph of
reachable types from there.

The patch adds the --non-reachable-types option to abidiff and
abipkgdiff, instructing them to also compare types that are
non-reachable from global variables and functions.

Using that option, for instance, here is what the summary of
abipkgdiff now looks like, in the test case attached added by this
patch:

================ changes of 'libflatpak.so.0.10204.0'===============
  Functions changes summary: 0 Removed, 0 Changed (16 filtered out), 16 Added functions
  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
  Unreachable types summary: 3 removed (2 filtered out), 1 changed (15 filtered out), 3 added (1 filtered out) types

You can see that there is a new summary line which starts with the
string: "Unreachable types summary:"

Then in the body of the report, those unreachable types are reported
separately.

In practise, we want to limit the unreachable types to compare
somehow, otherwise we'll end up comparing all the types of the types
of the binary and that can be huge.  So we want to limit the
unreachable type analysis to types that are defined in public headers.

So, for abipkgdiff, one can limit the analysis of non-reachable types
to those defined in public headers by supplying the --devel{1,2}
options that specifies the development packages that contain said
public headers.  For abidiff however, you'll want to use the
--headers-dir{1,2} options for that.

The patch comes with appropriate regression tests.

	* include/abg-comparison.h (string_type_base_sptr_map): Define new
	typedef.
	(diff_context::show_unreachable_types): Declare new member
	functions.
	(corpus_diff::{deleted_unreachable_types,
	deleted_unreachable_types_sorted, added_unreachable_types,
	added_unreachable_types_sorted, changed_unreachable_types,
	changed_unreachable_types_sorted}): Likewise.
	(maybe_report_unreachable_type_changes): Declare this function a
	friend of class corpus_diff.
	(corpus_diff::diff_stats::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	net_num_added_unreachable_types, num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	net_num_removed_unreachable_types, num_changed_unreachable_types,
	num_changed_unreachable_types_filtered_out,
	net_num_changed_unreachable_types}): Likewise.
	* src/abg-comparison-priv.h
	(diff_context::priv::show_unreachable_types_): Define new data
	member.
	(diff_context::priv::priv): Initialize the new data member.
	(diff_comp::operator()): Use pretty representation of diff
	subjects to sort them, rather than just their name.  Also, add
	comment to the other member functions of diff_comp.
	(corpus_diff::{unreachable_types_edit_script_,
	deleted_unreachable_types_, deleted_unreachable_types_sorted_,
	suppressed_deleted_unreachable_types_, added_unreachable_types_,
	added_unreachable_types_sorted_,
	suppressed_added_unreachable_types_, changed_unreachable_types_,
	changed_unreachable_types_sorted_}): Define new data members.
	(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
	Changed the name of
	corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars into
	this.
	(corpus_diff::priv::{added_unreachable_type_is_suppressed,
	deleted_unreachable_type_is_suppressed,
	changed_unreachable_types_sorted, count_unreachable_types}):
	Declare new member functions.
	(corpus_diff::diff_stats::priv::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	num_changed_unreachable_types,
	num_changed_unreachable_types_filtered_out}): Define new data
	members.
	(sort_string_type_base_sptr_map): Declare new function.
	* src/abg-comparison.cc (sort_string_type_base_sptr_map)
	(diff_context::show_unreachable_types): Define new functions.
	(corpus_diff::diff_stats::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	net_num_added_unreachable_types,
	net_num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	num_removed_unreachable_types}): Define new member functions.
	(diff_maps::insert_diff_node): Do not update the map "diff ->
	impacted interfaces" if the current impacted interface is nil.
	This happens if we are looking at a diff node for a change on a
	type that is not reachable from any interfaces.
	(corpus_diff::priv::ensure_lookup_tables_populated): Handle the
	edit script for unreachable types.
	(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
	Rename
	corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars
	into this.  Apply suppression specifications to added and removed
	unreachable types as well.
	(corpus_diff::priv::{added,deleted}_unreachable_type_is_suppressed):
	Define new member functions.
	(corpus_diff::priv::{count_unreachable_types,
	changed_unreachable_types_sorted}): Likewise.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Update
	statistics (including walking changed unreachable types to apply
	categorization and redundancy filters to them) related to
	unreachable types.
	(corpus_diff::priv::emit_diff_stats): Emit diff stats related to
	unreachable types.
	(corpus_diff::priv::maybe_dump_diff_tree): Dump diff tree nodes
	related to unreachable types.
	(corpus_diff::{deleted_unreachable_types,
	deleted_unreachable_types_sorted, added_unreachable_types,
	added_unreachable_types_sorted, changed_unreachable_types,
	changed_unreachable_types_sorted): Define new member functions.
	(corpus_diff::has_changes): Take deleted/added/changed unreachable
	types into account.
	(corpus_diff::has_incompatible_changes): Take net removed/changed
	unreachable types into account.
	(corpus_diff::has_net_subtype_changes): Take net removed and
	changed unreachable types into account.
	(corpus_diff::has_net_changes): Take net removed/added/changed
	unreachable types into account.
	(corpus_diff::traverse): When traversing the components of a
	corpus_diff node, make sure to traverse the changed unreachable
	types of the corpus.
	(leaf_diff_node_marker_visitor::visit_begin): Arrange for the fact
	that the current topmost interface can be nil if we are looking at
	types not reachable from global functions/variables.  Also, make
	sure that only leaf nodes that are reachable from a global
	function/variable are recorded as leaf nodes.
	(compute_diff): In the overload for corpus_sptr, compute the
	changes between types not reachable from global functions and
	variables, if the user wishes that we do so.  Also, add more
	comments.
	(apply_suppressions): Update for the name change of the function
	apply_suppressions_to_added_removed_fns_vars to
	apply_supprs_to_added_removed_fns_vars_unreachable_types.
	* include/abg-corpus.h
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces,
	get_types_not_reachable_from_public_interfaces}): Declare new
	member functions.
	(corpus::recording_types_reachable_from_public_interface_supported):
	Declare new virtual member function.
	(corpus_group::get_public_types_pretty_representations): Declare
	new member functons.
	(corpus_group::recording_types_reachable_from_public_interface_supported):
	Declare new virtual member function.
	* src/abg-corpus-priv.h
	(corpus::priv::{types_not_reachable_from_pub_ifaces_,
	pub_type_pretty_reprs_}): Define new data members.
	(corpus::priv::priv): Initialize the pub_type_pretty_reprs_ data
	member because it's a pointer.
	(corpus::priv::get_public_types_pretty_representations): Declare
	new member function.
	(corpus::priv::~priv): Declare a destructor.
	* src/abg-corpus.cc
	(corpus::priv::get_public_types_pretty_representations): Define
	new member function.
	(corpus::priv::~priv): Define new destructor to delete the new
	pub_type_pretty_reprs_ member pointer.
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces,
	get_types_not_reachable_from_public_interfaces,
	recording_types_reachable_from_public_interface_supported}):
	Define new member functions
	(corpus_group::get_public_types_pretty_representations): Likewise.
	* include/abg-diff-utils.h (struct deep_ptr_eq_functor): Document
	the equality operator.  Also, add an overload to the equality
	operator, for weak_ptr<T>.  The existing equality operator
	overload was just for shared_ptr<T>.
	* include/abg-fwd.h (is_user_defined_type): Declare function.
	* include/abg-ir.h (operator!=(const decl_base_sptr&, const
	decl_base_sptr&)): Declare new operator.
	(type_maps::get_types_sorted_by_name): Declare
	new member function.
	(decl_base::{g,s}et_is_artificial): Declare new member function.
	(function_decl::parameter::{g,s}et_artificial): Remove these
	member functions.
	* src/abg-ir.cc (operator!=(const decl_base_sptr&, const
	decl_base_sptr&)): Define new operator.
	(decl_base::priv::is_artificial_): Define new data
	member.
	(type_maps::priv::sorted_types_): Define new data member.
	(struct type_name_comp): Define new comparison functor to sort
	types based on their pretty representations.
	(decl_base::priv::priv): Initialize it.
	(decl_base::{g,s}et_is_artificial): Define new member functions.
	(type_maps::get_types_sorted_by_name): Define new member function.
	(is_user_defined_type): Define new function overloads.
	(strip_typedef, function_type::{function_type, set_parameters}):
	Adjust using decl_base::get_is_artificial rather than
	function_decl::parameter::get_artificial.
	(function_decl::parameter::priv::artificial_): Remove this data
	member.
	(function_decl::parameter::priv::priv): Adjust to the removal of
	function_decl::parameter::priv::artificial_.  This constructor
	does not take an "is_artificial" flag anymore.
	(function_decl::parameter::parameter): Adjust to the removal of
	the is_artificial flag from the arguments of the constructor of
	function_decl::parameter::parameter::priv.
	(function_decl::parameter::get_artificial): Remove this member
	function.
	* src/abg-reporter-priv.h (maybe_report_unreachable_type_changes):
	Declare new function.
	* src/abg-reporter-priv.cc
	(maybe_report_unreachable_type_changes): Define new function.
	* src/abg-default-reporter.cc (default_reporter::report): In the
	overload for corpus_diff&, report added/removed/changed types that
	are not reachable from global functions and variables using the
	new function maybe_report_unreachable_type_changes.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
	overload for corpus_diff, report changes to types unreachable from
	global functions or variables, using the new function
	maybe_report_unreachable_type_changes.
	* src/abg-dwarf-reader.cc (build_ir_node_from_die): When the user
	requests that all types be loaded, record relevant types as
	reachable from global functions and variables.
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): Read the 'is-artificial' DWARF
	attribute and set the corresponding decl_base property
	accordingly.
	(finish_member_function_reading, strip_typedef)
	(function_type::function_type): Adjust using
	decl_base::get_is_artificial, rather than
	function_decl::parameter::get_artificial.
	* include/abg-reader.h
	(consider_types_not_reachable_from_public_interfaces): Declare new
	function.
	* src/abg-reader.cc
	(read_context::m_tracking_non_reachable_types): Add new data
	member.
	(read_context::read_context): Initialize it.
	(read_context::tracking_non_reachable_types): Define accessors for
	the new data member above.
	(read_is_declaration_only): Re-indent.
	(read_is_artificial): Define new helper function.
	(build_function_parameter): Use the new read_is_artificial
	function here, rather than open-coding it.
	(build_enum_type_decl, build_class_decl, build_union_decl):
	Support reading the 'is-artificial' property by using the new
	read_is_artificial function.
	(read_corpus_from_input): If the user wants us to take
	non-reachable types into account, then make sure we do so.
	(read_tracking_non_reachable_types, read_is_non_reachable_type):
	Define new static functions.
	(handle_element_node, build_type): Read the "is-non-reachable"
	attribute on type element nodes if the user wants us to track
	non-reachable types.
	(consider_types_not_reachable_from_public_interfaces): Define new
	function.
	* src/abg-writer.cc (write_is_artificial): Define new static
	helper function.
	(annotate): Adjust using decl_base::get_is_artificial rather than
	function_decl::parameter::get_artificial.
	(write_enum_type_decl, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Support writing the
	"is-artificial" property, using the new write_is_artificial
	function.
	(write_function_type): Adjust this to use the new
	write_is_artificial rather than open-coding writing the
	'is-artificial' attribute.
	(write_is_non_reachable)
	(write_tracking_non_reachable_types): Define new static functions.
	(write_enum_type_decl, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Write the 'is-no-reachable'
	attribute when applicable.
	(write_corpus, write_corpus_group): Write the
	'tracking-non-reachable-types' attribute when applicable.
	* tools/abidiff.cc (options::options): Initialize ...
	(options::show_all_types): ... new data member.
	(display_usage): Add help string from the new
	--non-reachable-types option.
	(parse_command_line): Parse the new --non-reachable-types option.
	(set_diff_context_from_opts): Set the
	dwarf_reader::read_context::show_unreachable_types property.
	(set_native_xml_reader_options): Define new
	static function.
	(main): Load all types when analyzing the DWARF or the ABIXML
	files, if the user wants us to do so.
	* tools/abipkgdiff.cc (options::show_all_types): Define new data
	member.
	(options::options): Initialize it.
	(parse_command_line): Parse the --non-reachable-types option to
	set the options::show_all_types data member.
	(display_usage): Add a help string for the new
	--non-reachable-types option.
	(set_diff_context_from_opts): Set the
	dwarf_reader::read_context::show_unreachable_types property based
	on the options::show_all_type data member.
	(compare): Configure the read context to load all types while
	analyzing the DWARF info, depending on the options::show_all_type
	data member.
	* doc/manuals/abidiff.rst: Document the new --non-reachable-types
	option added to abidiff above.
	* doc/manuals/abipkgdiff.rst: Add documentation for the
	--non-reachable-types option.
	* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.c:
	Source code files of test binary input.
	* tests/data/test-diff-suppr/test47-non-reachable-types-suppr-{1,2,3,4,5}.txt:
	New test input files.
	* tests/data/test-diff-suppr/test47-non-reachable-types-report-{1,2,3,4,5,6,7,8,9,10}.txt:
	New test reference output files.
	* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.o.alltypes.abixml:
	New test input abixml.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new tests above
	to this test harness.
	* tests/data/test-abidiff/test-struct1-report.txt: Adjust.
	* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.2.4-3.fc30.x86_64.rpm:
	New input binary RPM.
	* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/PR24690-report-0.txt: New test
	reference output.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test material
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-01-06 14:26:00 +01:00
Dodji Seketeli
400ac7a412 Implement fast comparison of Linux Kernel types when applicable
During type canonicalization there are observations that can speed-up
type comparison significantly without impacting correctness too much.

Typically, when two types are of the same name and kind, are found in
the same corpus and are defined in the same translation unit, they
ought to be the same type, even in C.  So there is no need in this
case to actually perform the structural comparison of the two types
which does have a quadratic performance at best.

Using this optimization made the loading of the
drivers/gpu/drm/i915/i915.ko module go from a quasi inifite time (many
hours on my system) to less than two minutes.  I am confining this
optimization to the Linux kernel case only for now, but I believe it
could benefit all C programs.  I am waiting for more testing before
applying it more broadly.

Also, while looking at this, I noticed that when loading several
corpora into a given corpus group (i.e, loading several linux kernel
binaries to represent a single conceptual kernel), we sometimes fail
to recognize that a type defined in a header file that is included in
several corpora is actually the same type, and should be re-used,
rather than being re-defined in each corpus.  This later adds stress
(time and space) on the system as we need to canonicalize and
de-duplicate these type later on.

This is because the "per-corpus" type maps that we use to lookup a
type by name and location when we see it (so that we know it's defined
in a different corpus of our current group) should really be
per-corpus-group type maps!  That is a type can be defined in the
corpus representing a .ko binary, and that type would be seen again in
another .ko binary later.  Until now, we were wrongly considering that
types were to be first defined in the corpus of the vmlinux binary,
and then could be re-used later.

I have thus fixed the code so that whenever we add a type to its
scope, the relevant per-corpus type maps are updated, as well as the
per-corpus-group ones, so that we can later lookup types in those
per-corpus-group type maps to know if a type is already defined in any
corpus of the group.

	* include/abg-corpus.h (corpus::origin): Add a new
	LINUX_KERNEL_BINARY_ORIGIN enumerator.
	(corpus::{s,g}et_group): Declare new member
	functions.
	(class corpus): Make the corpus_group class friend of this one.
	(corpus_group::get_main_corpus): Declare new member function.
	* src/abg-corpus-priv.h (corpus::priv::group): Define new data
	member.
	(corpus::priv::priv): Initialize the new corpus::priv::group data
	member.
	* src/abg-corpus.cc (corpus::{g,s}et_group): Define new member
	functions.
	(corpus_group::get_main_corpus): Likewise.
	(corpus_group::add_corpus): Use the new corpus::set_group() here
	to to make the corpus be aware of the group it belongs to.
	* src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Set the
	current corpus origin to the corpus::LINUX_KERNEL_BINARY_ORIGIN if
	we are looking at a Linux Kernel binary.
	(read_context::main_corpus_from_current_group): Use the
	corpus_group::get_main_corpus method.
	(should_reuse_type_from_corpus_group): Return the corpus group,
	rather than the main corpus.
	(read_debug_info_into_corpus): Add the current corpus to the
	current corpus group before the debug info reading is done.  That
	way, the corpus group will be accessible from the current corpus
	during the construction of the internal representation.
	(read_and_add_corpus_to_group_from_elf): Add the corpus to the
	group only if it wasn't added to it before.
	* include/abg-ir.h (operator{==,!=}): Declare new deep equality
	and inequality operators for class_or_union_sptr and
	union_decl_sptr.
	* src/abg-ir.cc (types_defined_same_linux_kernel_corpus_public):
	Define a new static function.
	(type_base::get_canonical_type_for): Use the new
	types_defined_same_linux_kernel_corpus_public here to speed up
	type comparison.
	(equals): In the overload of class_or_union, use the new
	types_defined_same_linux_kernel_corpus_public as well, to speed up
	type comparison.
	(operator{==,!=}): Define new deep equality and inequality
	operators for class_or_union_sptr and union_decl_sptr.
	(maybe_update_types_lookup_map): In the overload function for
	type_decl_sptr, class_decl_sptr, union_decl_sptr,
	enum_type_decl_sptr, typedef_decl_sptr, qualified_type_def_sptr,
	reference_type_def_sptr, array_type_def_sptr,
	array_type_def::subrange_sptr, and function_type_sptr, update the
	type lookup maps of the containing corpus group as well, not just
	the ones of the current corpus.
	* src/abg-reader.cc (build_enum_type_decl): Forgot to set the
	"is-anonymous" flag.  Oops, fix this.
	* 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-17 19:35:38 +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
Matthias Maennich via libabigail
704932b75a add missing virtual destructors
Several virtual desctructors were missing. Even though there might not
have been actual leaks or similar bugs, it is worth fixing these
locations as they might lead to bugs in the future.

Clang also warns at these locations:

  warning: delete called on non-final 'abigail::ir::corpus' that has virtual
  functions but non-virtual destructor [-Wdelete-non-virtual-dtor]

 * include/abg-comparison.h: add virtual destructor for corpus_diff and diff_node_visitor
 * include/abg-corpus.h: add virtual destructor for corpus
 * include/abg-reporter.h: add virtual destructor for reporter_base
 * include/abg-traverse.h: add virtual destructor for traversable_base

Signed-off-by: Matthias Maennich <maennich@google.com>
2019-04-16 16:11:01 +02:00
Dodji Seketeli
047342467c Update copyright for 2019
* include/abg-comp-filter.h: Update copyright for 2019
	* include/abg-comparison.h: Update copyright for 2019
	* include/abg-config.h: Update copyright for 2019
	* include/abg-corpus.h: Update copyright for 2019
	* include/abg-diff-utils.h: Update copyright for 2019
	* include/abg-dwarf-reader.h: Update copyright for 2019
	* include/abg-fwd.h: Update copyright for 2019
	* include/abg-hash.h: Update copyright for 2019
	* include/abg-ini.h: Update copyright for 2019
	* include/abg-interned-str.h: Update copyright for 2019
	* include/abg-ir.h: Update copyright for 2019
	* include/abg-libxml-utils.h: Update copyright for 2019
	* include/abg-libzip-utils.h: Update copyright for 2019
	* include/abg-reader.h: Update copyright for 2019
	* include/abg-reporter.h: Update copyright for 2019
	* include/abg-sptr-utils.h: Update copyright for 2019
	* include/abg-suppression.h: Update copyright for 2019
	* include/abg-tools-utils.h: Update copyright for 2019
	* include/abg-traverse.h: Update copyright for 2019
	* include/abg-viz-common.h: Update copyright for 2019
	* include/abg-viz-dot.h: Update copyright for 2019
	* include/abg-viz-svg.h: Update copyright for 2019
	* include/abg-workers.h: Update copyright for 2019
	* include/abg-writer.h: Update copyright for 2019
	* src/abg-comp-filter.cc: Update copyright for 2019
	* src/abg-comparison-priv.h: Update copyright for 2019
	* src/abg-comparison.cc: Update copyright for 2019
	* src/abg-config.cc: Update copyright for 2019
	* src/abg-corpus-priv.h: Update copyright for 2019
	* src/abg-corpus.cc: Update copyright for 2019
	* src/abg-default-reporter.cc: Update copyright for 2019
	* src/abg-diff-utils.cc: Update copyright for 2019
	* src/abg-dwarf-reader.cc: Update copyright for 2019
	* src/abg-hash.cc: Update copyright for 2019
	* src/abg-ini.cc: Update copyright for 2019
	* src/abg-internal.h: Update copyright for 2019
	* src/abg-ir-priv.h: Update copyright for 2019
	* src/abg-ir.cc: Update copyright for 2019
	* src/abg-leaf-reporter.cc: Update copyright for 2019
	* src/abg-libxml-utils.cc: Update copyright for 2019
	* src/abg-libzip-utils.cc: Update copyright for 2019
	* src/abg-reader.cc: Update copyright for 2019
	* src/abg-reporter-priv.cc: Update copyright for 2019
	* src/abg-reporter-priv.h: Update copyright for 2019
	* src/abg-sptr-utils.cc: Update copyright for 2019
	* src/abg-suppression-priv.h: Update copyright for 2019
	* src/abg-suppression.cc: Update copyright for 2019
	* src/abg-tools-utils.cc: Update copyright for 2019
	* src/abg-traverse.cc: Update copyright for 2019
	* src/abg-viz-common.cc: Update copyright for 2019
	* src/abg-viz-dot.cc: Update copyright for 2019
	* src/abg-viz-svg.cc: Update copyright for 2019
	* src/abg-workers.cc: Update copyright for 2019
	* src/abg-writer.cc: Update copyright for 2019
	* tests/print-diff-tree.cc: Update copyright for 2019
	* tests/test-abicompat.cc: Update copyright for 2019
	* tests/test-abidiff-exit.cc: Update copyright for 2019
	* tests/test-abidiff.cc: Update copyright for 2019
	* tests/test-alt-dwarf-file.cc: Update copyright for 2019
	* tests/test-core-diff.cc: Update copyright for 2019
	* tests/test-diff-dwarf-abixml.cc: Update copyright for 2019
	* tests/test-diff-dwarf.cc: Update copyright for 2019
	* tests/test-diff-filter.cc: Update copyright for 2019
	* tests/test-diff-pkg.cc: Update copyright for 2019
	* tests/test-diff-suppr.cc: Update copyright for 2019
	* tests/test-diff2.cc: Update copyright for 2019
	* tests/test-ini.cc: Update copyright for 2019
	* tests/test-ir-walker.cc: Update copyright for 2019
	* tests/test-lookup-syms.cc: Update copyright for 2019
	* tests/test-read-dwarf.cc: Update copyright for 2019
	* tests/test-read-write.cc: Update copyright for 2019
	* tests/test-types-stability.cc: Update copyright for 2019
	* tests/test-utils.cc: Update copyright for 2019
	* tests/test-utils.h: Update copyright for 2019
	* tests/test-write-read-archive.cc: Update copyright for 2019
	* tools/abiar.cc: Update copyright for 2019
	* tools/abicompat.cc: Update copyright for 2019
	* tools/abidiff.cc: Update copyright for 2019
	* tools/abidw.cc: Update copyright for 2019
	* tools/abilint.cc: Update copyright for 2019
	* tools/abipkgdiff.cc: Update copyright for 2019
	* tools/abisym.cc: Update copyright for 2019
	* tools/binilint.cc: Update copyright for 2019
	* tools/kmidiff.cc: Update copyright for 2019
	* update-copyright.sh: Update new year to 2019

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

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

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:36 +02:00
Dodji Seketeli
d198b27b64 Update copyright year on a bunch of files
* include/abg-corpus.h: Update copyright year to 2017.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidw.cc: Likewise.

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

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

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

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

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

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

This is the strategy implemented by this patch.

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

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

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

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
ccdc44b3eb Setup per-corpus type maps indexed by type names
This patch creates per-corpus maps that associate, for a certain kind
of type, the fully qualified name of the type to the type.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

I tested the patch on this command:

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

I whitnessed a x10 speedup, at least.

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

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-17 14:20:43 +01:00
Dodji Seketeli
48801d23e4 Bug 19037 - Make ABI corpus support several functions with same symbol
It turns out that, in DWARF, there can be function template
instantiations foo<int>(int) and foo<TypedefOfInt>(TypedefOfInt) which
have the same symbol name, if TypedefOfInt is a typedef of int.

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-06 13:32:12 +02:00
Dodji Seketeli
b2e5366d3f Introduce the concept of environment
There are resources needed by the type system and other artifacts of
libabigail.  Today, when the life time of those resources need to be
greater than all of artifacts of Abigail, then said resources are made
global.

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

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

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

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

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

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

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 23:35:29 +02:00
Dodji Seketeli
e5cf9d1f60 Consider default symbol versions when computing added/removed fns/vars
When computing the set of added function or variable symbols, if a
symbol S with no version symbol was present in a given corpus and that
symbol gained a *DEFAULT* version V in the second corpus, we should
not consider that a new symbol S was added (and that the former S was
removed) because:

  1/ S was already present in the first corpus
  2/ applications linked to the first corpus and that were using S
  (with no version) there, will automatically use the S with version V
  in the second corpus, without needing any re-linking; the
  power of symbol versioning!

Rather, it's just that S gained a default symbol version.

This patch implements that.

	* include/abg-corpus.h (corpus::{lookup_function_symbol,
	lookup_variable_symbol}): Take a elf_symbol::version object,
	rather than a string representing the version.  Add an overload
	that takes an elf_symbol.
	* src/abg-corpus.cc (find_symbol_by_version): New static function.
	(corpus::{lookup_function_symbol, lookup_variable_symbol}): Take a
	elf_symbol::version object, rather than a string representing the
	version.  Add an overload that takes an elf_symbol.  If the looked
	up symbol has no version and if the corpus contains a symbol with
	the same name and with a default version, then return that latter
	symbol if the corpus doesn't contain a symbol with the same name
	and empty version.
	* src/abg-comparison.cc
	(class_diff::ensure_lookup_tables_populated): Adjust.
	(corpus_diff::priv::ensure_lookup_tables_populated): Before
	deciding that a symbol has been added, if the symbol has a default
	version, make sure no symbol with the same name and without
	version was present in the former corpus.  Similarly, before
	deciding that a symbol has been removed, if the symbol has no
	version, make sure the latter corpus has no symbol with the same
	name and with a default version.
	* tests/data/test-diff-dwarf/test12-report.txt: Adjust.  The
	function should not be considered as added, because its symbol
	(and version) was already present in the former DSO.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-24 14:04:11 +02:00
Dodji Seketeli
dc2f054d03 Build the set of exported decls directly during DWARF loading
Until now, after the ABI corpus was built from DWARF, the translation
units of the corpus were walked and each function was considered for
addition into the set of exported decls.  During that walking, a first
version of the set was put into a std::list and then, a set of filters
(user-provided tunables like a list of regular expressions to keep or
remove some functions from the exported decls) is applied to that list
and the final set of exported decls is put in a std::vector.

Profiling has shown that this process of building the set of exported
decls is a hot spot and also that the current use of std::list was a
big memory consumer especially on binaries with large exported symbol
tables.

So this patch builds the set of exported decls "on the fly", during
DWARF reading, as opposed to waiting after the DWARF is read and
having to walk the corpus again.  The corpus defines a policy object
that encapsulates the methods for determining if a function or
variable ought to be part of the set of exported decls.  The DWARF
reader uses that policy object to determine which functions and
variables among those built during the reading ought be part of the
exported decls; the policy object also has a reference to the final
vector (managed by the corpus) that must hold the exported decls, so
the decls are put in that vector directly without unnecessary copying.

Profiling also showed that the string copying done by
{var_decl,function_decl}::get_id() was a hot spot.  So the patch
returns a reference there.

With this patch applied, the peak memory consumption of abidiff on
libabigail.so itself (abidiff libabigail.so libabigail.so) is 54MB of
resident and takes 2 minutes and 16s (on my slow system).  Without the
patch the peak consumption was more than 300MB and it was taking
slightly longer.

For the test of bug
https://sourceware.org/bugzilla/show_bug.cgi?id=17948, memory
consumtion and wall clock time spent is down from 3.4GB and 1m59s to
760MB and 0m43s.

	* include/abg-ir.h ({var,function}_decl::get_id): Return a
	reference.
	* src/abg-ir.cc ({var,function}_decl::get_id): Return a reference
	to the string rather than copying it over.
	* include/abg-corpus.h (class corpus::exported_decls_builder):
	Declare new type.
	(corpus::{sort_functions, sort_variables,
	maybe_drop_some_exported_decls, get_exported_decls_builder}):
	Declare new methods.
	* src/abg-corpus.h (corpus::exported_decls_builder::priv): Define
	new type.
	(class symtab_build_visitor_type): Remove this type that is
	useless now.
	(corpus::exported_decls_builder::{exported_decls_builder,
	exported_functions, exported_variables,
	maybe_add_fn_to_exported_fns, maybe_add_var_to_exported_vars}):
	Define new functions.
	(corpus::priv::is_public_decl_table_built): Remove this data
	member.  It's now useless.
	(corpus::priv::priv): Adjust.
	(corpus::priv::build_public_decl_table): Remove this member
	function.  It's now useless.
	(corpus::{priv::build_unreferenced_symbols_tables, get_functions,
	get_variables}): No need to build the public decls table here.
	It's already built by the time the corpus is read from DWARF now.
	(corpus::{sort_functions, sort_variables,
	maybe_drop_some_exported_decls, get_exported_decls_builder}):
	Define new member functions.
	* src/abg-dwarf-reader.cc (read_context::exported_decls_builder):
	New data member.
	(read_context::read_context): Initialize it.
	(read_context::{exported_decls_builder,
	maybe_add_fn_to_exported_fns, maybe_add_var_to_exported_vars}):
	Define new member functions.
	(read_debug_info_into_corpus): Get the the new
	'exported_decls_builder' object from the corpus and stick it into
	the read context so the DWARF reading code can use it to build the
	exported decls set.  When the DWARF reading is done, sort the set
	of exported functions and variables that was built.
	(build_ir_node_from_die): When a function or variable is built,
	consider putting it into the set of exported decls.
	* tools/abicompat.cc (main): Now that the exported decls is built
	*before* we had a chance to stick the list of symbol IDs to keep,
	call corpus::maybe_drop_some_exported_decls() to update the set of
	exported decls we should consider for the corpus.

was applied to that list and the final

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-24 13:15:10 +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
Dodji Seketeli
721728e7de Support reading and comparing soname from ELF files
Libabigail's DWARF reader doesn't read the DT_SONAME tag from the
.dynamic section.  The abigail::corpus type doesn't have a property
for that tag either.  And the comparison engine doesn't take that tag
in when comparing corpora.

This patch modifies the DWARF reader to read the DT_SONAME and
DT_NEEDED tags from the .dynamic section.  The value of DT_SONAME tag
is then saved in the new corpus property accessed by the new
abigail::corpus::get_soname() accessor.  The comparison engine has
also been modified to compare the sonames of two corpora being
compared.  Note that the value of the DT_NEEDED elf tag is saved in a
new corpus property that is accessed via the new
abigail::corpus::get_needed() getter.  This property is not used yet.

This patch also adds a unit test for this new feature.

	* include/abg-corpus.h (corpus::{get_needed, set_needed,
	get_soname, set_soname}): Declare new accessors.
	* src/abg-corpus.cc (corpus::priv::{needed, soname}): New data
	members.
	(corpus::{get_needed, set_needed, get_soname, set_soname}): Define
	new accessors.
	(corpus::is_empty): Take dt_needed and dt_soname in account in
	computing empty-ness.
	* src/abg-dwarf-reader.cc (read_context::{dt_needed_,
	dt_soname_}): New data members.
	(read_context::{dt_needed, dt_soname}): New accessors.
	(read_context::load_dt_soname_and_needed): New member function.
	(read_corpus_from_elf): Call the new
	read_context::load_dt_soname_and_needed() to read the dt_soname
	and dt_needed tags.  Set them to the corpus.
	* include/abg-comparison.h (diff_context::show_soname_change):
	Declare new accessors.
	* src/abg-comparison.cc (diff_context::priv::show_soname_change_):
	New data member.
	(diff_context::priv::priv): Initialize the new data member
	diff_context::priv::show_soname_change_.
	(diff_context::show_soname_change): Define new accessors.
	(corpus_diff::priv::sonames_equal_): New data member.
	(corpus_diff::priv::priv): Initialize the new data member
	corpus_diff::priv::sonames_equal_.
	(corpus_diff::length): Take the new priv_->sonames_equals_ data
	member in account.
	(corpus_diff::{report, priv::emit_diff_stats}): If the sonames
	changed and we are allowed to report it, then report it.
	(compute_diff): In the variant for corpus_diff, do not forget to
	compare the sonames.
	* src/abg-reader.cc (build_needed, read_elf_needed_from_input):
	Define new static functions.
	(read_corpus_from_input): Read the 'soname' attribute from the
	'abi-corpus' xml element node.
	* src/abg-writer.cc (write_elf_needed): Define new static
	function.
	(write_corpus_to_native_xml): Write a new 'elf-needed' xml element
	node that contains one xml 'dependency' element node per
	dependency to emit.  This uses the new write_elf_needed() function
	above.
	* tests/data/test-diff-dwarf/libtest19-soname-v0.so: New test
	input data.
	* tests/data/test-diff-dwarf/libtest19-soname-v1.so: Likewise.
	* tests/data/test-diff-dwarf/test19-soname-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test19-soname-v0.c: Source code of
	the first binary above.
	* tests/data/test-diff-dwarf/test19-soname-v1.c: Source code of
	the second binary above.
	* tests/test-diff-dwarf.cc (in_out_specs): Add the test input
	above to the list of test input to run this harness on.
	* tests/data/Makefile.am: Add the new test input data above.
	* tests/data/test-read-dwarf/test{0,1}.abi: Adjust.
	* tests/data/test-read-dwarf/test{2,3,4,6,}.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-07 23:42:26 +01:00
Dodji Seketeli
ef7e71febf Initial implementation of the abicompat tool
Given an application A that links to a shared library L of version V
denoted L(V) and a subsequent version of that library denoted L(V+P),
the 'abicompat' tool tells the user if L(V+P) is still ABI compatible
with L(V+P).  And if it is not, abicompat gives a reports that shows
the differences between L(V) and L(V+P) that makes L(V+P)
ABI-incompatible with A.

The source code of this tool is in the tools/abicompat.cc source
file.  To support this new tool, this commit changes the comparison
engine to optionally avoid showing added symbols that were not
referenced by any debug info.  It changes the ABI corpus type to allow
the specification of a list of variables and functions symbols to keep
(and drop all other functions and variables which have other symbols
on the floor even before starting to compare the two libraries).

This is how the abicompat tool itself works.  It basically compares
L(V) and L(V+P) but it only looks at their exported functions and
variables which symbols are undefined in application A.  If the list
of exported and defined variables and functions of L(V) whose symbols
are undefined in A equals that of L(V+P) (including the sub-types of
these variables and functions) A is still compatible with L(V+P).
Otherwise, they might not be compatible depending on the kind of
differences that are found.

	* include/abg-comparison.h
	(diff_context::show_added_symbols_unreferenced_by_debug_info):
	Declare new accessors.
	(corpus_diff::{deleted_variables,
	deleted_unrefed_function_symbols,
	deleted_unrefed_variable_symbols,
	apply_filters_and_suppressions_before_reporting}): Declare new
	methods.
	(corpus_diff::diff_stats): Declare this new type.  Actually this
	was previously corpus_diff::priv::diff_stats, which was a hidden
	internal type..  We are moving it here, in the external API so
	that client code can have more information about changes
	statistics.  Change all the previously publicly accessible data
	members into accessor functions.
	* src/abg-comparison.cc (class corpus_diff::diff_stats::priv): New
	type.
	(diff_context::priv::show_added_syms_unreferenced_by_di_): New
	data member.
	(diff_context::priv::priv): Adjust.
	(diff_context::show_added_symbols_unreferenced_by_debug_info):
	Define this new method.
	(corpus_diff::priv::emit_diff_stats):  Do not show the diff stat
	if the only changes is added function or variables symbols and if
	we were instructed to not show added symbols.
	(corpus_diff::priv::{diff_stats_, filters_and_suppr_applied_}):
	New data members.
	(corpus_diff::priv::priv): Initialize the
	filters_and_suppr_applied_ data member.
	(corpus_diff::priv::diff_stats): Move this type to
	corpus_diff::diff_stats.
	(corpus_diff::priv::{apply_filters_and_compute_diff_stats,
	emit_diff_stats}): Adjust.
	(corpus_diff::apply_filters_and_suppressions_before_reporting):
	Define new member function.
	(corpus_diff::report): Use the new
	apply_filters_and_suppressions_before_reporting() function, rather
	than applying the filters and suppressions by ourselves.  Also
	adjust to the use the accessors of the new corpus_diff::diff_stats
	type.
	(corpus_diff::{deleted_variables,
	deleted_unrefed_function_symbols,
	deleted_unrefed_variable_symbols}): Define new accessors.
	(corpus_diff::diff_stats::{diff_stats, num_func_removed,
	num_func_added, num_func_changed, num_func_filtered_out,
	net_num_func_changed, num_vars_removed, num_vars_added,
	num_vars_changed, num_vars_filtered_out, net_num_vars_changed,
	num_func_sym_removed, num_func_syms_added, num_var_syms_removed,
	num_var_syms_added}): Define new member functions.
	* include/abg-corpus.h (corpus::{get_sym_ids_of_fns_to_keep,
	get_sym_ids_of_vars_to_keep}): Declare new methods.
	* src/abg-corpus.cc (corpus::priv::{sym_id_fns_to_keep,
	sym_id_vars_to_keep}): Added data members.
	(symtab_build_visitor_type::{unrefed_fun_symbols,
	unrefed_var_symbols, sym_id_fns_to_keep, sym_id_vars_to_keep}):
	Added new data members.
	(symtab_build_visitor_type::symtab_build_visitor_type): Take two
	additional parameters for the function and variable symbol ids to
	keep.
	(symtab_build_visitor_type::add_fn_to_wip_fns): Take the function
	symbols to keep in account when building the exported symbol
	table.
	(symtab_build_visitor_type::add_var_to_wip_vars): Likewise, take
	the variable symbols to keep in account when building the exported
	symbol table.
	(corpus::priv::build_public_decl_table): Adjust the initialization
	of the visitor that walks the ABI artifacts to build the exported
	symbol table to know take a list of function/variable symbols to
	keep.
	(corpus::priv::build_unreferenced_symbols_tables): Ensure that the
	public table of functions/variables is built before doing the work
	of this function.  Also, if a list of variable/function symbols to
	keep is given, drop all symbols that are not in that list on the
	floor.
	(corpus::{get_sym_ids_of_fns_to_keep,
	get_sym_ids_of_vars_to_keep}): Define new accessors.
	* tools/abicompat.cc: New abicompat tool.
	* doc/manuals/abicompat.rst: New documentation source for
	abicompat.
	* doc/manuals/libabigail-tools.rst: Add an entry for the abicompat
	doc.
	* tests/test-abicompat.cc: New test harness for the 'abicompat'
	tool.
	* tests/Makefile.am: Build the runtestabicompat test harness and
	add it to the list of tests harnesses that are run by make check.
	* tests/data/test-abicompat/libtest0-fn-changed-libapp-v0.so: New
	test input.
	* tests/data/test-abicompat/libtest0-fn-changed-libapp-v1.so: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-0.suppr: Likewise
	* tests/data/test-abicompat/test0-fn-changed-report-0.txt: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-report-1.txt: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-app.cc: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-libapp.h: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-libapp-v0.cc: Likewise.
	* tests/data/test-abicompat/test0-fn-changed-libapp-v1.cc: Likewise.
	* tests/data/test-abicompat/libtest1-fn-removed-v0.so: Likewise.
	* tests/data/test-abicompat/libtest1-fn-removed-v1.so: Likewise.
	* tests/data/test-abicompat/test1-fn-removed-app: Likewise.
	* tests/data/test-abicompat/test1-fn-removed-app.cc: Likewise.
	* tests/data/test-abicompat/test1-fn-removed-report-0.txt: Likewise.
	* tests/data/test-abicompat/test1-fn-removed-v0.cc: Likewise.
	* tests/data/test-abicompat/test1-fn-removed-v1.cc: Likewise.
	* tests/data/test-abicompat/libtest2-var-removed-v0.so: Likewise.
	* tests/data/test-abicompat/libtest2-var-removed-v1.so: Likewise.
	* tests/data/test-abicompat/test2-var-removed-app: Likewise.
	* tests/data/test-abicompat/test2-var-removed-app.cc: Likewise.
	* tests/data/test-abicompat/test2-var-removed-report-0.txt: Likewise.
	* tests/data/test-abicompat/test2-var-removed-v0.cc: Likewise.
	* tests/data/test-abicompat/test2-var-removed-v1.cc: Likewise.
	* tests/data/test-abicompat/libtest3-fn-removed-v0.so: Likewise.
	* tests/data/test-abicompat/libtest3-fn-removed-v1.so: Likewise.
	* tests/data/test-abicompat/test3-fn-removed-app: Likewise.
	* tests/data/test-abicompat/test3-fn-removed-app.cc: Likewise.
	* tests/data/test-abicompat/test3-fn-removed-report-0.txt: Likewise.
	* tests/data/test-abicompat/test3-fn-removed-v0.cc: Likewise.
	* tests/data/test-abicompat/test3-fn-removed-v1.cc: Likewise.
	* tests/data/test-abicompat/test3-fn-removed-version-script-0 Likewise.:
	* tests/data/test-abicompat/test3-fn-removed-version-script-1: Likewise.
	* tests/data/Makefile.am: Add the new test inputs above to the
	source distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-05 15:43:31 +01:00
Dodji Seketeli
06279598c8 Support reading undefined symbols from an ELF file
In preparation to support the upcoming 'abicompat' tool, we need the
ABI corpus type to capture the symbols that are undefined in a given
ELF file.

This patch changes the ELF reader to capture the undefined symbols as
well as the symbol versions they need to be satisfied.  These
undefined symbols are then stored in the instance ABI corpus build as
a result of the reading of the ELF file.

At the moment, these undefined symbols are not serialized to the
native XML format of libabigail yet.  I guess I'll do that in a
subsequent patch.

	* include/abg-corpus.h (corpus::{set_undefined_fun_symbol_map,
	set_undefined_var_symbol_map, get_undefined_fun_symbol_map_sptr,
	get_undefined_fun_symbol_map, get_sorted_undefined_fun_symbols,
	get_undefined_var_symbol_map_sptr, get_undefined_var_symbol_map,
	get_sorted_undefined_var_symbols}): Declare new methods ...
	* src/abg-corpus.cc (corpus::{set_undefined_fun_symbol_map,
	set_undefined_var_symbol_map, get_undefined_fun_symbol_map_sptr,
	get_undefined_fun_symbol_map, get_sorted_undefined_fun_symbols,
	get_undefined_var_symbol_map_sptr, get_undefined_var_symbol_map,
	get_sorted_undefined_var_symbols}): ... and define them.
	(struct corpus::priv::{undefined_var_symbol_map,
	sorted_undefined_var_symbols, undefined_fun_symbol_map,
	sorted_undefined_fun_symbols}): New data members.
	* src/abg-dwarf-reader.cc (get_symbol_versionning_sections): Also
	return the SHT_GNU_verneed section.
	(get_version_needed_for_versym): New static function.
	(get_version_definition_for_versym): Factorize this function out
	of ..
	(get_version_for_symbol): ... this one.  Take a flag that says if
	we want the definition version or the needed version of a symbol.
	Extend the implementation using the two new function
	get_version_needed_for_versym() and
	get_version_definition_for_versym() above.  This function now
	returns the version either for a defined & exported symbol, or for
	an undefined symbol.
	(lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab):
	Adjust for the change of signature of get_version_for_symbol().
	(read_context::{undefined_fun_syms_, undefined_var_syms_}): New
	data members.
	(read_context::lookup_elf_symbol_from_index): Adjust for
	invocation of the new signature of get_version_for_symbol().
	(read_context::{undefined_fun_syms_sptr, undefined_fun_syms,
	undefined_var_syms_sptr, undefined_var_syms}): Define new methods.
	(read_context::load_symbol_maps): Add support for loading
	undefined symbols and their versions.
	(read_context::maybe_load_symbol_maps):  Take in account the need
	to load undefined symbols as well.
	(read_corpus_from_elf): Once the undefined symbols have been read
	from the ELF file, stuff them into the resulting ABI corpus that
	has been built.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-11-30 19:57:05 +01:00
Dodji Seketeli
d6bba81ac0 Update the copyright years of include/abg-corpus.h
* include/abg-corpus.h: Update the copyright years of this file.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-11-30 19:57:04 +01:00
Dodji Seketeli
0dd5f64279 Sort elf symbols before serializing them
* include/abg-corpus.h (corpus::{get_sorted_fun_symbols,
	get_sorted_var_symbols}): Declare new member functions.
	* src/abg-corpus.cc (corpus_priv::{sorted_var_symbols,
	sorted_fun_symbols}): New data members.
	(struct elf_symbol_comp_functor): Define new comparison functor.
	(corpus::{get_sorted_fun_symbols, get_sorted_var_symbols}): Define
	new member functions.
	* src/abg-writer.cc (write_elf_symbols_table): Take a sorted
	vector of symbols in parameters, rather than an unsorted map.
	(write_corpus_to_native_xml): Write a sorted vector of symbols,
	rather than an unsorted map of symbols.
	* tests/data/test-read-dwarf/test0.abi: Adjust.
	* tests/data/test-read-dwarf/test1.abi: Likewise.
	* tests/data/test-read-dwarf/test2.so.abi: Likewise.
	* tests/data/test-read-dwarf/test3.so.abi: Likewise.
	* tests/data/test-read-dwarf/test6.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-11-08 11:22:43 +01:00
Dodji Seketeli
f44110b326 Support comparing symbols not referenced by debug info
* doc/manuals/abidiff.rst: Adjust intro to mention that w/o debug
	info, abidiff now works but just report about added/removed
	symbols.  Add documentation about the new
	--no-unreferenced-symbols option.
	* include/abg-comparison.h (string_elf_symbol_map): New typedef.
	(diff_context::show_symbols_unreferenced_by_debug_info): Declare
	new accessors.
	* src/abg-comparison.cc
	(diff_context::priv::show_syms_unreferenced_by_di_): New data
	member.
	(diff_context::priv::priv): Adjust.
	(diff_context::show_symbols_unreferenced_by_debug_info): Implement
	these accessors.
	(corpus_diff::priv::{unrefed_fn_syms_edit_script_,
	unrefed_var_syms_edit_script_, added_unrefed_fn_syms_,
	deleted_unrefed_fn_syms_, added_unrefed_var_syms_,
	deleted_unrefed_var_syms_}): New data members.
	(corpus_diff::priv::diff_stats::{num_func_syms_removed,
	num_func_syms_added, num_var_syms_removed, num_var_syms_added}):
	New data members.
	(corpus_diff::priv::diff_stats::diff_stats): Adjust.
	(corpus_diff::ensure_lookup_tables_populated): Populate lookup
	tables for added/removed symbols that are not referenced by any
	debug info.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Compute
	stats for the added/removed symbols not referenced by any debug
	info.
	(corpus_diff::priv::emit_diff_stats): Emit stats about
	added/removed symbols that are not referenced by any debug info.
	(corpus_diff::length): Adjust to take in account added/removed
	symbols not referenced by any debug info.
	(show_linkage_name_and_aliases): New static function.
	(corpus_diff::report): When emitting a symbol name, emit its
	version too, and tell if it aliases other symbols.  Avoid emitted
	extra new lines.  Report added/removed symbols not referenced by
	any debug info.
	(compute_diff): In the overload for corpus_sptr, compute the diffs
	for symbols not referenced by debug info.
	* include/abg-corpus.h
	(corpus::get_unreferenced_{function,variable}_symbols): Declare
	new member functions.
	* src/abg-corpus.cc (corpus_priv::{unrefed_fun_symbols,
	unrefed_var_symbols}): New data members.
	(corpus_priv::build_unreferenced_symbols_tables): Define new
	member function.
	(struct comp_elf_symbols_functor): New functor.
	(corpus::is_empty): Adjust to take in account added/removed
	symbols not referenced by debug info.
	(corpus::{get_unreferenced_function_symbols,
	corpus::get_unreferenced_variable_symbols}): Define these
	accessors.
	* include/abg-dwarf-reader.h (enum status): Transform this into
	bitfields.  Add a STATUS_UNKNOWN value that has the value 0.
	(operator|(status, status), operator&(status, status))
	(operator|=(status&, status), operator&=(status, status)): New
	bit-wise operators to manipulate instances of the status bit-field.
	* src/abg-dwarf-reader.cc (get_version_for_symbol): Fix this to
	avoid returning garbage version sometimes.
	(read_debug_info_into_corpus): Fix this to return a non-null but
	empty corpus_sptr when there is no debug info available.
	(operator|(status, status), operator&(status, status))
	(operator|=(status&, status), operator&=(status, status)): Define
	these new bitwise operators to manipulate instances of the status
	bit-field.
	(read_corpus_from_elf): Now that the abigail::dwarf_reader::status
	is a bit-field, set it to reflect if debug info and/or symbol
	tables have been found.  Do not bail out if debug info hasn't been
	found.  Rather, keep going, and go look for symbols-only; this is
	a kind of operating in degraded mode.
	* include/abg-ir.h (elf_symbol::get_aliases_id_string): Add a flag
	that says if the current instance of elf_symbol should be included
	in the list of aliases or not.
	* src/abg-ir.cc (elf_symbol::get_aliases_id_string): Define it.
	* tests/data/test-diff-dwarf/test16-syms-only-v{0,1}.o: New test
	input.
	* tools/abidiff.cc
	(options::show_symbols_not_referenced_by_debug_info): New data
	member.
	(options:options): Adjust.
	(display_usage): Add an info string for the new
	--no-unreferenced-symbols command line option.
	(parse_command_line): Parse the new --no-unreferenced-symbols
	command line.
	(set_diff_context_from_opts): Set the diff_context according to
	the presence of --no-unreferenced-symbols.
	(main): Adjust for the fact that abigail::dwarf_reader::status is
	now a bit-field.
	* tools/abilint.cc (main): Adjust for the fact that
	abigail::dwarf_reader::status is now a bit-field..
	():
	* tests/data/test-diff-dwarf/test16-syms-only-report.txt: New test
	reference output.
	* tests/data/test-diff-dwarf/test16-syms-only-v{0,1}.cc: Source code
	for new test input.
	* tests/data/test-diff-dwarf/test17-non-refed-syms-v{0,1}.o: New
	test input.
	* tests/data/test-diff-dwarf/test17-non-refed-syms-v{0,1}.cc: New
	source code for test input.
	* tests/data/test-diff-dwarf/libtest18-alias-sym-v{0,1}.so: New
	test input.
	* tests/data/test-diff-dwarf/test18-alias-sym-report-0.txt:
	Reference output for new test input.
	* tests/data/test-diff-dwarf/test18-alias-sym-v{0,1}.cc: Source
	code for new test input.
	* tests/data/test-diff-dwarf/test18-alias-sym-version-script:
	Source code for new test input.
	* tests/Makefile.am: Add the new test materials to the source
	distribution.
	* tests/test-diff-dwarf.cc(in_out_specs): Add the new input tests
	above to the array of tests to run by this harness.
	(main): Emit empty reports for empty resulting diffs.
	* tests/data/test-diff-dwarf/test{0,8,9,12,14-inline-report,}-report.txt:
	Adjust.
	* tests/data/test-diff-filter/test{0,01,2,4,5,7,8,9,10,12,13,15-0,15-1}-report.txt:
	Likewise.
	* tests/data/test-diff-filter/test{19-enum,20-inline,}-report-0.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-{1,2}.txt:
	Likewise.
	* tests/data/test-diff-suppr/test{1,2}-typedef-suppr-report-1.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-22 23:04:40 +02:00
Dodji Seketeli
fccc516656 Put IR artifacts in the abigail::ir namespace
* include/abg-fwd.h: Wrap IR artifacts into abigail::ir namespace.
	Inject that new abigail::ir namespace into the abigail namespace.
	* include/abg-ir.h: Wrap IR artifacts into abigail::ir namespace.
	(function_decl::parameter::get_type_name): Adjust the call to
	abigail::get_type_name.  It's now a call to
	abigail::ir::get_type_name.
	* src/abg-ir.cc: Wrap IR artifacts into abigail::ir namespace.
	* include/abg-traverse.h: Wrap the ir traversing artifact into the
	abigail::ir namespace too.
	* src/abg-traverse.cc: Adjust.
	* include/abg-corpus.h: Wrap corpus type stuff into abigail::ir.
	* include/abg-dwarf-reader.h: Inject namespace abigail::ir stuff
	into the abigail::dwarf_reader namespace.
	* include/abg-reader.h: Inject namespace abigail::ir stuff into
	the abigail::xml_reader namespace.
	* src/abg-reader.cc: Adjust.
	* include/abg-writer.h: Inject namespace abigail::ir stuff into
	the abigail::xml_writer namespace.
	* src/abg-writer.cc: Inject namespace abigail::ir stuff into
	abigail namespace here too.
	* src/abg-hash.cc: Inject the abigail::ir namespace into the
	abigail namespace.
	* tools/abg-tools-utils.cc: Adjust for the injection of
	abigail::function_decl. It's now abigail::ir::function_decl.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-13 17:44:43 +02:00