Commit Graph

394 Commits

Author SHA1 Message Date
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
Dodji Seketeli
ec8dc110a1 Improve type (de)serialization instability debugging
When debugging an issue uncovered by performing self comparison (abidw
--abidiff <binary>) I realized that I needed a stronger verification
of canonical types changing between type serialization and type
de-serialization.  Namely, when a type T with canonical type C is
serialized, its de-serialized type should still have the same
canonical type C.  Otherwise, it means some "type instability" took
place during serialization and de-serialization.

This patch implements that verification and also cleans up things
that came across while working on adding this debugging check.

	* include/abg-fwd.h (is_non_canonicalized_type): Declare new
	function.
	* src/abg-ir-priv.h: Include abg-corpus.h
	(environment::priv::pointer_type_id_map_): Fix comment.
	(environment::priv::check_canonical_type_from_abixml_during_self_comp):
	Define new member function.
	* src/abg-ir.cc (unmark_types_as_being_compared): Factorize this
	from ...
	(return_comparison_result): ... here.  Also, add a parameter to
	control whether this function should perform the "canonical type
	propagation optimization" or not.  By default the optimization is
	performed.  This can be changed for debugging purposes later.
	(type_base::get_canonical_type_for): Re-organise the self
	comparison debugging process to invoke the new function
	environment::priv::check_canonical_type_from_abixml_during_self_comp
	each time a canonical type is computed, in addition to doing the
	previous verification that was done when no canonical type was
	found.  Emit better error messages.
	(is_non_canonicalized_type): Rename the static function
	is_allowed_non_canonicalized_type into this and make it
	non-static.
	(hash_as_canonical_type_or_constant): Adjust.
	* src/abg-reader.cc (maybe_map_type_with_type_id): Define new
	static function.
	(read_context::maybe_check_abixml_canonical_type_stability):
	Ignore types that were not canonicalized.
	(read_corpus_from_input): Set the origin of the corpus early
	enough so that it's available to the canonicalizer even for types
	being canonicalized early.
	(MAYBE_MAP_TYPE_WITH_TYPE_ID): Factorize this macro out of ...
	(build_type): ... this.  That macro is defined only when debugging
	self comparison.
	(build_array_type_def): Map the read subrange type with its
	type-id.
	(handle_{type_decl, qualified_type, pointer_type_def,
	reference_type_def, function_type, array_type_def,enum_type_decl,
	typedef_decl, class_decl, union_decl}): Map the read type with its
	type-id.
	(load_canonical_type_ids): Ignore non-canonicalized types that
	which ids were saved in the type-id file.
	* src/abg-writer.cc (write_type_record): Factorize from ...
	(write_canonical_type_ids): ... here.  Don't forget to write the
	type-ids of decl-only types.  This can be useful for eye
	inspection.
	* tools/abidw.cc (load_corpus_and_write_abixml): Wait until the
	end of the function before removing the type-id file.  This can be
	useful for eye inspection.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-10-15 10:43:56 +02:00
Dodji Seketeli
1115e3f08e abipkgdiff: Do not erase working dirs before we are done using them
* tools/abipkgdiff.cc (compare_prepared_userspace_packages):
	Removing working directories "early" prevents e.g,
	dwarf_reader::get_soname_of_elf_file from accessing those files.
	So do not remove them until the very end.
	* tests/data/test-diff-pkg/libxcrypt-4.1.1-6.el8.x86_64--libxcrypt-4.1.1-6.el8.x86_64-output-1.txt:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-09-21 16:48:22 +02:00
Dodji Seketeli
6dc5e281da abipkgdiff: Fix showing added/removed files
When two packages are different just because one adds or removes
binaries -- and no binary have any ABI change otherwise, abipkgdiff
quits early and doesn't report the added and removed binaries.

This patch fixes the issue by reporting added/removed binaries even
when no ABI comparison took place.

	* tools/abipkgdiff.cc (compare_prepared_userspace_packages): Do
	not return early if there are no binaries to compare.  Also add
	more verbose messages.
	* tests/data/test-diff-pkg/libxcrypt-4.1.1-6.el8.x86_64--libxcrypt-4.1.1-6.el8.x86_64-output-1.txt:
	New reference output file.
	* tests/data/test-diff-pkg/libxcrypt-4.1.1-6.el8.x86_64--libxcrypt-compat-4.4.18-3.el9.x86_64-report-1.txt:
	New reference output file.
	* tests/data/test-diff-pkg/libxcrypt-4.1.1-6.el8.x86_64.rpm: New
	binary input file.
	* tests/data/test-diff-pkg/libxcrypt-4.4.18-3.el9.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/libxcrypt-compat-4.4.18-3.el9.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/libxcrypt-compat-debuginfo-4.4.18-3.el9.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/libxcrypt-debuginfo-4.1.1-6.el8.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/libxcrypt-debuginfo-4.4.18-3.el9.x86_64.rpm: Likewise.
	* tests/data/Makefile.am: Add the new testing files to source
	distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add these binary packages
	to this testing harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-09-20 09:12:00 +02:00
Dodji Seketeli
46b1ab08b0 Bug 27995 - Self comparison error from abixml file
There are several self comparison issues uncovered by comparing the
file test-PR27995.abi (provided in the bug report) against itself.
This patch address them all as well as the regressions induced on some
of the test suite and then and updates the other reference test suite
output that need it.

In the equals overload for decl_base, we compare the non-internal
versions of qualified decl names.  For var_decls of anonymous class or
union types, the non-internal version is the flat-representation of
the type.  Thus a benign change in a data member name of the anonymous
type might cause the equals function to consider the var_decls to be
wrongly different.  The internal version of the qualified decl name
should return a name that is stable for types, irrespective of these
benign variations.  The patch thus makes the equals overload for
decl_base to compare internal versions of qualified decl names instead.

The patch ensures that enum_type_decl::get_pretty_representation
return and internal pretty representation that is "stable" for
anonymous types.  Basically, all anonymous enums will have the same of
name that looks like "__anonymous_enum__".  This is to ensure two
things: first, that all anonymous enums are compared against each
other during type canonicalization, ensuring that when two anonymous
enums are canonically different, it really is because of changes in
their enumerators or basic type, not because of anything having to do
with their artificial names.  Second, that in the equals overload for
decl_base, their internal qualified name always compare equal.  This
nullifies the risk of having anonymous types compare different because
of their (non existent) name.  This is because libabigail's dwarf
reader assigns artificial unique names to anonymous types, so we don't
want to use these during actual type comparison.

We do something similar for class_decl::get_pretty_representation and
union_decl::get_pretty_representation where the pretty internal
representation for class/union decl would now be
__anonymous_{struct,union}__.

The patch scouts the uses of get_pretty_representation() to make sure
to use avoid using the internal-form of the pretty representations
when it's not warranted.  It also updates the doxygen comments of the
overloads of that function.

In the abixml reader, we were wrongly canonicalizing array types
early, even before they were fully created.  The was leading to
spurious type chances down the road.

The patch also fixes the caching of the name of function types by
making it consistent with caching of the names of the other types of
the system.  The idea is that we don't cache the name of a function
type until it's canonicalize.  This is because the type might be
edited during its pre-canonicalization life time; and that editing
might change its name.  However once the type is canonicalized, it
becomes immutable.  At that point we can cache its name, for
performance purposes.  Note that we need to do that both for the
"internal version" of the type name (used for canonilization purposes)
and the "non-internal version" one, which is used for other purposes.

This caching scheme wasn't respected for function types, so we were
caching a potentially wrong name for the type after its
canonicalization.

Last but not least, there is a problem that makes canonical type
comparison different from structural type comparison.
Let's consider these two declarations:

    typedef int FirstInt;
    typedef int SecondInt;

Now, consider these two pointer types: FirstInt* and SecondInt*;
These two pointer types are canonically different because they have
different type names.  This is because during type canonicalization,
types with the same "pretty representation" are compared against each
other.  So types with different type names will certainly have
different pretty representations and won't be compared; they are thus
going to have different canonical types.

However, FirstInt* and SecondInt* do compare equal, structurally,
because the equals overload for pointer_type_def compares the
pointed-to types of pointers by peeling off typedefs.  So, here, as
both pointed-to types are 'int' when the typedefs are peeled off, the
two pointers structurally compare equal.  This discrepancy between
structural and canonical equality introduces subtle and spurious type
changes depending on the order in which types are canonicalized.  For
instance:

    struct {FirstInt* m0;};   /* First type.  */

    struct {SecondInt* m0;};  /* Second type. */

If FirstInt* and SecondInt* are canonicalized before their containing
anonymous types, then the two anonymous types will compare different
(because FirstInt* and SecondInt* compare different) and have
different canonical types.  If, however, the anonymous types are
canonicalized before FirstInt* and SecondInt*, then will compare equal
because FirstInt* and SecondInt* are structurally equivalent.
FirstInt* and SecondInt* will be canonicalized latter and have
different canonical types (because they have different type names)
despite being structurally equivalent.

The change in the order of canonicalization can happen when
canonicalizing types from a corpus coming from DWARF as opposed to
canonicalizing types from a corpus coming from abixml.

The patch fixes this discrepancy by not peeling off typedefs from the
pointed-to types when comparing pointers.  Note that this makes us
regress on bug https://sourceware.org/bugzilla/show_bug.cgi?id=27236,
where the typedef peeling was introduced.  In hindsight, introducing
that typedef peeling was a mistake.  I'll try to address that bug
again in a subsequent patch.

	* doc/manuals/abidiff.rst: Add documentation for the --debug
	option.
	* src/abg-ir.cc (equals): In the overload for decl_base consider
	the internal version of qualified decl name.  In the overload for
	pointer_type_def do not peel typedefs off from the compared
	pointed-to types.  In the overload for typedef_decl compare the
	typedef as a decl as well.  In the overload for var_decl, compare
	variables that have the same ELF symbols without taking into
	account their qualified name, rather than their name.  Stop
	comparing data member without considering their names.
	In the overload for class_or_union, when a decl-only class that is
	ODR-relevant is compared against another type, assume that
	equality if names are equal.  This is useful in environments where
	some TUs are ODR-relevant and others aren't.
	(*::get_pretty_representation): Update doxygen comments.
	(enum_type_decl::get_pretty_representation): Return an internal
	pretty representation that is stable across all anonymous enums.
	(var_decl::get_anon_dm_reliable_name): Use the non-internal pretty
	representation for anonymous data members.
	(function_type::priv::temp_internal_cached_name_): New data
	member.
	(function_type::get_cached_name): Cache the internal name after
	the function type is canonicalized.  Make sure internal name and
	non-internal name are cached separately.
	(class_or_union::find_anonymous_data_member): Look for the anonymous
	data member by looking at its non-internal name.
	({class, union}_decl::get_pretty_representation): Use something like "class
	__anonymous_{union,struct}__" for all anonymous classes, so that they can
	all be compared against each other during type canonicalization.
	(type_has_sub_type_changes): Use non-internal pretty
	representation.
	(hash_type_or_decl, function_decl_is_less_than:): Use internal
	pretty representation for comparison here.
	* src/abg-reader.cc (read_context::maybe_canonicalize_type): Don't
	early canonicalize array types.
	* src/abg-writer.cc (annotate): Use non-internal pretty
	representation.
	* tests/data/test-diff-filter/test-PR27995-report-0.txt: New
	reference report.
	* tests/data/test-diff-filter/test-PR27995.abi: New test input
	abixml file.
	* tests/data/Makefile.am: Add test-PR27995.abi,
	test-PR27995-report-0.txt to the source distribution.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-diff-dwarf/test6-report.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Adjust.
	* tests/data/test-diff-filter/test41-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test43-decl-only-def-change-leaf-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test8-report.txt: Adjust.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	Adjust.
	* tests/data/test-diff-suppr/test39-opaque-type-report-0.txt: Adjust.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Adjust.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
	* tests/test-diff-filter.cc (in_out_specs): Add the
	test-PR27995.abi to the test harness.
	* tools/abidiff.cc (options::do_debug): New data member.
	(options::options): Initialize it.
	(parse_command_line): Parse --debug.
	(main): Activate self comparison debug if the user provided
	--debug.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-08-11 17:38:14 +02:00
Ben Woodard via Libabigail
519d7ce8e5 Fix trivial typo when printing version string
When abicompat prints its version string, it does not terminate
it with a newline the way that other commands do. Contributed by
Bolo.

	* tools/abicompat.cc (main): Add a newline after version string.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-06-10 15:27:35 +02:00
Dodji Seketeli
d604e33793 Revert "Fix trivial typo when printing version string"
This reverts commit ad619f14ea.
2021-06-10 15:26:36 +02:00
Ben Woodard via Libabigail
ad619f14ea Fix trivial typo when printing version string
When abicompat prints its version string, it does not terminate
it with a newline the way that other commands do. Contributed by
Bolo.

Signed-off-by: Ben Woodard <woodard@redhat.com>
2021-06-10 15:22:53 +02:00
Dodji Seketeli
923a355f16 abidw: Remove temporary .typeid files when using --debug-abidiff
I noticed that the temporary typeid file generated by abidw when using
the --debug-abidiff option was left behind.  This patch removes it.

	* tools/abidw.cc (load_corpus_and_write_abixml): Remove temporary
	typeid file after its use.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-06-09 19:45:22 +02:00
Dodji Seketeli
27d2927107 Detect abixml canonical type instability during abidw --debug-abidiff
In the debugging mode of self comparison induced by the invocation of
"abidw --debug-abidiff <binary>", it's useful to be able to ensure the
following invariant:

    The pointer value of the canonical type of a type T that is
    serialized into abixml with the id string "type-id-12" (for
    instance) must keep the same canonical type pointer value when
    that abixml file is de-serialized back into memory.  This is
    possible mainly because libabigail stays loaded in memory all the
    time during both serialization and de-serialization.

This patch adds support for detecting when that invariant is not
respected.

In other words it detects when the type build from de-serializing the
type which id is "type-id-12" (for instance) has a canonical type
which pointer value is different from the pointer value of the
canonical type (of the type) that was serialized as having the type id
"type-id-12".

This is done in three phases.

The first phase happens in the code of abidw itself; after the abixml
is written on disk, another file called the "typeid file" is written
on disk as well.  That later file contains a set of records; each
record associates a "type id string" (like the type IDs that appear in
the abixml file) to the pointer value of the canonical type that
matches that type id string.  That file is thus now available for
manual inspection during a later debugger session.  This is done by
invoking the new function write_canonical_type_ids.

The second phase appears right before abixml loading time.  The typeid
file is read back and the association "type-id string" <-> is stored
in a hash map that is returned by
environment::get_type_id_canonical_type_map().  This is done by
invoking the new function load_canonical_type_ids.

The third phase happens right after the canonicalization (triggered in
the abixml reader) of a type coming from abixml, corresponding to a
given type id.  It checks if the pointer value of the canonicalization
type just computed is the same as the one associated to that type id
in the map returned by environment::get_type_id_canonical_type_map.

This is a way of verifying the "stability" of a canonical type during
its serialization and de-serialization to and from abixml and it's
done as part of "abidw --debug-abidiff <binary>".

Just as an example, here is the kind of error output that I am getting
on a real life debugging session on a binary that exhibits self
comparison error:

    $ abidw  --debug-abidiff -d <some-binary>
    error: problem detected with type 'typedef Vmalloc_t' from second corpus
    error: canonical type for type 'typedef Vmalloc_t' of type-id 'type-id-179' changed from '1a083e8' to '21369b8'
    [...]
    $

From this output, I see that the first type for which libabigail
exhibits an instability on the pointer value of the canonical type is
the type 'typedef Vmalloc_t'.  In other words, when that type is saved
to abixml, the type we read back is different.  This needs further
debugging but at least it pinpoints exactly what type we are seeing
the core issue on first.  This is of a tremendous help in the root
cause analysis needed to understand why the self comparison is
failing.

	* include/abg-ir.h (environment::get_type_id_canonical_type_map):
	Declare new data member.
	* src/abg-ir.cc (environment::priv::type_id_canonical_type_map_):
	Define new data member.
	(environment::get_type_id_canonical_type_map): Define new method.
	* include/abg-reader.h (load_canonical_type_ids): Declare new
	function.
	* src/abg-reader.cc (read_context::m_pointer_type_id_map):
	Define new data member.
	(read_context::{get_pointer_type_id_map,
	maybe_check_abixml_canonical_type_stability}): Define new methods.
	(read_context::{maybe_canonicalize_type,
	perform_late_type_canonicalizing}): Invoke
	maybe_perform_self_comparison_canonical_type_check after
	canonicalization to perform canonicalization type stability
	checking.
	(build_type): Associate the pointer value for the newly built type
	with the type id string identifying it in the abixml.  Once the
	abixml representation is dropped from memory and we are about to
	perform type canonicalization, we can still know what the type id
	of a given type coming from abixml was; it's thus possible to
	verify that the canonical type associated to that type id is the
	same as the one stored in the typeid file.
	(read_type_id_string): Define new static function.
	(load_canonical_type_ids): Define new function.
	* include/abg-writer.h (write_canonical_type_ids): Likewise.
	* src/abg-writer.cc (write_canonical_type_ids): Define new
	function overloads.
	* tools/abidw.cc (options::type_id_file_path): New data member.
	(load_corpus_and_write_abixml): Write and read back the typeid
	file.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-05-25 12:24:26 +02:00
Dodji Seketeli
104468d1a4 Detect failed self comparison in type canonicalization of abixml
During the self comparison triggered by "abidw --abidiff <binary>",
some comparison errors can happen when canonicalizing types that are
"de-serialized" from the abixml that was serialized from the input
binary.

This patch adds some debugging checks and messaging to emit a message
when a type from the abixml appears to not "match" the original type
from the initial corpus it originated from.

This is the more detailed description:

Let's consider a type T coming from the corpus of the input binary.

That input corpus is serialized into abixml and de-serialized again
into a second corpus that we shall name the abixml corpus.  From that
second corpus, let's consider the type T' that is the result of
serializing T into abixml and de-serializing it again.  T is said to
be the original type of T'.  If T is a canonical type, then T' should
equal T.  Otherwise, if T is not a canonical type, its canonical type
should equal the canonical type of T'.

For the sake of simplicity, let's consider that T is a canonical
type.  During the canonicalization of T', T' should equal T.  Each and
every canonical type coming from the abixml corpus should be equal to its
original type from the binary corpus.

If a T' is different from its original type T, then there is an
"equality problem" between T and T'.  In other words, there is a
mismatch between T and T'.  We want to be notified of that problem so
that we can debug it further and fix it.

So this patch introduces the option "abidw --debug-abidiff <binary>"
to trigger the "debug self comparison mode".  At canonicalization
time, we detect that we are in that debug self comparison mode and
during canonicalization of types from the abixml corpus, it detects
when they compare different from their counterpart from the original
corpus.

This debugging capability can be enabled at configure time with a new
--enable-debug-self-comparison configure option.  That option defines
a new WITH_DEBUG_SELF_COMPARISON compile time macro that is used to
conditionally compile the implementation of this debugging feature.

So, one example of this might look like this:

    abidw  --debug-abidiff bin:
    error: problem detected with type 'typedef Vmalloc_t' from second corpus
    error: problem detected with type 'Vmalloc_t*' from second corpus
    [...]

So that means the "typedef Vmalloc_t" read from the abixml compares
different from its original type where it should not.

So armed with this new insight, I know I need to debug that comparison
in particular to see why it wrongly results in two different types.

	* doc/manuals/abidw.rst: Add documentation for the --debug-abidiff
	option.
	* include/abg-ir.h (environment::{set_self_comparison_debug_input,
	get_self_comparison_debug_inputs, self_comparison_debug_is_on}):
	Declare new methods.
	* configure.ac: Define a new --enable-debug-self-comparison option
	that is disabled by default.  That option defines a new
	WITH_DEBUG_SELF_COMPARISON preprocessor macro.
	* src/abg-ir.cc
	(environment::priv::{first_self_comparison_corpus_,
	second_self_comparison_corpus_, self_comparison_debug_on_}): New
	data members.  Also, re-indent the data members.
	(environment::{set_self_comparison_debug_input,
	get_self_comparison_debug_inputs, self_comparison_debug_is_on}):
	Define new method.
	(type_base::get_canonical_type_for): In the "debug self comparison
	mode", if a type coming from the second corpus compares different
	from its counterpart coming from the first corpus then log a debug
	message.
	* src/abg-dwarf-reader.cc (read_debug_info_into_corpus): When
	loading the first corpus, if the debug self comparison mode is on,
	then save that corpus on the side in the environment.
	* src/abg-reader.cc (read_corpus_from_input): When loading the
	second corpus, if the debug self comparison mode is on, then save
	that corpus on the side in the environment.
	* tools/abidw.cc: Include the config.h file for preprocessor
	macros defined at configure
	(options::debug_abidiff): New data member.
	(parse_command_line): Parse the --debug-abidiff option.
	(load_corpus_and_write_abixml): Switch the self debug mode on when
	the --debug-abidiff option is provided.  Use a read_context for
	the abixml loading.  That is going to be useful for subsequent
	patches.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-05-25 12:16:25 +02:00
Dodji Seketeli
dd55550355 reader: Handle 'abi-corpus' element being possibly empty
This problem was reported at https://sourceware.org/bugzilla/show_bug.cgi?id=27616.

The abixml reader wrongly assumes that the 'abi-corpus' element is
always non-empty.  Note that until now, the only emitter of abixml
consumed in practice was abg-writer.cc and it only emits non-empty
'abi-corpus' elements.  So the issue wasn't exposed.

So, the reader assumes that an 'abi-corpus' element has at least a
text node.

For instance, consider this minimal input file named test-v0.abi:

    $cat test-v0.abi

    <abi-corpus-group architecture='elf-arm-aarch64'>
     <abi-corpus path='vmlinux' architecture='elf-arm-aarch64'>
     </abi-corpus>
    </abi-corpus-group>

    $

Now, compare it to this file where the abi-corpus element is an empty
element (doesn't even contain any text):

    $cat test-v0.abi

    <abi-corpus-group architecture='elf-arm-aarch64'>
     <abi-corpus path='vmlinux'/>
    </abi-corpus-group>

    $

comparing the two files with abidiff (wrongly) reports:

    $ abidiff test-v0.abi test-v1.abi
    ELF architecture changed
    Functions changes summary: 0 Removed, 0 Changed, 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

    architecture changed from 'elf-arm-aarch64' to ''
    $

What's happening is that read_corpus_from_input is getting out early
when it sees that the node is empty.  This is at:

   xmlNodePtr node = ctxt.get_corpus_node();
@@ -1907,10 +1925,14 @@ read_corpus_from_input(read_context& ctxt)
 	corp.set_soname(reinterpret_cast<char*>(soname_str.get()));
     }

  if (!node->children)  // <---- we get out early here and we
    return nil;         // forget about the properties of
                        // the current empty corpus element node

So, at its core, fixing the issue at hand involves avoiding the early
return there.

But then, it turns out that's not enough.

In the current setting, the different abixml processing entry points
are designed to be used in a semi "streaming" mode.

So for instance, read_translation_unit_from_input can be invoked
repeatedly to "stream in" the next translation unit at each
invocation.

Alternatively, the lower level xmlTextReaderNext can be used to
iterate over XML node until we reach the translation unit XML element
we are interested in.  At that point xmlTextReaderExpand can be used
to expand the XML node, then we let the context know that this is
the current node of the corpus that needs to be processed, using
read_context::get_corpus_node.  Once we've done that,
read_translation_unit_from_input can be called to process that
particular corpus node.  Note that the corpus node at hand, that needs
to be processed will be retrieved by read_context::get_corpus_node.

These two modes of operation are also available for
read_corpus_from_input, read_symbol_db_from_input,
read_elf_needed_from_input etc.

Today, these functions all assume that the current node returned by
read_context::get_corpus_node is the node /before/ the node of the
corpus to be processed.  So they all start looking at the /next sibling/
of the node returned by read_context::get_corpus_node.  So the code
was implicitly assuming that read_context::get_corpus_node was
pointing to a text node that was before the node of the corpus that we
want to process.

This is wrong.  read_context::get_corpus_node should just return the
current node of the corpus that needs to be processed and voila.

And so read_context::set_corpus_node should be used to set the current
node of the corpus to the current element node that needs to be processed.

That's the spirit of the change done by this patch.

As its name suggests, the existing
xml::advance_to_next_sibling_element is used to skip non element xml
nodes (including text nodes) and move to the next element node to
process, which is set to the context using
read_context::set_corpus_node.

Then the actual processing functions like read_corpus_from_input get
the node to process, using read_context::get_corpus_node and process
it rather than processing the sibling node that comes after it.

The other changes are either to prevent related crashes that I noticed
while doing various tests, update the abilint tool used to read and
debug abixml input files and add better documentation.

	* src/abg-reader.cc (read_context::get_corpus_node): Add comment
	to this member function.
	(read_translation_unit_from_input, read_symbol_db_from_input)
	(read_elf_needed_from_input): Start processing the current node of
	the corpus that needs to be processed rather than its next
	sibling.  Once the processing is done, set the new "current node
	of the corpus to be processed" properly by skipping to the next
	element node to be processed.
	(read_corpus_from_input): Don't get out early when the
	'abi-corpus' element is empty.  If, however, it has children node,
	skip to the first child element and flag it -- using
	read_context::set_corpus_node -- as being the element node to be
	processed by the processing facilities of the reader.  If we are
	in a mode where we called xmlTextReaderExpand ourselves to get the
	node to process, then it means we need to free that node
	indirectly by calling xmlTextReaderNext.  In that case, that node
	should not be flagged by read_context::set_corpus_node.  Add more
	comments.
	* src/abg-corpus.cc (corpus::is_empty): Do not crash when no
	symtab is around.
	* src/abg-libxml-utils.cc (go_to_next_sibling_element_or_stay):
	Fix typo in comment.
	(advance_to_next_sibling_element): Don't crash when given a nil
	node.
	* tests/data/test-abidiff/test-PR27616-squished-v0.abi: Add new
	test input.
	* tests/data/test-abidiff/test-PR27616-squished-v1.abi: Likewise.
	* tests/data/test-abidiff/test-PR27616-v0.xml: Likewise.
	* tests/data/test-abidiff/test-PR27616-v1.xml: Likewise.
	* tests/data/Makefile.am: Add the new test inputs above to source
	distribution.
	* tests/test-abidiff.cc (specs): Add the new tests inputs above to
	this harness.
	* tools/abilint.cc (main): Support writing corpus groups.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-05-03 17:13:31 +02:00
Matthias Maennich
3abd9742b7 dwarf reader: drop (now) unused code related to symbol table reading
The introduction of the new symtab reader incorporated much of the
existing functionality. Now that the most code parts are migrated to the
new symtab reader, we can safely remove the old code paths.

Ignoring the symbol table is not a thing anymore. The new symtab reader
does read the symtab unconditionally for consistency reasons. Hence also
remove all functionality around conditional symtab reading.

	* include/abg-dwarf-reader.h (set_ignore_symbol_table): Remove.
	(get_ignore_symbol_table): Likewise.
	* src/abg-dwarf-reader.cc (add_symbol_to_map): Likewise.
	(read_context::options_type::ignore_symbol_table): Likewise.
	(read_context::options_type): Adjust.
	(read_context::fun_addr_sym_map_): Remove.
	(read_context::fun_entry_addr_sym_map_): Likewise.
	(read_context::fun_syms_): Likewise.
	(read_context::var_addr_sym_map_): Likewise.
	(read_context::var_syms_): Likewise.
	(read_context::undefined_fun_syms_): Likewise.
	(read_context::undefined_var_syms_): Likewise.
	(read_context::initialize): Adjust.
	(read_context::lookup_elf_symbol_from_index): Remove.
	(read_context::fun_entry_addr_sym_map_sptr): Likewise.
	(read_context::fun_entry_addr_sym_map): Likewise.
	(read_context::fun_syms_sptr): Likewise.
	(read_context::fun_syms): Likewise.
	(read_context::var_syms_sptr): Likewise.
	(read_context::var_syms): Likewise.
	(read_context::undefined_fun_syms_sptr): Likewise.
	(read_context::undefined_var_syms_sptr): Likewise.
	(read_context::load_symbol_maps_from_symtab_section): Likewise.
	(read_context::load_symbol_maps): Likewise.
	(read_context::maybe_load_symbol_maps): Likewise.
	(set_ignore_symbol_table): Likewise.
	(get_ignore_symbol_table): Likewise.
	(create_default_var_sym): Likewise.
	(build_var_decl): Adjust.
	(function_is_suppressed): Likewise.
	(variable_is_suppressed): Likewise.
	(build_function_decl): Likewise.
	(add_symbol_to_map): Remove.
	(read_corpus_from_elf): Adjust.
	(build_corpus_group_from_kernel_dist_under): Likewise.
	* tools/abidw.cc (main): Likewise.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Reviewed-by: Dodji Seketeli <dodji@seketeli.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
2021-04-02 15:48:23 +02:00
Ben Woodard via Libabigail
05d33d607a Bug 27512 - Remove broken zip-archive support
The optional zip archive feature was broken when the concept of
environment was introduced by commit b2e5366d3 back in 2015. Since it
wouldn't even compile and nobody noticed, we are fairly sure nobody
uses that feature. Therefore, we decided to remove it rather than fix
it.

	* configure.ac: remove --enable-zip-archive option and logic
	associated with it.
	* include/abg-libzip-utils.h: Remove.
	* src/abg-libzip-utils.cc: Likewise.
	* include/Makefile.am: remove reference to include/abg-libzip-utils.h
	that no longer exists.
	* src/Makefile.am: remove reference to src/abg-libzip-utils.cc that no
	longer exists.
	* relicensing-scripts/file-licenses.orig.txt: remove references to
	files that no longer exist.
	* relicensing-scripts/files-with-lgplv3.txt: remove references to
	files that no longer exist.
	* tests/test-write-read-archive.cc: Remove because it tests code
	that no longer exists.
	* tests/Makefile.am: remove reference to tests that no longer exist.
	* include/abg-reader.h: remove conditionally compiled code for zip
	archives.
	* include/abg-tools-utils.h: remove conditionally compiled code for
	zip archives.
	* src/abg-corpus.cc: remove conditionally compiled code for zip
	archives.
	* src/abg-reader.cc: remove conditionally compiled code for zip
	archives.
	* src/abg-tools-utils.cc: remove conditionally compiled code for zip
	archives.
	* src/abg-writer.cc: remove conditionally compiled code for zip
	archives.
	* tools/abidiff.cc: remove conditionally compiled code for zip
	archives.
	* tools/abilint.cc: remove conditionally compiled code for zip
	archives.
	* tools/abiar.c: Remove.
	* tools/Makefile.am: remove references to abiar a utility that no
	longer has a reason for existing.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-03-19 10:52:57 +01:00
Ben Woodard via Libabigail
701de3ba5d Fix declaratons of conditionally defined functions
Functions relating to zip archives are declared but are never compiled
when --enable-zip-archive=no, the default.

This makes sure that they are not declared when they won't be defined
due to conditional compilation.

	* include/abg-reader.h (read_corpus_from_file): Guard the
	declaration of these overloads with #ifdef WITH_ZIP_ARCHIVE.
	* tools/abilint.cc: Guard the use of
	abigail::xml_reader::read_corpus_from_file with #ifdef
	WITH_ZIP_ARCHIVE.

Signed-off-by: Ben Woodard <woodard@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-03-08 13:05:43 +01:00
Dodji Seketeli
f433d4dbdb Revert "Fix declaratons of conditionally defined functions"
I forgot to edit the commit message of this commit to make it comply
with the rules in https://sourceware.org/git/?p=libabigail.git;a=blob;f=COMMIT-LOG-GUIDELINES.

So I am reverting commit cd2af9e5f5
2021-03-08 13:04:13 +01:00
Ben Woodard via Libabigail
cd2af9e5f5 Fix declaratons of conditionally defined functions
Functions relating to zip archives are declared but are never compiled
when --enable-zip-archive=no, the default.

This makes sure that they are not declared when they won't be defined
due to conditional compilation.

Signed-off-by: Ben Woodard <woodard@redhat.com>
2021-03-08 12:52:50 +01:00
Dodji Seketeli
23046152e0 Bump ABIXML format version to 2.0
After fixing the interpretation of the DW_AT_bit_offset attribute for
offset of bit field data members, serialized abixml might now be
incompatible with versions of Libabigail that use the previous
interpretation.

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

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

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-02-01 14:09:29 +01:00
Dodji Seketeli
1d29610d51 Bug 27255 - fedabipkgdiff fails on nfs-utils on Fedora 33
When running fedabipkgdiff as:

    fedabipkgdiff --self-compare -a --from fc33 nfs-utils

I am getting:

    Error encountered while running fedabipkgdiff with error message:

Running it with the --verbose option yields more clue, though.

It turns out that fedabipkgdiff runs abipkgdiff on an RPM and gives it
the wrong associated -debuginfo RPM.

This is because the member function
RPMCollection.get_sibling_debuginfo() doesn't returns the "first"
debuginfo package that comes with a given RPM.  In the case of the
package nfs-utils-2.5.2-1.rc4.fc33.aarch64.rpm, it was using the
package nfs-utils-coreos-debuginfo-2.5.2-1.rc4.fc33.aarch64.rpm
instead of the package nfs-utils-debuginfo-2.5.2-1.rc4.fc33.aarch64.rpm.

So, of course, abipkgdiff could not find the proper debuginfo for the
binaries carried by nfs-utils-2.5.2-1.rc4.fc33.aarch64.rpm.

This happens only in cases where there a several debuginfo packages
for a given RPM.  In that case, we need to be more careful to select
the right debuginfo package and not just a random one.

This patch adds a RPMCollection.get_matching_debuginfo() member function
that does the right thing.  It thus teaches
generate_comparison_halves() to use the new function.

	* tools/fedabipkgdiff (RPMCollection::get_sibling_debuginfo):
	Update comment.
	(RPMCollection::get_matching_debuginfo): Define new function.
	(generate_comparison_halves): Use
	RPMCollection::get_matching_debuginfo instead of
	RPMCollection::get_sibling_debuginfo.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-01-27 11:20:48 +01:00
Dodji Seketeli
40709acdd5 Bug 27232 - fedabipkgdiff fails on gawk from Fedora 33
When running fedabipkgdiff on the gawk-5.1.0-2.fc33.aarch64.rpm
package we get this error message:

    Error encountered while running fedabipkgdiff with error message:

That is not a very useful error message to say the least.

The issue is that abipkgdiff returns with an "unknown error" which is
due to the fact that the gawk package contains a directory that is
owned by root.  As abipkgdiff tries to write temporary files into that
directory, it fails to do so.

The patch now writes the temporary ABIXML file into a sub-directory
that is not owned the package where we should have write privileges.

It also improves error reporting.

	* tools/abipkgdiff.cc (options::pkg{1,2}): Add new data members to
	store the packages to compare and have them available for the
	various functions that may need them down the road.
	(package::create_abi_file_path): Add new function.
	(compare_to_self): Use the new package::create_abi_file_path to
	create the path to the ABI file in a directory not owned by the
	package.  That should increase our chances of having the rights to
	write that one.  Make sure to emit error message when the
	comparison against self fails.
	({compare_task, self_compare_task}::perform): During the process
	of comparison if an internal error happens, report it.  Cleanup
	the existing reporting a little bit.
	(pkg_extraction_task::perform): Fix comment.
	* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64-self-report-0.txt:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2021-01-26 17:41:33 +01:00
Matthias Maennich
840eca4714 abipkgdiff: Address operator precedence warning
When compiling with clang, it (rightfully) complains about an operator
precedence issue:

abipkgdiff.cc:1646:7: error: operator '?:' has lower precedence than '<<'; '<<' will be evaluated first [-Wparentheses]
      ? string("Comparison against self SUCCEEDED\n")
      ^

Fix that by properly placing the parentheses. Also, drop the superfluous
string conversion.

	* tools/abipkgdiff.cc (compare_to_self): address clang warning.

Signed-off-by: Matthias Maennich <maennich@google.com>
2021-01-26 17:19:08 +01:00
Matthias Maennich
c458e00db9 Drop unneccessary includes of abg-cxx-compat.h
Remove the unneccessary includes of abg-cxx-compat.h as users have been
migrated to use the corresponding standard includes.

	* include/abg-comparison.h: Remove include of abg-cxx-compat.h.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-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-workers.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.

Signed-off-by: Matthias Maennich <maennich@google.com>
2020-12-15 09:23:44 +01:00
Matthias Maennich
5d669e0126 Remove <unordered_set> usages from abg_compat
std::unordered_set is now provided through the language standard, hence
remove the compatibility code for <unordered_set> and adjust all users
accordingly.

	* include/abg-cxx-compat.h: Drop compatibility for <unordered_set>.
	* include/abg-comparison.h: migrate abg_compat use to std.
	* include/abg-interned-str.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.

Signed-off-by: Matthias Maennich <maennich@google.com>
2020-12-15 09:21:38 +01:00