Add support for BTF

This adds support for the BTF debug information format.  It provides a
new BTF front-end which can be instantiated by the function
tools::create_best_elf_based_reader().

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

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

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

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

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2022-10-31 10:10:52 +01:00
parent 5d97da9755
commit 12641b1130
34 changed files with 2026 additions and 28 deletions

View File

@ -201,6 +201,12 @@ AC_ARG_ENABLE(ctf,
ENABLE_CTF=$enableval,
ENABLE_CTF=auto)
dnl check if user has enabled BTF code
AC_ARG_ENABLE(btf,
AS_HELP_STRING([--enable-btf=yes|no],
[disable support of btf files)]),
ENABLE_BTF=$enableval,
ENABLE_BTF=auto)
dnl *************************************************
dnl check for dependencies
dnl *************************************************
@ -339,6 +345,77 @@ if test x$ENABLE_CTF != xno; then
fi
fi
dnl configure BTF usage
BPF_LIBS=
if test x$ENABLE_BTF != xno; then
AC_CHECK_HEADER([bpf/btf.h],
[ENABLE_BTF=yes],
[AC_MSG_NOTICE([could not find bpf/btf.h])])
if test x$ENABLE_BTF = xyes; then
AC_MSG_NOTICE([enable BTF support])
ENABLE_BTF=yes
AC_DEFINE([WITH_BTF], 1,
[Defined if user enabled BTF usage])
BPF_LIBS=-lbpf
else
AC_MSG_NOTICE([BTF support was disabled])
ENABLE_BTF=no
fi
dnl Test if various functions and structs are present.
if test x$ENABLE_BTF = xyes; then
dnl Test if struct btf_enum64 is present.
AC_CHECK_TYPE([struct btf_enum64],
[HAVE_BTF_ENUM64=yes],
[HAVE_BTF_ENUM64=no],
[#include <bpf/btf.h>])
if test x$HAVE_BTF_ENUM64 = xyes; then
AC_DEFINE([WITH_BTF_ENUM64], 1, [struct btf_enum64 is present])
fi
dnl Test if btf__get_nr_types is present
AC_CHECK_DECL([btf__get_nr_types],
[HAVE_BTF__GET_NR_TYPES=yes],
[HAVE_BTF__GET_NR_TYPES=no],
[#include <bpf/btf.h>])
if test x$HAVE_BTF__GET_NR_TYPES = xyes; then
AC_DEFINE(WITH_BTF__GET_NR_TYPES, 1, [The function btf__get_nr_types is present])
fi
dnl Test if btf__type_cnt is present
AC_CHECK_DECL([btf__type_cnt],
[HAVE_BTF__TYPE_CNT=yes],
[HAVE_BTF__TYPE_CNT=no],
[#include <bpf/btf.h>])
if test x$HAVE_BTF__TYPE_CNT = xyes; then
AC_DEFINE(WITH_BTF__TYPE_CNT, 1, [The function btf__type_cnt is present])
fi
dnl Test if BTF_KIND_TYPE_TAG exists
AC_CHECK_DECL([int kind = BTF_KIND_TYPE_TAG],
[HAVE_BTF_KIND_TYPE_TAG=yes],
[HAVE_BTF_KIND_TYPE_TAG=no],
[#include <bpf/btf.h>])
if test x$HAVE_BTF_KIND_TYPE_TAG = xyes; then
AC_DEFINE([WITH_BTF_KIND_TYPE_TAG], 1,
[The BTF_KIND_TYPE_TAG enumerator is present])
fi
dnl Test if BTF_KIND_DECL_TAG exists
AC_CHECK_DECL([int kind = BTF_KIND_DECL_TAG],
[HAVE_BTF_KIND_DECL_TAG=yes],
[HAVE_BTF_KIND_DECL_TAG=no],
[#include <bpf/btf.h>])
if test x$HAVE_BTF_KIND_DECL_TAG = xyes; then
AC_DEFINE([WITH_BTF_KIND_DECL_TAG], 1,
[The BTF_KIND_DECL_TAG enumerator is present])
fi
fi
fi
dnl Check for dependency: libxml
LIBXML2_VERSION=2.6.22
PKG_CHECK_MODULES(XML, libxml-2.0 >= $LIBXML2_VERSION)
@ -741,7 +818,7 @@ AX_VALGRIND_CHECK
dnl Set the list of libraries libabigail depends on
DEPS_LIBS="$XML_LIBS $ELF_LIBS $DW_LIBS $CTF_LIBS"
DEPS_LIBS="$XML_LIBS $ELF_LIBS $DW_LIBS $CTF_LIBS $BPF_LIBS"
AC_SUBST(DEPS_LIBS)
if test x$ABIGAIL_DEVEL != x; then
@ -782,6 +859,7 @@ fi
dnl Set a few Automake conditionals
AM_CONDITIONAL([CTF_READER],[test "x$ENABLE_CTF" = "xyes"])
AM_CONDITIONAL([BTF_READER],[test "x$ENABLE_BTF" = "xyes"])
dnl Set the level of C++ standard we use.
CXXFLAGS="$CXXFLAGS -std=$CXX_STANDARD"
@ -1092,6 +1170,7 @@ AC_MSG_NOTICE([
Enable fedabipkgdiff : ${ENABLE_FEDABIPKGDIFF}
Enable python 3 : ${ENABLE_PYTHON3}
Enable CTF front-end : ${ENABLE_CTF}
Enable BTF front-end : ${ENABLE_BTF}
Enable running tests under Valgrind : ${enable_valgrind}
Enable build with -fsanitize=address : ${ENABLE_ASAN}
Enable build with -fsanitize=memory : ${ENABLE_MSAN}

View File

@ -16,8 +16,9 @@ For a comprehensive ABI change report between two input shared
libraries that includes changes about function and variable sub-types,
``abidiff`` uses by default, debug information in `DWARF`_ format, if
present, otherwise it compares interfaces using debug information in
`CTF`_ format, if present, finally, if neither is found, it uses only
`ELF`_ symbols to report which of them were added or removed.
`CTF`_ or `BTF`_ formats, if present. Finally, if no debug info in
these formats is found, it only considers `ELF`_ symbols and report
about their addition or removal.
.. include:: tools-use-libabigail.txt
@ -605,6 +606,11 @@ Options
When comparing binaries, extract ABI information from `CTF`_ debug
information, if present.
* ``--btf``
When comparing binaries, extract ABI information from `BTF`_ debug
information, if present.
* ``--stats``
Emit statistics about various internal things.
@ -830,6 +836,7 @@ Usage examples
.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
.. _DWARF: http://www.dwarfstd.org
.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
.. _BTF: https://docs.kernel.org/bpf/btf.html
.. _ODR: https://en.wikipedia.org/wiki/One_Definition_Rule
.. _One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule
.. _DWZ: https://sourceware.org/dwz

View File

@ -21,10 +21,10 @@ functions and variables, along with a complete representation of their
types.
To generate either ABI or KMI representation, by default ``abidw``
uses debug information in `DWARF`_ format, if present, otherwise it
looks for debug information in `CTF`_ format, if present, finally, if
neither is found, it uses only `ELF`_ symbols to report which of them
were added or removed.
uses debug information in the `DWARF`_ format, if present, otherwise
it looks for debug information in `CTF`_ or `BTF`_formats, if present.
Finally, if no debug info in these formats is found, it only considers
`ELF`_ symbols and report about their addition or removal.
.. include:: tools-use-libabigail.txt
@ -389,6 +389,7 @@ standard `here
.. _GNU: http://www.gnu.org
.. _Linux Kernel: https://kernel.org/
.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
.. _BTF: https://docs.kernel.org/bpf/btf.html
.. _ODR: https://en.wikipedia.org/wiki/One_Definition_Rule
.. _One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule
.. _DWZ: https://sourceware.org/dwz

View File

@ -13,17 +13,17 @@ binaries.
For a comprehensive ABI change report that includes changes about
function and variable sub-types, the two input packages must be
accompanied with their debug information packages that contain debug
information either in `DWARF`_ or in `CTF`_ formats. Please note
however that some packages contain binaries that embed the debug
information either in `DWARF`_, `CTF`_ or in `BTF`_ formats. Please
note however that some packages contain binaries that embed the debug
information directly in a section of said binaries. In those cases,
obviously, no separate debug information package is needed as the tool
will find the debug information inside the binaries.
By default, ``abipkgdiff`` uses debug information in `DWARF`_ format,
if present, otherwise it compares binaries interfaces using debug
information in `CTF`_ format, if present, finally, if neither is
found, it uses only `ELF`_ symbols to report which of them were added
or removed.
information in `CTF`_ or in `BTF`_ formats, if present. Finally, if no
debug info in these formats is found, it only considers `ELF`_ symbols
and report about their addition or removal.
.. include:: tools-use-libabigail.txt
@ -554,6 +554,11 @@ Options
This is used to compare packages with `CTF`_ debug information,
if present.
* ``--btf``
This is used to compare packages with `BTF`_ debug information,
if present.
.. _abipkgdiff_return_value_label:
Return value
@ -573,6 +578,7 @@ In the later case, the value of the exit code is the same as for the
.. _tar: https://en.wikipedia.org/wiki/Tar_%28computing%29
.. _DWARF: http://www.dwarfstd.org
.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
.. _BTF: https://docs.kernel.org/bpf/btf.html
.. _Development Package: https://fedoraproject.org/wiki/Packaging:Guidelines?rd=Packaging/Guidelines#Devel_Packages
.. _ODR: https://en.wikipedia.org/wiki/One_Definition_Rule
.. _One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule

View File

@ -74,10 +74,11 @@ functions and variables) between the Kernel and its modules. In
practice, though, some users might want to compare a subset of the
those interfaces.
By default, ``kmidiff`` uses debug information in `DWARF`_ format,
if present, otherwise it compares interfaces using debug information
in `CTF`_ format, if present, finally, if neither is found, it uses
only `ELF`_ symbols to report which were added or removed.
By default, ``kmidiff`` uses debug information in the `DWARF`_ debug
info format, if present, otherwise it compares interfaces using `CTF`_
or `BTF`_ debug info formats, if present. Finally, if no debug info
in these formats is found, it only considers `ELF`_ symbols and report
about their addition or removal.
Users can then define a "white list" of the interfaces to compare.
Such a white list is a just a file in the "INI" format that looks
@ -179,8 +180,13 @@ Options
* ``--ctf``
Extract ABI information from `CTF`_ debug information, if present in
the Kernel and Modules.
Extract ABI information from `CTF`_ debug information, if present,
in the Kernel and Modules.
* ``--btf``
Extract ABI information from `BTF`_ debug information, if present,
in the Kernel and Modules.
* ``--impacted-interfaces | -i``
@ -249,3 +255,4 @@ Options
.. _Linux Kernel: https://kernel.org
.. _DWARF: http://www.dwarfstd.org
.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf
.. _BTF: https://docs.kernel.org/bpf/btf.html

View File

@ -34,4 +34,8 @@ if CTF_READER
pkginclude_HEADERS += abg-ctf-reader.h
endif
if BTF_READER
pkginclude_HEADERS += abg-btf-reader.h
endif
EXTRA_DIST = abg-version.h.in

34
include/abg-btf-reader.h Normal file
View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2022 Red Hat, Inc.
//
// Author: Dodji Seketeli
/// @file
///
/// This file contains the declarations of the front-end to analyze the
/// BTF information contained in an ELF file.
#ifndef __ABG_BTF_READER_H__
#define __ABG_BTF_READER_H__
#include "abg-elf-based-reader.h"
namespace abigail
{
namespace btf
{
elf_based_reader_sptr
create_reader(const std::string& elf_path,
const vector<char**>& debug_info_root_paths,
environment& env,
bool load_all_types = false,
bool linux_kernel_mode = false);
}//end namespace btf
}//end namespace abigail
#endif //__ABG_BTF_READER_H__

View File

@ -48,7 +48,8 @@ public:
ELF_ORIGIN = 1 << 1,
DWARF_ORIGIN = 1 << 2,
CTF_ORIGIN = 1 << 3,
LINUX_KERNEL_BINARY_ORIGIN = 1 << 4
BTF_ORIGIN = 1 << 4,
LINUX_KERNEL_BINARY_ORIGIN = 1 << 5
};
private:

View File

@ -97,6 +97,9 @@ class reader : public fe_iface
bool
has_ctf_debug_info() const;
bool
has_btf_debug_info() const;
const Dwarf*
alternate_dwarf_debug_info() const;
@ -118,6 +121,9 @@ class reader : public fe_iface
const Elf_Scn*
find_alternate_ctf_section() const;
const Elf_Scn*
find_btf_section() const;
const vector<string>&
dt_needed()const;

View File

@ -41,6 +41,8 @@ bool file_has_dwarf_debug_info(const string& elf_file_path,
const vector<char**>& debug_info_root_paths);
bool file_has_ctf_debug_info(const string& elf_file_path,
const vector<char**>& debug_info_root_paths);
bool file_has_btf_debug_info(const string& elf_file_path,
const vector<char**>& debug_info_root_paths);
bool is_dir(const string&);
bool dir_exists(const string&);
bool dir_is_empty(const string &);

View File

@ -48,6 +48,10 @@ if CTF_READER
libabigail_la_SOURCES += abg-ctf-reader.cc
endif
if BTF_READER
libabigail_la_SOURCES += abg-btf-reader.cc
endif
libabigail_la_LIBADD = $(DEPS_LIBS) $(FTS_LIBS)
libabigail_la_LDFLAGS = -lpthread -Wl,--as-needed -no-undefined -version-info $(LIBABIGAIL_SO_CURRENT):$(LIBABIGAIL_SO_REVISION):$(LIBABIGAIL_SO_AGE)

1102
src/abg-btf-reader.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -274,6 +274,7 @@ struct reader::priv
int alt_ctf_fd = 0;
Elf* alt_ctf_handle = nullptr;
Elf_Scn* alt_ctf_section = nullptr;
Elf_Scn* btf_section = nullptr;
priv(reader& reeder, const std::string& elf_path,
const vector<char**>& debug_info_roots)
@ -602,6 +603,13 @@ bool
reader::has_ctf_debug_info() const
{return (priv_->ctf_section != nullptr);}
/// Test if the binary has BTF debug info.
///
/// @return true iff the binary has BTF debug info
bool
reader::has_btf_debug_info() const
{return (priv_->btf_section != nullptr);}
/// Getter of the handle use to access DWARF information from the
/// alternate split DWARF information.
///
@ -697,6 +705,20 @@ reader::find_alternate_ctf_section() const
return priv_->alt_ctf_section;
}
/// Find and return a pointer to the BTF section of the current ELF
/// file.
///
/// @return a pointer to the BTF section of the current ELF file.
const Elf_Scn*
reader::find_btf_section() const
{
if (priv_->btf_section == nullptr)
priv_->btf_section =
elf_helpers::find_section(priv_->elf_handle,
".BTF", SHT_PROGBITS);
return priv_->btf_section;
}
/// Get the value of the DT_NEEDED property of the current ELF file.
///
/// @return the value of the DT_NEEDED property.

View File

@ -47,6 +47,9 @@
#ifdef WITH_CTF
#include "abg-ctf-reader.h"
#endif
#ifdef WITH_BTF
#include "abg-btf-reader.h"
#endif
#include "abg-internal.h"
#include "abg-regex.h"
@ -504,6 +507,34 @@ file_has_ctf_debug_info(const string& elf_file_path,
return false;
}
/// Test if an ELF file has BTFG debug info.
///
/// @param elf_file_path the path to the ELF file to consider.
///
/// @param debug_info_root a vector of pointer to directory to look
/// for debug info, in case the file is associated to split debug
/// info. If there is no split debug info then this vector can be
/// empty. Note that convert_char_stars_to_char_star_stars() can be
/// used to ease the construction of this vector.
///
/// @return true iff the ELF file at @elf_file_path is an ELF file
/// that contains debug info.
bool
file_has_btf_debug_info(const string& elf_file_path,
const vector<char**>& debug_info_root_paths)
{
if (guess_file_type(elf_file_path) != FILE_TYPE_ELF)
return false;
environment env;
elf::reader r(elf_file_path, debug_info_root_paths, env);
if (r.find_btf_section())
return true;
return false;
}
/// Tests if a given path is a directory or a symbolic link to a
/// directory.
///
@ -2850,6 +2881,13 @@ create_best_elf_based_reader(const string& elf_file_path,
#ifdef WITH_CTF
if (file_has_ctf_debug_info(elf_file_path, debug_info_root_paths))
result = ctf::create_reader(elf_file_path, debug_info_root_paths, env);
#endif
}
else if (requested_fe_kind & corpus::BTF_ORIGIN)
{
#ifdef WITH_BTF
if (file_has_btf_debug_info(elf_file_path, debug_info_root_paths))
result = btf::create_reader(elf_file_path, debug_info_root_paths, env);
#endif
}
else
@ -2862,6 +2900,14 @@ create_best_elf_based_reader(const string& elf_file_path,
// front end even if it wasn't formally requested by the user.
result = ctf::create_reader(elf_file_path, debug_info_root_paths, env);
#endif
#ifdef WITH_BTF
if (!file_has_dwarf_debug_info(elf_file_path, debug_info_root_paths)
&& file_has_btf_debug_info(elf_file_path, debug_info_root_paths))
// The file has BTF debug info and no BTF, let's use the BTF
// front-end even if it wasn't formally requested by the user.
result = btf::create_reader(elf_file_path, debug_info_root_paths, env);
#endif
}
if (!result)

View File

@ -30,6 +30,10 @@ if CTF_READER
TESTS += runtestreadctf
endif
if BTF_READER
TESTS += runtestreadbtf
endif
# rather cheap tests
TESTS+= \
runtestabicompat \
@ -111,6 +115,13 @@ runtestreadctf_LDADD=libtestreadcommon.la libtestutils.la \
runtestreadctf_LDFLAGS=-pthread
endif
if BTF_READER
runtestreadbtf_SOURCES=test-read-btf.cc
runtestreadbtf_LDADD=libtestreadcommon.la libtestutils.la \
$(top_builddir)/src/libabigail.la
runtestreadbtf_LDFLAGS=-pthread
endif
runtestannotate_SOURCES=test-annotate.cc
runtestannotate_LDADD=libtestutils.la $(top_builddir)/src/libabigail.la

View File

@ -242,6 +242,12 @@ test-abidiff-exit/test-rhbz2114909-v0.o \
test-abidiff-exit/test-rhbz2114909-v1.cc \
test-abidiff-exit/test-rhbz2114909-v1.o \
test-abidiff-exit/test-rhbz2114909-report-1.txt \
test-abidiff-exit/btf/test0-report-1.txt \
test-abidiff-exit/btf/test0-report-2.txt \
test-abidiff-exit/btf/test0-v0.c \
test-abidiff-exit/btf/test0-v0.o \
test-abidiff-exit/btf/test0-v1.c \
test-abidiff-exit/btf/test0-v1.o \
\
test-diff-dwarf/test0-v0.cc \
test-diff-dwarf/test0-v0.o \
@ -721,6 +727,13 @@ test-read-ctf/test-array-size.abi \
test-read-ctf/test-array-size.c \
test-read-ctf/test-array-size.o \
\
test-read-btf/test0.c \
test-read-btf/test0.o \
test-read-btf/test0.o.abi \
test-read-btf/test1.c \
test-read-btf/test1.o \
test-read-btf/test1.o.abi \
\
test-annotate/test0.abi \
test-annotate/test1.abi \
test-annotate/test2.so.abi \

View File

@ -0,0 +1,16 @@
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added variable
1 function with some indirect sub-type change:
[C] 'function void fn0(const foo_type*)' has some indirect sub-type changes:
return type changed:
type name changed from 'void' to 'int'
type size changed from 0 to 32 (in bits)
mangled name changed from '' to int
parameter 1 of type 'const foo_type*' changed:
in pointed to type 'const foo_type':
entity changed from 'const foo_type' to 'typedef foo_type'
type size hasn't changed
parameter 2 of type 'int' was added

View File

@ -0,0 +1,53 @@
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 1 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C] 'function void fn0(const foo_type*)' has some indirect sub-type changes:
return type changed:
type name changed from 'void' to 'int'
type size changed from 0 to 32 (in bits)
mangled name changed from '' to int
parameter 1 of type 'const foo_type*' changed:
in pointed to type 'const foo_type':
entity changed from 'const foo_type' to 'typedef foo_type'
type size hasn't changed
parameter 2 of type 'int' was added
1 Changed variable:
[C] 'foo_type foos[2]' was changed:
type of variable changed:
array element type 'struct foo_type' changed:
type size hasn't changed
2 data member changes:
type of 'const int* m0' changed:
in pointed to type 'const int':
entity changed from 'const int' to 'int'
type size hasn't changed
type of 'volatile const u_type* m5' changed:
in pointed to type 'volatile const u_type':
in unqualified underlying type 'typedef u_type':
underlying type 'union u_type' changed:
type size hasn't changed
1 data member insertion:
'char* m2'
2 data member changes:
type of 'ENUM_TYPE* m0' changed:
in pointed to type 'typedef ENUM_TYPE':
underlying type 'enum ENUM_TYPE' changed:
type size hasn't changed
1 enumerator insertion:
'ENUM_TYPE::E2_ENUM_TYPE' value '2'
type of 'ANOTHER_ENUM_TYPE* m1' changed:
in pointed to type 'typedef ANOTHER_ENUM_TYPE':
underlying type 'enum ANOTHER_ENUM_TYPE' changed:
type size hasn't changed
1 enumerator insertion:
'ANOTHER_ENUM_TYPE::E2_ANOTHER_ENUM_TYPE' value '2'
type changed from:
union u_type{ENUM_TYPE* m0; ANOTHER_ENUM_TYPE* m1;}
to:
union u_type{ENUM_TYPE* m0; ANOTHER_ENUM_TYPE* m1; char* m2;}
type size hasn't changed

View File

@ -0,0 +1,40 @@
/*
* Compile this to emit BTF debug info with:
*
* gcc -c -gbtf test0.c
*/
typedef enum ENUM_TYPE
{
E0_ENUM_TYPE = 0,
E1_ENUM_TYPE= 1
} ENUM_TYPE;
typedef enum ANOTHER_ENUM_TYPE
{
E0_ANOTHER_ENUM_TYPE = 0,
E1_ANOTHER_ENUM_TYPE= 1
} ANOTHER_ENUM_TYPE;
typedef union u_type
{
ENUM_TYPE *m0;
ANOTHER_ENUM_TYPE *m1;
} u_type;
typedef struct foo_type
{
const int *m0;
volatile char *m1;
unsigned *m2;
const volatile unsigned char *m3;
float m4[10];
volatile const u_type *m5;
} foo_type;
void
fn0(const foo_type* p __attribute__((unused)))
{
}
struct foo_type foos[2] = {0};

Binary file not shown.

View File

@ -0,0 +1,45 @@
/*
* Compile this to emit BTF debug info with:
*
* gcc -c -gbtf test0.c
*/
typedef enum ENUM_TYPE
{
E0_ENUM_TYPE = 0,
E1_ENUM_TYPE= 1,
E2_ENUM_TYPE= 2
} ENUM_TYPE;
typedef enum ANOTHER_ENUM_TYPE
{
E0_ANOTHER_ENUM_TYPE = 0,
E1_ANOTHER_ENUM_TYPE= 1,
E2_ANOTHER_ENUM_TYPE= 2
} ANOTHER_ENUM_TYPE;
typedef union u_type
{
ENUM_TYPE *m0;
ANOTHER_ENUM_TYPE *m1;
char *m2;
} u_type;
typedef struct foo_type
{
int *m0;
volatile char *m1;
unsigned *m2;
const volatile unsigned char *m3;
float m4[10];
volatile const u_type *m5;
} foo_type;
int
fn0(foo_type* p, int a)
{
*p->m0 = a;
return a;
}
struct foo_type foos[2] = {0};

Binary file not shown.

View File

@ -0,0 +1,40 @@
/*
* Compile this to emit BTF debug info with:
*
* gcc -c -gbtf test0.c
*/
typedef enum ENUM_TYPE
{
E0_ENUM_TYPE = 0,
E1_ENUM_TYPE= 1
} ENUM_TYPE;
typedef enum ANOTHER_ENUM_TYPE
{
E0_ANOTHER_ENUM_TYPE = 0,
E1_ANOTHER_ENUM_TYPE= 1
} ANOTHER_ENUM_TYPE;
typedef union u_type
{
ENUM_TYPE *m0;
ANOTHER_ENUM_TYPE *m1;
} u_type;
typedef struct foo_type
{
const int *m0;
volatile char *m1;
unsigned *m2;
const volatile unsigned char *m3;
float m4[10];
volatile const u_type *m5;
} foo_type;
void
fn0(const foo_type* p __attribute__((unused)))
{
}
struct foo_type foos[2] = {0};

Binary file not shown.

View File

@ -0,0 +1,90 @@
<abi-corpus version='2.1' path='data/test-read-btf/test0.o'>
<elf-function-symbols>
<elf-symbol name='fn0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<elf-variable-symbols>
<elf-symbol name='foos' size='160' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-variable-symbols>
<abi-instr address-size='64'>
<type-decl name='char' size-in-bits='8' id='type-id-1'/>
<enum-decl name='ANOTHER_ENUM_TYPE' linkage-name='ANOTHER_ENUM_TYPE' id='type-id-2'>
<underlying-type type-id='type-id-3'/>
<enumerator name='E0_ANOTHER_ENUM_TYPE' value='0'/>
<enumerator name='E1_ANOTHER_ENUM_TYPE' value='1'/>
</enum-decl>
<enum-decl name='ENUM_TYPE' linkage-name='ENUM_TYPE' id='type-id-4'>
<underlying-type type-id='type-id-5'/>
<enumerator name='E0_ENUM_TYPE' value='0'/>
<enumerator name='E1_ENUM_TYPE' value='1'/>
</enum-decl>
<type-decl name='enum-ANOTHER_ENUM_TYPE-underlying-type-32' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
<type-decl name='enum-ENUM_TYPE-underlying-type-32' size-in-bits='32' alignment-in-bits='32' id='type-id-5'/>
<type-decl name='float' size-in-bits='32' id='type-id-6'/>
<array-type-def dimensions='1' type-id='type-id-6' size-in-bits='320' id='type-id-7'>
<subrange length='10' id='type-id-8'/>
</array-type-def>
<array-type-def dimensions='1' type-id='type-id-9' size-in-bits='1280' id='type-id-10'>
<subrange length='2' id='type-id-11'/>
</array-type-def>
<type-decl name='int' size-in-bits='32' id='type-id-12'/>
<class-decl name='foo_type' size-in-bits='640' is-struct='yes' visibility='default' id='type-id-9'>
<data-member access='public' layout-offset-in-bits='0'>
<var-decl name='m0' type-id='type-id-13' visibility='default'/>
</data-member>
<data-member access='public' layout-offset-in-bits='64'>
<var-decl name='m1' type-id='type-id-14' visibility='default'/>
</data-member>
<data-member access='public' layout-offset-in-bits='128'>
<var-decl name='m2' type-id='type-id-15' visibility='default'/>
</data-member>
<data-member access='public' layout-offset-in-bits='192'>
<var-decl name='m3' type-id='type-id-16' visibility='default'/>
</data-member>
<data-member access='public' layout-offset-in-bits='256'>
<var-decl name='m4' type-id='type-id-7' visibility='default'/>
</data-member>
<data-member access='public' layout-offset-in-bits='576'>
<var-decl name='m5' type-id='type-id-17' visibility='default'/>
</data-member>
</class-decl>
<typedef-decl name='ANOTHER_ENUM_TYPE' type-id='type-id-2' id='type-id-18'/>
<typedef-decl name='ENUM_TYPE' type-id='type-id-4' id='type-id-19'/>
<typedef-decl name='foo_type' type-id='type-id-9' id='type-id-20'/>
<typedef-decl name='u_type' type-id='type-id-21' id='type-id-22'/>
<union-decl name='u_type' size-in-bits='64' visibility='default' id='type-id-21'>
<data-member access='public'>
<var-decl name='m0' type-id='type-id-23' visibility='default'/>
</data-member>
<data-member access='public'>
<var-decl name='m1' type-id='type-id-24' visibility='default'/>
</data-member>
</union-decl>
<type-decl name='unsigned char' size-in-bits='8' id='type-id-25'/>
<type-decl name='unsigned int' size-in-bits='32' id='type-id-26'/>
<pointer-type-def type-id='type-id-18' size-in-bits='64' id='type-id-24'/>
<pointer-type-def type-id='type-id-19' size-in-bits='64' id='type-id-23'/>
<qualified-type-def type-id='type-id-20' const='yes' id='type-id-27'/>
<pointer-type-def type-id='type-id-27' size-in-bits='64' id='type-id-28'/>
<qualified-type-def type-id='type-id-12' const='yes' id='type-id-29'/>
<pointer-type-def type-id='type-id-29' size-in-bits='64' id='type-id-13'/>
<qualified-type-def type-id='type-id-22' const='yes' id='type-id-30'/>
<qualified-type-def type-id='type-id-25' const='yes' id='type-id-31'/>
<pointer-type-def type-id='type-id-26' size-in-bits='64' id='type-id-15'/>
<qualified-type-def type-id='type-id-1' volatile='yes' id='type-id-32'/>
<pointer-type-def type-id='type-id-32' size-in-bits='64' id='type-id-14'/>
<qualified-type-def type-id='type-id-30' volatile='yes' id='type-id-33'/>
<pointer-type-def type-id='type-id-33' size-in-bits='64' id='type-id-17'/>
<qualified-type-def type-id='type-id-31' volatile='yes' id='type-id-34'/>
<pointer-type-def type-id='type-id-34' size-in-bits='64' id='type-id-16'/>
<var-decl name='foos' type-id='type-id-10' mangled-name='foos' visibility='default' elf-symbol-id='foos'/>
<function-decl name='fn0' mangled-name='fn0' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fn0'>
<parameter type-id='type-id-28' name='p'/>
<return type-id='type-id-35'/>
</function-decl>
<type-decl name='void' id='type-id-35'/>
<function-type size-in-bits='64' id='type-id-36'>
<parameter type-id='type-id-28' name='p'/>
<return type-id='type-id-35'/>
</function-type>
</abi-instr>
</abi-corpus>

View File

@ -0,0 +1,20 @@
/*
* Compile this to emit BTF debug info with:
*
* gcc -c -gbtf test0.c
*/
struct S;
typedef struct S S;
union U;
typedef union U U;
S*
fn0(S* p, U* u)
{
if (u)
;
return p;
}

Binary file not shown.

View File

@ -0,0 +1,23 @@
<abi-corpus version='2.1' path='data/test-read-btf/test1.o'>
<elf-function-symbols>
<elf-symbol name='fn0' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<abi-instr address-size='64'>
<typedef-decl name='S' type-id='type-id-1' id='type-id-2'/>
<typedef-decl name='U' type-id='type-id-3' id='type-id-4'/>
<pointer-type-def type-id='type-id-2' size-in-bits='64' id='type-id-5'/>
<pointer-type-def type-id='type-id-4' size-in-bits='64' id='type-id-6'/>
<function-decl name='fn0' mangled-name='fn0' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fn0'>
<parameter type-id='type-id-5' name='p'/>
<parameter type-id='type-id-6' name='u'/>
<return type-id='type-id-5'/>
</function-decl>
<class-decl name='S' size-in-bits='48' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1'/>
<union-decl name='U' visibility='default' is-declaration-only='yes' id='type-id-3'/>
<function-type size-in-bits='64' id='type-id-7'>
<parameter type-id='type-id-5' name='p'/>
<parameter type-id='type-id-6' name='u'/>
<return type-id='type-id-5'/>
</function-type>
</abi-instr>
</abi-corpus>

View File

@ -471,6 +471,30 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-rhbz2114909-report-1.txt",
"output/test-abidiff-exit/test-rhbz2114909-report-1.txt"
},
#ifdef WITH_BTF
{
"data/test-abidiff-exit/btf/test0-v0.o",
"data/test-abidiff-exit/btf/test0-v1.o",
"",
"",
"",
"--no-default-suppression --btf",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/btf/test0-report-1.txt",
"output/test-abidiff-exit/btf/test0-report-1.txt"
},
{
"data/test-abidiff-exit/btf/test0-v0.o",
"data/test-abidiff-exit/btf/test0-v1.o",
"",
"",
"",
"--no-default-suppression --harmless --btf",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/btf/test0-report-2.txt",
"output/test-abidiff-exit/btf/test0-report-2.txt"
},
#endif
{0, 0, 0 ,0, 0, 0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
};

188
tests/test-read-btf.cc Normal file
View File

@ -0,0 +1,188 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2022 Red Hat, Inc.
//
// Author: Dodji Seketeli
/// @file
///
/// This file is part of the BTF testsuite. It reads ELF binaries
/// containing BTF, save them in XML corpus files and diff the
/// corpus files against reference XML corpus files.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "abg-btf-reader.h"
#include "test-read-common.h"
using std::string;
using std::cerr;
using std::vector;
using abigail::tests::read_common::InOutSpec;
using abigail::tests::read_common::test_task;
using abigail::tests::read_common::display_usage;
using abigail::tests::read_common::options;
using abigail::btf::create_reader;
using abigail::xml_writer::SEQUENCE_TYPE_ID_STYLE;
using abigail::xml_writer::HASH_TYPE_ID_STYLE;
using abigail::tools_utils::emit_prefix;
static InOutSpec in_out_specs[] =
{
{
"data/test-read-btf/test0.o",
"",
"",
SEQUENCE_TYPE_ID_STYLE,
"data/test-read-btf/test0.o.abi",
"output/test-read-btf/test0.o.abi",
"--btf",
},
{
"data/test-read-btf/test1.o",
"",
"",
SEQUENCE_TYPE_ID_STYLE,
"data/test-read-btf/test1.o.abi",
"output/test-read-btf/test1.o.abi",
"--btf",
},
// This should be the last entry.
{NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL}
};
/// Task specialization to perform BTF tests.
struct test_task_btf : public test_task
{
test_task_btf(const InOutSpec &s,
string& a_out_abi_base,
string& a_in_elf_base,
string& a_in_abi_base);
virtual void
perform();
virtual
~test_task_btf()
{}
}; // end struct test_task_btf
/// Constructor.
///
/// Task to be executed for each BTF test entry in @ref
/// abigail::tests::read_common::InOutSpec.
/// @param InOutSpec the array containing set of tests.
///
/// @param a_out_abi_base the output base directory for abixml files.
///
/// @param a_in_elf_base the input base directory for object files.
///
/// @param a_in_elf_base the input base directory for expected
/// abixml files.
test_task_btf::test_task_btf(const InOutSpec &s,
string& a_out_abi_base,
string& a_in_elf_base,
string& a_in_abi_base)
: test_task(s, a_out_abi_base, a_in_elf_base, a_in_abi_base)
{}
/// The thread function to execute each BTF test entry in @ref
/// abigail::tests::read_common::InOutSpec.
///
/// This reads the corpus into memory, saves it to disk, loads it
/// again and compares the new in-memory representation against the
void
test_task_btf::perform()
{
abigail::ir::environment env;
set_in_elf_path();
set_in_suppr_spec_path();
abigail::fe_iface::status status =
abigail::fe_iface::STATUS_UNKNOWN;
vector<char**> di_roots;
ABG_ASSERT(abigail::tools_utils::file_exists(in_elf_path));
abigail::elf_based_reader_sptr rdr = abigail::btf::create_reader(in_elf_path,
di_roots, env);
ABG_ASSERT(rdr);
corpus_sptr corp = rdr->read_corpus(status);
// if there is no output and no input, assume that we do not care about the
// actual read result, just that it succeeded.
if (!spec.in_abi_path && !spec.out_abi_path)
{
// Phew! we made it here and we did not crash! yay!
return;
}
if (!corp)
{
error_message = string("failed to read ") + in_elf_path + "\n";
is_ok = false;
return;
}
corp->set_path(spec.in_elf_path);
// Do not take architecture names in comparison so that these
// test input binaries can come from whatever arch the
// programmer likes.
corp->set_architecture_name("");
if (!(is_ok = set_out_abi_path()))
return;
if (!(is_ok = serialize_corpus(out_abi_path, corp)))
return;
if (!(is_ok = run_abidw("--btf ")))
return;
if (!(is_ok = run_diff()))
return;
}
/// Create a new BTF instance for task to be execute by the testsuite.
///
/// @param s the @ref abigail::tests::read_common::InOutSpec
/// tests container.
///
/// @param a_out_abi_base the output base directory for abixml files.
///
/// @param a_in_elf_base the input base directory for object files.
///
/// @param a_in_abi_base the input base directory for abixml files.
///
/// @return abigail::tests::read_common::test_task instance.
static test_task*
new_task(const InOutSpec* s, string& a_out_abi_base,
string& a_in_elf_base, string& a_in_abi_base)
{
return new test_task_btf(*s, a_out_abi_base,
a_in_elf_base, a_in_abi_base);
}
int
main(int argc, char *argv[])
{
options opts;
if (!parse_command_line(argc, argv, opts))
{
if (!opts.wrong_option.empty())
emit_prefix(argv[0], cerr)
<< "unrecognized option: " << opts.wrong_option << "\n";
display_usage(argv[0], cerr);
return 1;
}
// compute number of tests to be executed.
const size_t num_tests = sizeof(in_out_specs) / sizeof(InOutSpec) - 1;
return run_tests(num_tests, in_out_specs, opts, new_task);
}

View File

@ -23,6 +23,10 @@
#include "abg-ctf-reader.h"
#endif
#ifdef WITH_BTF
#include "abg-btf-reader.h"
#endif
using std::vector;
using std::string;
using std::ostream;
@ -121,6 +125,9 @@ struct options
#endif
#ifdef WITH_CTF
bool use_ctf;
#endif
#ifdef WITH_BTF
bool use_btf;
#endif
vector<char*> di_root_paths1;
vector<char*> di_root_paths2;
@ -170,6 +177,10 @@ struct options
,
use_ctf()
#endif
#ifdef WITH_BTF
,
use_btf()
#endif
#ifdef WITH_DEBUG_SELF_COMPARISON
,
do_debug_self_comparison()
@ -273,6 +284,9 @@ display_usage(const string& prog_name, ostream& out)
#ifdef WITH_CTF
<< " --ctf use CTF instead of DWARF in ELF files\n"
#endif
#ifdef WITH_BTF
<< " --btf use BTF instead of DWARF in ELF files\n"
#endif
#ifdef WITH_DEBUG_SELF_COMPARISON
<< " --debug-self-comparison debug the process of comparing "
"an ABI corpus against itself"
@ -639,6 +653,10 @@ parse_command_line(int argc, char* argv[], options& opts)
else if (!strcmp(argv[i], "--ctf"))
opts.use_ctf = true;
#endif
#ifdef WITH_BTF
else if (!strcmp(argv[i], "--btf"))
opts.use_btf = true;
#endif
#ifdef WITH_DEBUG_SELF_COMPARISON
else if (!strcmp(argv[i], "--debug-self-comparison"))
opts.do_debug_self_comparison = true;
@ -1232,6 +1250,10 @@ main(int argc, char* argv[])
#ifdef WITH_CTF
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
abigail::elf_based_reader_sptr rdr =
create_best_elf_based_reader(opts.file1,
@ -1305,6 +1327,10 @@ main(int argc, char* argv[])
#ifdef WITH_CTF
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
abigail::elf_based_reader_sptr rdr =
create_best_elf_based_reader(opts.file2,

View File

@ -29,6 +29,9 @@
#ifdef WITH_CTF
#include "abg-ctf-reader.h"
#endif
#ifdef WITH_BTF
#include "abg-btf-reader.h"
#endif
#include "abg-writer.h"
#include "abg-reader.h"
#include "abg-comparison.h"
@ -103,6 +106,9 @@ struct options
bool noout;
#ifdef WITH_CTF
bool use_ctf;
#endif
#ifdef WITH_BTF
bool use_btf;
#endif
bool show_locs;
bool abidiff;
@ -144,6 +150,9 @@ struct options
noout(),
#ifdef WITH_CTF
use_ctf(false),
#endif
#ifdef WITH_BTF
use_btf(false),
#endif
show_locs(true),
abidiff(),
@ -234,6 +243,9 @@ display_usage(const string& prog_name, ostream& out)
"speed-up the analysis of the binary\n"
<< " --no-assume-odr-for-cplusplus do not assume the ODR to speed-up the "
"analysis of the binary\n"
#ifdef WITH_BTF
<< " --btf use BTF instead of DWARF in ELF files\n"
#endif
<< " --annotate annotate the ABI artifacts emitted in the output\n"
<< " --stats show statistics about various internal stuff\n"
<< " --verbose show verbose messages about internal stuff\n";
@ -335,6 +347,10 @@ parse_command_line(int argc, char* argv[], options& opts)
#ifdef WITH_CTF
else if (!strcmp(argv[i], "--ctf"))
opts.use_ctf = true;
#endif
#ifdef WITH_BTF
else if (!strcmp(argv[i], "--btf"))
opts.use_btf = true;
#endif
else if (!strcmp(argv[i], "--no-architecture"))
opts.write_architecture = false;
@ -588,6 +604,10 @@ load_corpus_and_write_abixml(char* argv[],
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
// First of all, create a reader to read the ABI from the file
// specfied in opts ...

View File

@ -93,6 +93,9 @@
#ifdef WITH_CTF
#include "abg-ctf-reader.h"
#endif
#ifdef WITH_BTF
#include "abg-btf-reader.h"
#endif
using std::cout;
using std::cerr;
@ -212,6 +215,9 @@ public:
#ifdef WITH_CTF
bool use_ctf;
#endif
#ifdef WITH_BTF
bool use_btf;
#endif
vector<string> kabi_whitelist_packages;
vector<string> suppression_paths;
@ -256,6 +262,10 @@ public:
#ifdef WITH_CTF
,
use_ctf()
#endif
#ifdef WITH_BTF
,
use_btf()
#endif
{
// set num_workers to the default number of threads of the
@ -905,6 +915,9 @@ display_usage(const string& prog_name, ostream& out)
"binaries inside the input package against their ABIXML representation\n"
#ifdef WITH_CTF
<< " --ctf use CTF instead of DWARF in ELF files\n"
#endif
#ifdef WITH_BTF
<< " --btf use BTF instead of DWARF in ELF files\n"
#endif
<< " --help|-h display this help message\n"
<< " --version|-v display program version information"
@ -1353,6 +1366,10 @@ compare(const elf_file& elf1,
#ifdef WITH_CTF
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
abigail::elf_based_reader_sptr reader =
create_best_elf_based_reader(elf1.path,
@ -1414,6 +1431,11 @@ compare(const elf_file& elf1,
if (opts.use_ctf)
;
else
#endif
#ifdef WITH_BTF
if (opts.use_btf)
;
else
#endif
reader->refers_to_alt_debug_info(alt_di_path);
if (!alt_di_path.empty())
@ -1449,10 +1471,16 @@ compare(const elf_file& elf1,
corpus_sptr corpus2;
{
corpus::origin requested_fe_kind = corpus::DWARF_ORIGIN;
#ifdef WITH_CTF
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
abigail::elf_based_reader_sptr reader =
create_best_elf_based_reader(elf2.path,
di_dirs2,
@ -1513,6 +1541,11 @@ compare(const elf_file& elf1,
if (opts.use_ctf)
;
else
#endif
#ifdef WITH_BTF
if (opts.use_btf)
;
else
#endif
reader->refers_to_alt_debug_info(alt_di_path);
if (!alt_di_path.empty())
@ -1617,6 +1650,10 @@ compare_to_self(const elf_file& elf,
#ifdef WITH_CTF
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
abigail::elf_based_reader_sptr reader =
create_best_elf_based_reader(elf.path,
@ -3044,14 +3081,24 @@ compare_prepared_linux_kernel_packages(package& first_package,
suppressions_type supprs;
corpus_group_sptr corpus1, corpus2;
corpus::origin requested_fe_kind = corpus::DWARF_ORIGIN;
#ifdef WITH_CTF
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
corpus1 = build_corpus_group_from_kernel_dist_under(dist_root1,
debug_dir1,
vmlinux_path1,
opts.suppression_paths,
opts.kabi_whitelist_paths,
supprs,
opts.verbose,
env);
supprs, opts.verbose,
env, requested_fe_kind);
if (!corpus1)
return abigail::tools_utils::ABIDIFF_ERROR;
@ -3061,9 +3108,8 @@ compare_prepared_linux_kernel_packages(package& first_package,
vmlinux_path2,
opts.suppression_paths,
opts.kabi_whitelist_paths,
supprs,
opts.verbose,
env);
supprs, opts.verbose,
env, requested_fe_kind);
if (!corpus2)
return abigail::tools_utils::ABIDIFF_ERROR;
@ -3434,6 +3480,10 @@ parse_command_line(int argc, char* argv[], options& opts)
#ifdef WITH_CTF
else if (!strcmp(argv[i], "--ctf"))
opts.use_ctf = true;
#endif
#ifdef WITH_BTF
else if (!strcmp(argv[i], "--btf"))
opts.use_btf = true;
#endif
else if (!strcmp(argv[i], "--help")
|| !strcmp(argv[i], "-h"))

View File

@ -63,6 +63,9 @@ struct options
optional<bool> exported_interfaces_only;
#ifdef WITH_CTF
bool use_ctf;
#endif
#ifdef WITH_BTF
bool use_btf;
#endif
string wrong_option;
string kernel_dist_root1;
@ -88,6 +91,10 @@ struct options
#ifdef WITH_CTF
,
use_ctf(false)
#endif
#ifdef WITH_BTF
,
use_btf(false)
#endif
{}
}; // end struct options.
@ -117,6 +124,9 @@ display_usage(const string& prog_name, ostream& out)
"whitelist\n"
#ifdef WITH_CTF
<< " --ctf use CTF instead of DWARF in ELF files\n"
#endif
#ifdef WITH_BTF
<< " --btf use BTF instead of DWARF in ELF files\n"
#endif
<< " --impacted-interfaces|-i show interfaces impacted by ABI changes\n"
<< " --full-impact|-f show the full impact of changes on top-most "
@ -259,6 +269,10 @@ parse_command_line(int argc, char* argv[], options& opts)
#ifdef WITH_CTF
else if (!strcmp(argv[i], "--ctf"))
opts.use_ctf = true;
#endif
#ifdef WITH_BTF
else if (!strcmp(argv[i], "--btf"))
opts.use_btf = true;
#endif
else if (!strcmp(argv[i], "--impacted-interfaces")
|| !strcmp(argv[i], "-i"))
@ -421,11 +435,15 @@ main(int argc, char* argv[])
corpus_group_sptr group1, group2;
string debug_info_root_dir;
corpus::origin requested_fe_kind =
corpus::origin requested_fe_kind = corpus::DWARF_ORIGIN;
#ifdef WITH_CTF
opts.use_ctf ? corpus::CTF_ORIGIN :
if (opts.use_ctf)
requested_fe_kind = corpus::CTF_ORIGIN;
#endif
#ifdef WITH_BTF
if (opts.use_btf)
requested_fe_kind = corpus::BTF_ORIGIN;
#endif
corpus::DWARF_ORIGIN;
if (!opts.kernel_dist_root1.empty())
{