416 Commits

Author SHA1 Message Date
lizhenlin a506c1d186 update version to 2.8
Signed-off-by: lizhenlin <lizhenlin2@h-partners.com>
2025-11-13 14:39:47 +08:00
hosted d85c7a46b4 libabigail changed its static library dependency on libxml2 to a dynamic library dependency.
https://gitcode.com/openharmony/third_party_libabigail/issues/22

Signed-off-by: hosted <chenyadong18@huawei.com>
2025-11-10 11:55:31 +08:00
王佳栋 5bcc524117 Signed-off-by: 王佳栋 <wangjiadong14@huawei.com>
update version
2024-12-21 14:59:35 +08:00
zhanghaibo fbbf953d71 use header of elfutils in third_party
Signed-off-by: zhanghaibo <zhanghaibo0@huawei.com>
Change-Id: I7664b4cd4f33d1523a23c7c21a9d0d542497f5b7
2023-03-08 15:06:26 +08:00
zhanghaibo 3cf1e522c9 fix review issue
Signed-off-by: zhanghaibo <zhanghaibo0@huawei.com>
2023-03-01 15:25:05 +08:00
zhanghaibo ee499fa04b add notice
Signed-off-by: zhanghaibo <zhanghaibo0@huawei.com>
2023-02-27 20:26:21 +08:00
zhanghaibo 2d2ba37b34 build libabigail
Signed-off-by: zhanghaibo <zhanghaibo0@huawei.com>
2023-02-27 11:23:55 +08:00
Dodji Seketeli d222b44733 dwarf-reader: Leverage ODR & DWZ
When DWARF debug info has been preprocessed with the DWZ tool, I think
we can assume that if two DIEs originating from the .gnu_debugaltlink
section have different offset, it means they are different, even if
they represent two types of the same nature and of the same name.
This is the whole point of DWZ.

When we process two DIEs originating from C++, it's possible "in
general" to assume that the One Definition Rule is in effect, meaning
that if two types of the same nature have the same name, they ought to
represent the same entity, meaning, they are the same type.

These two observations can lead to faster comparison of two aggregate
types of the same nature and of the same name.

This patch implements these two optimizations and use them by
default.

The first one is used by default on binaries that contains a
.gnu_debugaltlink section, which is the hint we use to detect that DWZ
was used to factorize DWARF DIEs.

The second of is used by default on DWARF DIEs originating from C++.

These optimizations can be de-activated on abidw and abidiff using the
--no-leverage-dwarf-factorization and --no-assume-odr-for-cplusplus.

	* doc/manuals/abidiff.rst: Add documentation for
	--no-leverage-dwarf-factorization and
	--no-assume-odr-for-cplusplus
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-fe-iface.h (options::{leverage_dwarf_factorization,
	assume_odr_for_cplusplus}): New data members.
	* src/abg-dwarf-reader.cc (reader::leverage_dwarf_factorization_):
	New data member.
	(reader::leverage_dwarf_factorization): New accessor.
	(compare_dies): If we are allowed to leverage the DWARF
	factorization and if two type DIEs coming from the
	.gnu_debugaltlink DWARF section have different offset, then they
	are different.  Also, if we are allowed to assume ODR, use it to
	speed up class/struct/unions comparisons.
	* tools/abidiff.cc (options::{assume_odr_for_cplusplus,
	leverage_dwarf_factorization}): Define new data members.
	(options::options): Initialize them.
	(display_usage): Add new help strings for
	--no-leverage-dwarf-factorization and
	--no-assume-odr-for-cplusplus.
	(parse_command_line): Parse these new options.
	(set_generic_options): New function.
	(main): Use the new set_generic_options function.
	* tools/abidw.cc (options::{assume_odr_for_cplusplus,
	leverage_dwarf_factorization}): Define new data members.
	(options::options): Initialize them.
	(display_usage): Add new help strings for
	--no-leverage-dwarf-factorization and
	--no-assume-odr-for-cplusplus.
	(parse_command_line): Parse these new options.
	(set_generic_options): New function.
	(load_corpus_and_write_abixml): Use the new set_generic_options
	function.
	* tools/abipkgdiff.cc (options::{assume_odr_for_cplusplus,
	leverage_dwarf_factorization}): Define new data members.
	(options::options): Initialize them.
	(display_usage): Add new help strings for
	--no-leverage-dwarf-factorization and
	--no-assume-odr-for-cplusplus.
	(parse_command_line): Parse these new options.
	(set_generic_options): New function.
	(compare): Use it.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-11-30 17:17:15 +01:00
Guillermo E. Martinez 8fd02e0a10 Use the CTF reader by default when applicable
At the moment, the tools abidw, abidiff, abipkgdiff and kmidiff all
use the DWARF front-end by default.  When the "--ctf" option is added
to the command line, they use the CTF front-end.

This patch changes that behaviour in the way described below.

If the "--ctf" command line option is passed to the tool and if the
binary to analyze contains CTF debug info, then the CTF front-end is
used.

If the binary contains ONLY CTF debug info, then the CTF front-end is
used, even if no "--ctf" option was provided.

In all the other cases, the DWARF front-end is used.

Of course, the CTF front-end is not used at all if the CTF
functionality hasn't been enabled at configure time.

This new behaviour is effective for user space and Linux kernel
binaries.

	* doc/manuals/abidiff.rst: Adjust.
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* doc/manuals/kmidiff.rst: Likewise.
	* include/abg-elf-based-reader.h (initialize): Add member function.
	* include/abg-elf-reader.h (has_{dwarf,ctf}_debug_info): Add predicate
	functions.
	* include/abg-tools-utils.h (create_best_elf_based_reader): Add arguments.
	* src/abg-ctf-reader.cc (process_ctf_typedef, process_ctf_base_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):
	Remove arguments. Using getters to access required information instead.
	(reader::cur_tu_): Add data member.
	(initialize): Add arguments.
	(cur_transl_unit): Add {get,set)ter.
	(slurp_elf_info): Clear `STATUS_DEBUG_INFO_NOT_FOUND' if corpus is
	`LINUX_KERNEL_BINARY_ORIGIN'.
	(reader::lookup_type): Remove.
	(reader::build_type): New member function.
	* src/abg-elf-reader.cc (reader::reader): Locate ctf debug info
	from binary file.
	(reader::reader): Reset base `fe_iface' constructor.
	(reader::has_{dwarf,ctf}_debug_info): New definitions.
	(reader::read_corpus): Set `STATUS_DEBUG_INFO_NOT_FOUND' according
	to corpus::origin.
	* src/abg-tools-utils.cc (dir_contains_ctf_archive): Define new member.
	(file_has_ctf_debug_info): Looks for kernel ctf debug information archive.
	(maybe_load_vmlinux_{dwarf,ctf}_corpus): Remove.
	(load_vmlinux_corpus): Define function to load IR from kernel
	regardless of the corpus::origin.
	(build_corpus_group_from_kernel_dist_under): Use
	create_best_elf_based_reader to select the front-end.
	(create_best_elf_based_reader): Adjust to allow fallback behaviour
	for different front-ends.
	* tests/data/Makefile.am: Add tests.
	* tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt: Adjust.
	* tests/data/test-read-ctf/test-fallback.abi: New test case.
	* tests/data/test-read-ctf/test-fallback.c: Likewise.
	* tests/data/test-read-ctf/test-fallback.o: Likewise.
	* tests/data/test-read-dwarf/test-fallback.abi: Likewise.
	* tests/data/test-read-dwarf/test-fallback.c: Likewise.
	* tests/data/test-read-dwarf/test-fallback.o: Likewise.
	* tests/test-diff-pkg.cc: Adjust.
	* tests/test-read-common.cc (test_task::run_abidw): Use the
	`options:option' field.
	* tests/test-read-common.h (InOutSpec): Add new member.
	* tests/test-read-ctf.cc (in_out_specs): Add option field to test
	suite.  Add new test case.
	* tests/test-read-dwarf.cc: Likewise.
	* tools/abidiff.cc (main): Use create_best_elf_based_reader.
	* tools/abidw.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-11-28 16:52:33 +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::elf::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::elf::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::elf::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::elf::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 94ff477b31 kmidiff: Fix spacing in the help string
* tools/kmidiff.cc (display_usage): Fix spacing.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-11-08 11:34:19 +01:00
Dodji Seketeli 5eaeddc943 abidiff: add a --debug-tc option
Like what was done for abidw, this patch adds a --debug-tc option to
abidiff to debug type canonicalization issues.

With this option, just like for abidw, during type canonicalization,
each type comparison is done twice: once using structural comparison
and once using canonical comparison.  Both comparisons should yield
the same result otherwise, an abort signal is emitted, asking for
in-depth debugging to understand reason of the difference.

This option is enabled by the configure option
--enable-debug-type-canonicalization.

It proved useful in debugging some comparison errors I was looking at
recently.

	* doc/manuals/abidiff.rst: Add documentation for the new
	--debug-tc option.  Fix the existing documentation for
	--debug-self-comparison.
	* tools/abidiff.cc (options::do_debug_self_comparison): Renamed
	options::do_debug into this.
	(options::do_debug_type_canonicalization): Add new data member.
	(display_usage): Fix help string for the --debug option that is
	now --debug-self-comparison.  Also, add a help string for the new
	option --debug-tc option.
	(main): Adjust use options::do_debug into
	options::do_debug_self_comparison.  Call
	environment::debug_type_canonicalization() if the user provided
	the --debug-tc option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-10-07 22:50:14 +02:00
Dodji Seketeli 755dfdb21c Allow restricting analyzed decls to exported symbols
Profiling showed that the DWARF reader scans too much data.

Basically, in build_translation_unit_and_add_to_ir,
build_ir_node_from_die is called on every single DIE that is seen, for
a given translation unit.

There are interfaces (function and variable decls) that are not
associated with exported ELF symbols and that are analyzed by
build_ir_node_from_die nonetheless.  For instance, interfaces that are
visible outside of their translation units are analyzed and the types
that are reachable from those interfaces are analyzed as well.

Once that is done, an ABI corpus is built with the subset of
interfaces that have exported ELF symbol (strictly those that are part
of the ABI), but types that are not necessarily reachable from those
ABI interfaces can also be put into the ABI corpus.

Some tools make use of this "lose" behaviour of libabigail.  For
instance, abicompat precisely wants to analyze interfaces with
undefined symbols.  For an application, those interfaces represents
the interfaces that the application expects to be provided by some
shared library.

When analyzing the exported interface of the Linux Kernel (or any
other huge application) however, analyzing more types than necessary
appears to incur a huge time penalty.

So, this patch introduces an optional behaviour whereby
build_translation_unit_and_add_to_ir is restricted to analyzing
interfaces that have exported ELF symbols only.  So only the types
reachable from those interfaces are analyzed.  This more than halves
the time spent by "abidw --noout vmlinux".

Strictly speaking, this new behaviour is triggered by a new option named
--exported-interfaces-only, supported by the tools abidw, abidiff,
abipkgdiff and kmidiff.

When looking at the Linux Kernel however, this option is enabled by
default.

Note that an option --allow-non-exported-interfaces is also introduce
to function under the previous model of operations.  This option is
enabled by default on all the tools when they are not looking at the
Linux Kernel.

With this enabled, analyzing the Linux Kernel is back to taking less
than a minute on a reasonable machine.

	* doc/manuals/tools-use-libabigail.txt: New doc text.
	* doc/manuals/Makefile.am: Add the new tools-use-libabigail.rst
	tool to the source distribution.
	* doc/manuals/abidiff.rst: Include the new
	tools-use-libabigail.rst.  Document the --exported-interfaces-only
	and --allow-non-exported-interfaces.
	* doc/manuals/abidw.rst: Likewise.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* doc/manuals/kmidiff.rst: Likewise.
	* include/abg-ir.h
	(environment::{user_set_analyze_exported_interfaces_only,
	analyze_exported_interfaces_only}): Declare new accessors.
	* src/abg-ir.cc
	(environment::{user_set_analyze_exported_interfaces_only,
	analyze_exported_interfaces_only}): Define new accessors.
	* src/abg-dwarf-reader.cc (die_is_variable_decl)
	(die_is_function_decl): Define new static functions.
	(read_context::is_decl_die_with_exported_symbol): Define new
	member function.
	(read_context::get_{function,variable}_address): Const-ify the
	Dwarf_Die* parameter.
	(build_translation_unit_and_add_to_ir): If the user asks to
	analyze exported interfaces only,  the analyze only interfaces
	that have exported ELF symbols.
	(read_debug_info_into_corpus): If we are looking at the Linux
	Kernel, then only analyze exported interfaces unless the user asks
	otherwise.
	* src/abg-ir-priv.h
	(environment::priv::analyze_exported_interfaces_only_): Define new
	data member.
	* tools/abidiff.cc (options::exported_interfaces_only): Define new
	data member.
	(display_usage): Add new help strings for
	--exported-interfaces-only and --allow-non-exported-interfaces.
	(parse_command_line): Parse the new options
	--exported-interfaces-only and --allow-non-exported-interfaces.
	(main): Pass the value of opts.exported_interfaces_only to the
	environment.
	* tools/abidw.cc (options::exported_interfaces_only): Define new
	data member.
	(display_usage): Add new help strings for
	--exported-interfaces-only and --allow-non-exported-interfaces.
	(parse_command_line): Parse the new options
	(load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml): Pass the value of
	opts.exported_interfaces_only onto the environment.
	* tools/abipkgdiff.cc (options::exported_interfaces_only): Define new
	data member.
	(display_usage): Add new help strings for
	--exported-interfaces-only and --allow-non-exported-interfaces.
	(parse_command_line): Parse the new options
	(compare_task::perform, self_compare_task::perform): Pass the
	value of opts.exported_interfaces_only onto the environment.
	(compare_prepared_linux_kernel_packages): Likewise.
	* tools/kmidiff.cc(options::exported_interfaces_only): Define new
	data member.
	(display_usage): Add new help strings for
	--exported-interfaces-only and --allow-non-exported-interfaces.
	(parse_command_line): Parse the new options
	(main): Pass the value of opts.exported_interfaces_only onto the
	environment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-09-20 11:43:32 +02:00
Guillermo E. Martinez via Libabigail 68f369f218 kmidiff: Add CTF support to comparing Kernel trees
This patch adds a new --ctf option to kmidiff to make it support CTF
type information when analysing Linux Kernel trees.

	* doc/manuals/kmidiff.rst: Add documentation for the new --ctf option.
	* tools/kmidiff.cc (options::use_ctf): Define new data member.
	(display_usage): Add a help string for the --ctf option.
	(main): Adjust call to pass
	build_corpus_group_from_kernel_dist_under with origin being
	corpus::CTF_ORIGIN when the user provides the --ctf option.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-07-08 10:20:34 +02: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
Dodji Seketeli b9c73978ed abidw, dwarf-reader: Add an option to debug DIE canonicalization
While looking at something else, it appeared that I needed an option
to turn on checks to debug DIE canonicalization.  That option would
itself be enable only when the project is configured using the
--enable-debug-type-canonicalization configure option.

	* include/abg-ir.h
	(environment::debug_die_canonicalization_is_on): Declare new methods.
	* src/abg-ir.cc (environment::debug_die_canonicalization_is_on):
	Define them.
	* src/abg-dwarf-reader.cc
	(compare_dies_during_canonicalization): Define new static
	function.
	(read_context::{debug_die_canonicalization_is_on_,
	use_canonical_die_comparison_}): Declare these data members.
	(read_context::read_context): Initialize them.
	(read_context::get_canonical_die): When ODR is considered, if DIE
	canonicalization debugging is on, use the new
	compare_dies_during_canonicalization for the type comparison to be
	done both structurally and canonically; both comparison should
	yield the same result.  Also, make this method function non-const.
	* src/abg-ir-priv.h
	(environment::priv::debug_die_canonicalization_): Define new data
	member.
	(environment::priv::priv): Initialize it.
	* tools/abidw.cc (options::debug_die_canonicalization_): Define
	new data member.
	(options::options): Initialize it.
	(display_usage): Add a description for the --debug-dc option.
	(parse_command): Parse the new --debug-dc option.
	(load_corpus_and_write_abixml): Use the new
	environment::debug_die_canonicalization_is_on.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-06-20 17:19:27 +02:00
Dodji Seketeli e8a012b6e1 abicompat: Properly guard inclusion of abg-ctf-reader.h
A recent patch to add CTF support to abicompat included
abg-ctf-reader.h without guarding it with #ifdef WITH_CTF.  This patch
fixes that.

	* tools/abicompat.cc: Guard inclusion of abg-ctf-reader.h with
	#ifdef WITH_CTF.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-06-09 12:20:19 +02:00
Ben Woodard via Libabigail 57a5ce73cf abicompat: Support reading CTF and abixml
While abidw generates abidw and abidiff can consume that abidw
abicompat could only read from ELF objects with DWARF. To bring it in
line with the capabilities of abidiff, this patch adds the ability for
abicompat to read both abixml and CTF. The reason why being able to
handle abixml as well as an ELF file with DWARF is that it allows
someone to archive the abixml for an object and use it in place of
having to keep the entire object when doing abi compatibility studies.

The ability to handle CTF was also in the code that I copied over from
abidiff and so I brought it over at the same time. This should be
tested more extensively. The make check works and a trivial test using
the same object seems to work but I do not have any CTF other binaries
around to test against.

Also a feature that I asked for a long time ago was to fail if the
binaries don't have debug infomation which is needed for proper
comparison. This was added to abidiff but it didn't get added to
abicompat. Since the code was in the same area, I copied it over from
abidiff at the same time.

I do not think it makes sense to try to split these three features
apart because they are just replicating pre-existing code in a
different tool.

	* tools/abicompat.cc (options::{fail_no_debug_info, use_ctf}): New
	data members.
	(options::options): Initialize them.
	(display_usage): Add a help string for the new options
	--fail-no-debug-info and --ctf.
	(parse_command_line): Support parsing the new options
	--fail-no-debug-info and --ctf.
	(read_corpus): New static function.
	(main): Use the new read_corpus in lieu of using
	dwarf_reader::read_corpus_from_elf and/or  ctf_reader::read_corpus
	and/or xml::reader::read_corpus_from_input.
	* doc/manuals/abicompat.rst: add documentation for new options.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-06-08 17:13:14 +02:00
Ben Woodard ebf8f98f3d abidiff: Remove redundant code
While working on abicompat, I noticed that the following two blocks of
code are redundant. They perform the same test as in the switch
statement a few lines below.

	* tools/abidiff.cc (main): Remove redundant code.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-06-07 15:50:49 +02:00
Ben Woodard bb935f6219 abicompat: Add missing space
This is absolutely trivial but I noticed this missing space one day
and fixed it and have been carrying the hunk of patch for months.

	* tools/abicompat.cc (main): Add missing space in expression.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-06-07 15:11:00 +02:00
Guillermo E. Martinez 1ebd5ff0eb ctf-reader: add support to looking debug information in external path
When an ELF `stripped' file is used to get CTF debug information the ELF
symbols used by ctf reader (`symtab_reader::symtab') is split in a
separate file and even though CTF was designed to be in ELF file after
be `stripped' this .ctf section can be 'loaded'  from and external
.debug file, for instance the script `find-debuginfo' used to generate
RPM debug packages split debug information in .debug files. The location
of such files is pass as a standard argument from libabigail tools and
the name of the file is gathering from the `.gnu_debuglink' section.

	* include/abg-ctf-reader.h (ctf_reader::create_read_context):
	Add `debug_info_root_paths' argument.
	(ctf_reader::reset_read_context): Likewise.
	* src/abg-ctf-reader.cc: Add `read_context::elf_{handler,fd}_dbg',
	data members.
	(read_context::read_context): Add new `debug_info_root_paths'
	argument.
	(read_context::initialize): Likewise.
	(ctf_reader::create_read_context): Likewise.
	(ctf_reader::close_elf_handler): Release
	`read_context::elf_{handler,fd}_dbg' members.
	(ctf_reader::find_alt_debuginfo): Add new function.
	(ctf_reader::slurp_elf_info): Add new argument `status'. Use
	`find_alt_debuginfo' and `elf_helpers::find_section_by_name'
	to read the symtab and ctf information from an external .debug
	file, the `status' reference is updated.
	(ctf_reader::read_corpus): Verify `status' after `slurp_elf_info'.
	(ctf_reader::reset_read_context): Add new `debug_info_root_path'
	argument.
	* src/abg-elf-helpers.cc (elf_helpers::find_section_by_name): Update
	comment.
	* src/abg-tools-utils.cc (maybe_load_vmlinux_ctf_corpus):
	Adjust `ctf_reader::{create,reset}_read_context'.
	* tests/test-read-ctf.cc: Likewise.
	* tools/abidiff.cc (display_usage): Add `--ctf' command line
	option.
	(main): Adjust `ctf_reader::create_read_context'.
	Likewise.
	* tools/abidw.cc (load_corpus_and_write_abixml): Adjust
	`ctf_reader::create_read_context'.
	* tools/abilint.cc (main): Likewise.
	* tools/abipkgdiff.cc (compare, compare_to_self): Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-05-17 15:44:15 +02:00
Guillermo E. Martinez 28a629347f abipkgdiff: Add support to compare packages with CTF debug format
This patch add support in `abipkgdiff' to compare binaries with CTF
debug information inside of packages, when `--ctf' option is provided.

	* tools/abipkgdiff.cc: Include `abg-ctf-reader.h'.
	(options::use_ctf): Add new data member.
	(display_usage): Add `--ctf' usage.
	(compare): Add condition to use ctf-reader to extract
	(parse_command_line): Set `options::use_ctf' when --ctf
	option is provided.
	and build CTF corpora when `options::use_ctf' is set.
	(compare_to_self): Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-05-16 18:07:40 +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
vsoch 707e47f4ce Add Logic to detect file type by extension
Fedabipkgdiff uses mimetypes to detect what file type it is looking
at. In some minimal versions of the OS, in particular container
images, the package that includes all the mimetypes may not be
installed. This allows fedabipkgdiff to fall back to using the
extension.

    * tools/fedabipkgdiff - add logic to detect file type by extension

Signed-off-by: vsoch <vsoch@users.noreply.github.com>
Reviewed-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-05-12 12:10:15 +02:00
Ben Woodard c7a71ba2d1 Add an option ignore SONAME differences in libraries
There are rare use cases where we do not want to compare the SONAME when
testing libraries for compatiblity or diffing libraries. This adds an
option to ignore the SONAME when doing the comparison. In these cases,
we will edit the application's DT_NEEDED to point to the other library.

This reuses the show_soname_change() function and slightly changes its
meaning to not only control if the sonames are printed but also if
they are compared. There didn't seem to be any other users of this
function and slight semantic change seemed harmless.

	* doc/manuals/abicompat.rst - added new option
	* doc/manuals/abidiff.rst - added new option to manpage
	* src/abg-comparison.cc (compute_diff): don't bother comparing the
	sonames if you aren't going to print them.
	* tools/abicompat.cc (options::ignore_soname): Add new data
	member.
	(parse_command_line): Support the new --ignore-soname command line
	option.
	(display_usage): Add a description string for the new
	--ignore-soname command line option.
	(create_diff_context): Set the diff_context::show_soname_change
	from the new options::ignore_soname data member.
	* tools/abidiff.cc (options::ignore_soname): Add new data member.
	(display_usage): Add a description string for the new
	--ignore-soname command line option.
	(parse_command_line): Support the new --ignore-soname command line
	option.
	(set_diff_context_from_opts): Set the
	diff_context::show_soname_change from the new
	options::ignore_soname.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-05-12 11:58:18 +02:00
Dodji Seketeli 1eb3dc84f7 abilint --show-type-use: Show results for global decls that have no symbols
In some abixml file, there can be global decls that don't have ELF
symbols.  We still want to see how those decls use the type that is
being used, as analyzed by abilint --show-type-use <type-id>.

	* include/abg-fwd.h (is_at_global_scope): Declare ...
	* src/abg-ir.cc (is_at_global_scope): ... new overload.
	* tools/abilint.cc (emit_artifact_use_trace): Emit the trace also
	when the decl is at global scope or has a linkage name.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-02-28 17:30:04 +01:00
Dodji Seketeli 1483f6cb49 abilint: add the --show-type-use option
"abilint --show-type-use <type-id> <abixml-file>" is a facility that
shows how a type defined in an abixml file is used.  That is, it emits
a textual representation of how the use a type is used up until the
function or global variable that constitutes an entry point in the API
corpus.  Here is an example of its use:

    test-read-write$ abilint --noout --show-type-use type-id-5 test17.xml
    Type ID 'type-id-5' is for type 'enum E'
    The usage graph for that type is:
    | -> enum E -> E S::m2 -> class S -> S* -> method void S::S()
    | -> enum E -> E S::m2 -> class S -> S* -> method void S::__base_ctor ()
    | -> enum E -> E S::m2 -> class S -> S* -> method void S::__comp_ctor ()
    | -> enum E -> E S::m2 -> class S -> S* -> method void S::S(S&)
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> method void S::S(S&)
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> S var
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::S()
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::__base_ctor ()
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::__comp_ctor ()
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::S(S&)
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> S& -> method void S::S(S&)
    | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> S& -> S var
    $

The screenshot above should be self explanatory.

This facility is useful to analyse type usage and find potential
issues in how libabigail represents some types.

To activate this feature, one needs to configure the package with the
configure option "--enable-show-type-use-in-abilint".

	* configure.ac: Define the --enable-show-type-use-in-abilint
	configure option.  It defines the WITH_SHOW_TYPE_USE_IN_ABILINT
	macro.
	* include/abg-reader.h (read_translation_unit): Add an overload
	that takes the read context.
	(get_types_from_type_id, get_artifact_used_by_relation_map):
	Declare new functions.
	* src/abg-reader.cc (get_types_from_type_id)
	(get_artifact_used_by_relation_map): Declare these functions as
	friend of the read_context type.
	(read_context::m_artifact_used_by_map):
	(read_context::key_type_decl): Replace the shared_ptr<type_base>
	type of the first parm by the equivalent type_base_sptr type.
	(read_context::{record_artifact_as_used_by,
	record_artifacts_as_used_in_fn_decl,
	record_artifacts_as_used_in_fn_type}): Add new methods guarded by
	the WITH_SHOW_TYPE_USE_IN_ABILINT macro.
	(get_types_from_type_id, get_artifact_used_by_relation_map): Define
	new functions guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro.
	(read_translation_unit): Define new overload.
	(RECORD_ARTIFACT_AS_USED_BY, RECORD_ARTIFACTS_AS_USED_IN_FN_DECL)
	(RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE): Define new macros.
	(build_function_decl, build_var_decl, build_qualified_type_decl)
	(build_pointer_type_def, build_reference_type_def)
	(build_function_type, build_array_type_def, build_enum_type_decl)
	(build_typedef_decl, build_class_decl, build_union_decl): Use the
	macros above to mark the relevant sub-types as used by the
	artifact being built.
	* tools/abilint.cc (struct artifact_use_relation_tree): Define new
	type, guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro.
	(fill_artifact_use_tree, build_type_use_tree, emit_trace)
	(emit_artifact_use_trace, emit_artifact_use_trace)
	(show_how_type_is_used): Define static functions guarded by the
	WITH_SHOW_TYPE_USE_IN_ABILINT macro.
	(display_usage): Add doc string for the --show-type-use option,
	guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro.
	(parse_command_line): Parse the --show-type-use option, guarded by
	the WITH_SHOW_TYPE_USE_IN_ABILINT macro.
	(main): Slight re-organisation to make the abixml file reading use
	a read_context.  That read context is then used to analyze how a
	given type is used whenever the --show-type-use option is used.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-02-28 10:24:46 +01:00
David Seifert 1198798985 Find fts-standalone on musl
When using the musl C library fts is optional.  So we need to detect
its presence by looking at the fts-standalone pkgconfig module.

This patch does that.

This comes from Gentoo bug https://bugs.gentoo.org/831571

	* configure.ac: Invoke AC_CANONICAL_HOST to compute the host_cpu,
	host_vendor, host_os parts of the 'host" variable.  Then if the
	host_os ends up with "musl" then, check for the fts-standalone
	pkgconfig module and record the fts library into
	FTS_{LIBS,CFLAGS}.
	* src/Makefile.am: Link to $FTS_LIBS and use $FTS_CFLAGS for
	compilation.
	* tools/Makefile.am: Likewise.
	* tools/abisym.cc: Include libgen.h
	* tools/kmidiff.cc: Remove useless fts.h header file.

Signed-off-by: David Seifert <soap@gentoo.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2022-02-07 16:26:30 +01:00
Giuliano Procida eab1463fea abidiff: include ABI XML versions when reporting a mismatch cont.
This fixes a copy/paste error in function documentation.

	* tools/abidiff.cc
	(emit_incompatible_format_version_error_message): Fix
	parameter documentation.

Fixes: b251bc611e ("abidiff: include ABI XML versions when reporting a mismatch")
Signed-off-by: Giuliano Procida <gprocida@google.com>
2022-01-18 17:59:04 +01:00
Giuliano Procida b251bc611e abidiff: include ABI XML versions when reporting a mismatch
In the rare event of an XML version mismatch it would be helpful to
have the versions in the error message, particularly if abidiff is
being run from automation.

	* tools/abidiff.cc
	(emit_incompatible_format_version_error_message): Add version1
	and version2 arguments. Add versions to error message.
	(main): Pass emit_incompatible_format_version_error_message
	mismatching versions.

Signed-off-by: Giuliano Procida <gprocida@google.com>
2022-01-18 17:10:03 +01:00
David Cantrell 069ead6b55 Include <libgen.h> in tools/abisym.cc for basename(3)
Support building on non-glibc systems, such as musl, by including
libgen.h for basename(3).

Signed-off-by: David Cantrell <dcantrell@redhat.com>
2022-01-17 14:32:33 +01:00
Thomas Schwinge 968fe8c013 fedabipkgdiff: Also accept MIME type 'application/x-redhat-package-manager' for RPM files
... as that's what a few Debian and Ubuntu systems are using, that I just
sampled:

    $ awk '$2 ~ /rpm/' < /etc/mime.types
    application/x-redhat-package-manager            rpm
    $ dpkg -S /etc/mime.types
    media-types: /etc/mime.types
    $ apt policy media-types
    media-types:
      Installed: 4.0.0
      Candidate: 4.0.0
      Version table:
     *** 4.0.0 900
            900 http://ftp.de.debian.org/debian testing/main amd64 Packages
            900 http://ftp.de.debian.org/debian testing/main i386 Packages
            800 http://ftp.de.debian.org/debian unstable/main amd64 Packages
            800 http://ftp.de.debian.org/debian unstable/main i386 Packages
            100 /var/lib/dpkg/status

    $ awk '$2 ~ /rpm/' < /etc/mime.types
    application/x-redhat-package-manager            rpm
    $ dpkg -S /etc/mime.types
    mime-support: /etc/mime.types
    $ apt policy mime-support
    mime-support:
      Installed: 3.64ubuntu1
      Candidate: 3.64ubuntu1
      Version table:
     *** 3.64ubuntu1 500
            500 http://de.archive.ubuntu.com/ubuntu focal/main amd64 Packages
            500 http://de.archive.ubuntu.com/ubuntu focal/main i386 Packages
            100 /var/lib/dpkg/status

    $ awk '$2 ~ /rpm/' < /etc/mime.types
    application/x-redhat-package-manager		rpm
    $ dpkg -S /etc/mime.types
    mime-support: /etc/mime.types
    $ apt-cache policy mime-support
    mime-support:
      Installed: 3.54ubuntu1.1
      Candidate: 3.54ubuntu1.1
      Version table:
     *** 3.54ubuntu1.1 0
            500 http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
            500 http://us.archive.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
            100 /var/lib/dpkg/status
         3.54ubuntu1 0
            500 http://us.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages

Otherwise, 'is_rpm_file' fails, resulting in a few test cases failing with an
unhelpful 'Unknown arguments. Please refer to --help.' message (similar to what
had been observed in PR22077 "runtestfedabipkgdiff.py fails on centos-x86_64").

	* tools/fedabipkgdiff (is_rpm_file): Also accept MIME type
	'application/x-redhat-package-manager' for RPM files.

CC: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Thomas Schwinge <thomas@codesourcery.com>
2021-12-21 14:54:46 +01:00
Thomas Schwinge feb441e284 fedabipkgdiff: Enable testing without proper Koji installation
... as is now documented in 'CONTRIBUTING'.

	* tools/fedabipkgdiff: Handle 'koji.ConfigurationError'.
	* configure.ac: Likewise.
	* CONTRIBUTING: Document "fedabipkgdiff testing".

Documenting/providing a way to enable such testing, this commit can be
considered a sequel to commit 90d236a033
"Bug 22076 - Disable fedabipkgdiff for old koji clients", for Mark Wielaard's
PR22076 "runtestfedabipkgdiff.py fails on debian-amd64".

Signed-off-by: Thomas Schwinge <thomas@codesourcery.com>
2021-12-20 17:31:27 +01:00
Thomas Schwinge daf38b8231 abipkgdiff: Use 'convert_path_to_relative' in 'create_abi_file_path'
... instead of open-coding it, insufficiently.

On one system, I have a '/home' -> 'media/[...]/home' symlink, so:

    $ readlink -f /home/thomas/.cache
    /media/[...]/home/thomas/.cache

Now:

    Thread 4 "abipkgdiff" hit Breakpoint 1, package::create_abi_file_path (this=0x5555555a7990,
        elf_file_path="/media/[...]/home/thomas/.cache/libabigail/abipkgdiff-tmp-dir-upGgLK/package1/usr/lib64/libGLU.so.1.3.1", abi_file_path="") at [...]/tools/abipkgdiff.cc:668
    668       create_abi_file_path(const string &elf_file_path,
    (gdb) n
    671         string abi_path, dir, parent;
    (gdb) n
    672         if (!abigail::tools_utils::string_suffix(elf_file_path,
    (gdb) n
    675           return false;

So we unexpectedly 'return false' here.  That's because of 'elf_file_path' as
above ('realpath'ed) vs. 'extracted_dir_path()' as follows (not 'realpath'ed):

    (gdb) print extracted_dir_path()
    $1 = "/home/thomas/.cache/libabigail/abipkgdiff-tmp-dir-upGgLK/package1"

Avoid that by just using 'convert_path_to_relative' here.

(I did not generally review the code for other such problems...)

	* tools/abipkgdiff.cc (create_abi_file_path): Use
	'convert_path_to_relative'.

Signed-off-by: Thomas Schwinge <thomas@codesourcery.com>
2021-12-20 16:42:13 +01:00
Thomas Schwinge 0e38678cfa abipkgdiff: Respect 'create_abi_file_path' interface
Currently we may run into this:

    [...]
    abipkgdiff: Could not create the directory tree to store the abi for '[...]'
    abipkgdiff: Writting ABIXML file '' ...
    abipkgdiff: Wrote ABIXML file '' OK
    abipkgdiff: Reading ABIXML file '' ...
    abipkgdiff: Could not read temporary ABIXML file ''
    ==== Error happened during self check of '[...]' ====
    [...]

That is, after a failed 'create_abi_file_path', we proceed with an empty
'abi_file_path' -- because that one only gets set "iff the function return
true".  So we ought to 'return abigail::tools_utils::ABIDIFF_ERROR' in that
case.

(It's likewise strange why 'create_write_context'/'write_corpus' succeed with
an empty 'abi_file_path', but that's for another day...)

	* tools/abipkgdiff.cc (compare_to_self): Respect
	'create_abi_file_path' interface.

Signed-off-by: Thomas Schwinge <thomas@codesourcery.com>
2021-12-20 15:53:14 +01:00
Guillermo E. Martinez via Libabigail b5a914c208 ctf-reader: Use ABG_ASSERT instead of assert
* tools/abidiff.cc (main): Use ABG_ASSERT instead of assert.
	* tools/abilint.cc: Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
2021-11-23 15:36:06 +01:00
Guillermo E. Martinez via Libabigail 7f60fbc96b ctf-reader: Make create_read_context return a smart pointer.
* include/abg-ctf-reader.h (read_context_sptr): New typedef.
	(create_read_context): Use read_context_sptr as return value.
	(read_corpus): New overload that takes a read_context_sptr.
	* src/abg-ctf-reader.cc (create_read_context): Use
	read_context_sptr as return value.
	(read_corpus): New overload that takes a read_context_sptr.
	* tools/abidiff.cc (main): Use read_context_sptr.
	* tools/abidw.cc (load_corpus_and_write_abixml): Adjust call to
	create_read_context.
	* tools/abilint.cc: Likewise.

Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-23 15:25:05 +01:00
Jose E. Marchesi via Libabigail 18569fc154 abidw: add support for CTF
This patch adds support for CTF to the abidw utility.  It depends on
the previous patch that makes abigail::ctf_reader::read_corpus to
return a status code.

	* tools/abidw.cc: Conditionally include abg-ctf-reader.h.
	(load_corpus_and_write_abixml): Do not get a
	dwarf_reader::read_context as an argument.
	(main): Adjust call to load_corpus_and_write_abixml accordingly.
	(struct options): New option use_ctf.
	(options): ... and initialize it.
	(display_usage): Document --ctf.
	(parse_command_line): Handle --ctf.
	* doc/manuals/abidw.rst: Document --ctf.

Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-18 09:51:06 +01:00
Jose E. Marchesi via Libabigail 8324a223df ctf: ctf_reader::read_corpus now sets a status
This patch makes ctf_reader::read_corpus to get a reference to a
`status' variable as an argument, and set it to reflect the result of
the read operation.  The utilities calling to ctf_reader::read_corpus
are updated accordingly.

	* include/abg-ctf-reader.h: Include abg-elf-reader-common.h.
	read_corpus now gets an extra argument `status'.
	* src/abg-ctf-reader.cc (read_corpus): Likewise, and set `status'
	accordingly when the debug info is not found.
	* tools/abilint.cc (main): Pass a status argument to
	ctf_reader::read_corpus.
	* tools/abidiff.cc (main): Likewise.

Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-17 17:55:53 +01:00
Jose E. Marchesi via Libabigail ddad560153 Move dwarf_reader::status facilities to an abigail::elf_reader namespace
The DWARF reader is no longer the only ELF-based reader in libabigail:
the CTF reader also operates on ELF files.  Other ELF-based formats
(such as BTF) may also join in the future.  These readers share a lot
of similarities: they all operate on object files, they fetch
debugging information from certain sections, they rely on the symtab
of the read object, the debugging info may be in a separated file (for
certain formats) and so on.

It follows that a lot of logic can be shared among all the ELF-based
readers.  This patch is oriented to that direction.

A new namespace, abigail::elf_reader, is introduced with the goal of
holding features and definitions useful for any ELF-based abigail
reader.  Then all the definitions related to the status resulting from
extracting a corpus from an object file (the dwarf_reader::status) are
moved to abigail::elf_reader.  The utilities and tests are adjusted
accordingly.

Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>

	* include/abg-reader-common.h: New file.
	* include/abg-dwarf-reader.h (enum status): Move to
	abg-reader-status.h.
	(status_to_diagnostic_string): Likewise.
	(operator|): Likewise.
	(operator&): Likewise.
	(operator|=): Likewise.
	(operator&=): Likewise.
	Include abg-reader-common.h.
	* include/Makefile.am (pkginclude_HEADERS): Add
	abg-elf-reader-common.h.
	* src/abg-elf-reader-status.cc: New file.
	* src/abg-dwarf-reader.cc (operator|): Move to
	abg-elf-reader-common.cc.
	(operator&): Likewise.
	(operator|): Likewise.
	(operator|=): Likewise.
	(operator&=): Likewise.
	(status_to_diagnostic_string): Likewise.
	* src/Makefile.am (libabigail_la_SOURCES): Add
	elf-reader-common.cc.
	* src/abg-tools-utils.cc: Use abigail::elf_reader instead of
	abigail::dwarf_reader for the status definitions.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-symtab.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-15 11:08:53 +01:00
Dodji Seketeli 522cc62b9b abidw: Add --abixml-version
Add a command line option to display the version number of the ABIXML
output format.

	* doc/manuals/abidw.rst: Document the --abixml-version command
	line option.
	* configure.ac (ABIXML_VERSION_MAJOR, ABIXML_VERSION_MINOR):
	Define these two new autoconf variables.
	* include/abg-config.h (abigail_get_abixml_version): Declare new
	function.
	* include/abg-tools-utils.h (get_abixml_version_string): Declare
	new function.
	* include/abg-version.h.in (ABIGAIL_ABIXML_VERSION_MAJOR)
	(ABIGAIL_ABIXML_VERSION_MINOR): Define new preprocessor macros.
	* src/abg-config.cc (config::config): Initialize
	config::m_format_{minor,major} using the newly defined
	preprocessor macros ABIGAIL_ABIXML_VERSION_M{IN,AJ}OR.
	* src/abg-tools-utils.cc (get_abixml_version_string): Define new
	function.
	* tools/abidw.cc (options::display_abixml_version): Define new
	data member.
	(options::options): Initialize it.
	(display_usage): Emit a help string for the new --abixml-version
	option.
	(parse_command_line): Parse the --abixml-version string.
	(main): Emit the abixml version when asked.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-12 18:31:28 +01:00
tangmeng 38d883cc74 abicompat: Add prompt message for abnormal operation
When using abicompat, if the --redundant option and --no-redundant
option are used at the same time, no error is prompted and none of the
options have an impact.

This patch emits an error message in that case.

	* tools/abicompat.cc (parse_command_line): Notify the user
	when --redundant and --no-redundant are used at the same time

Signed-off-by: tangmeng <tangmeng@uniontech.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-09 11:15:09 +01:00
tangmeng c36f8028fd abilint: Add prompt message for abnormal operation
When using abilint, if the user provides the --stdin option as well as
a file path on the command line, the file path is silently ignored.

This patch provides a warning to notify the user that the file path is
ignored in that case.

	* tools/abilint.cc (parse_command_line): Notify the user when the
	path to the file is ignored because the --stdin option was
	provided.

Signed-off-by: tangmeng <tangmeng@uniontech.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-09 10:57:48 +01:00
tangmeng 3592d272c4 Fix trivial typo when printing message
When abilint prints its tips information and abisym prints its
version string, it does not terminate it with a newline the way
that other commands do.

	* tools/abilint.cc (main): End the 'FILE_TYPE_UNKNOWN' tips with a
	newline.
	* tools/abisym.cc (main): Add a newline after version string.

Signed-off-by: tangmeng <tangmeng@uniontech.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-09 10:40:29 +01: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
tangmeng ba18218ec2 abicompat: Add prompt message for abnormal operation
When using abicompat, if the uses the --weak-mode option and also
provides a lib2 path on the command line, the lib2 path is silently
ignored.

This patch provides a warning to notify the user that the lib2 path is
ignored in that case.

	* tools/abicompat.cc (main): Notify the user when the path to
	the second library is ignored because the --weak-mode option
	was provided.  Also, fix comment.

Signed-off-by: tangmeng <tangmeng@uniontech.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-02 10:12:35 +01:00
tangmeng cf70e8698a abilint: fix trivial typo when using abilint
When using the abilint command, several problems were found:
1.When abilint prints its version information, it does not terminate
it with a newline.
2.There is a spelling error, the path is mistakenly written as patch.
3.There are extra fields in the help option.
4.Inappropriate and confusing option description.

	* tools/abilint.cc (display_usage): Correct the errors and
	redundant content in the help information.
	(main): Add a newline after version string.

Signed-off-by: tangmeng <tangmeng@uniontech.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-11-02 09:41:39 +01:00
tangmeng 5c67169668 Fix trivial typo when printing help information
When abicompat prints its help information, it does not terminate
it with a newline and option format is not aligned the way that
other commands do.

	* tools/abicompat.cc (display_usage): End the usage message with a
	newline and properly indent it.

Signed-off-by: tangmeng <tangmeng@uniontech.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-10-27 12:49:03 +02:00
Dodji Seketeli 623391a040 Add --enable-debug-type-canonicalization to configure
This configure option adds the possibility to debug the type
canonicalization process specifically.

When this new configure option is turned on, in
ir::get_canonical_type_for, when the type T, candidate for
canonicalization is compared to a given canonical type C, the
comparison is done twice; once using structural equality and once
using canonical equality whenever it's possible.  For all the
sub-types of T and C, structural equality and canonical equality must
yield the same result.  Otherwise, an error message is emitted and the
process aborts.

This all happens when using the abidw program with the --enable-tc or
--enable-type-canonicalization option.

This has proven to be very helpful to detect type canonicalization issues.

For instance, here is a trace of canonicalization issue that was
detected thanks to this patch:

    $ build/tools/abidw --debug-tc /usr/lib64/libwiretap.so.11.0.8
    structural & canonical equality different for type: function type void (wtap*)
    in compare_types_during_canonicalization at: /home/dodji/git/libabigail/PR28364/src/abg-ir.cc:13575: execution should not have reached this point!
    Abandon (core dumped)

This means that right after canonicalizing the type "void (wtap*)",
structural and canonical equality yield different results.  So it
means there is a problem with that type specifically that makes its
canonicalization "go wrong".  This requires further debugging to
understand, but at least, we are super close to the root cause of the
canonicalization problem.

	* configure.ac: Support the new
	--enable-debug-type-canonicalization option.  Define macro
	WITH_DEBUG_TYPE_CANONICALIZATION accordingly.
	* doc/manuals/abidw.rst: Update documentation.
	* include/abg-ir.h
	(environment::debug_type_canonicalization_is_on): Declare new
	member function if WITH_DEBUG_TYPE_CANONICALIZATION is defined.
	* src/abg-ir-priv.h
	(environment::priv::{use_canonical_type_comparison_,
	debug_type_canonicalization_}): Define new data members if
	WITH_DEBUG_TYPE_CANONICALIZATION is defined.
	(environment::priv::priv): Initialize them.
	* src/abg-ir.cc (try_canonical_compare): When
	WITH_DEBUG_TYPE_CANONICALIZATION is defined, perform comparison
	using either structural or canonical equality depending on the
	environment::priv::use_canonical_type_comparison_ flag.
	(environment::debug_type_canonicalization_is_on): Define member
	function when WITH_DEBUG_TYPE_CANONICALIZATION is defined.
	(compare_types_during_canonicalization): Define new function.
	(type_base::get_canonical_type_for): Use the new function
	compare_types_during_canonicalization.
	* tools/abidw.cc (options::debug_type_canonicalization): Define
	new data member.
	(option::option): Initialize it.
	(display_usage): Add help string for --debug-tc.
	(parse_command_line): Support new option --debug-tc or
	--debug-type-canonicalization.
	(load_corpus_and_write_abixml): Turn type canonicalization
	debugging on if --enable-tc is provided.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-10-18 09:40:15 +02:00