mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-11 03:49:29 +00:00
12641b1130
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>
409 lines
8.5 KiB
C++
409 lines
8.5 KiB
C++
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
// -*- mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2023 Red Hat, Inc.
|
|
|
|
/// @file
|
|
|
|
#ifndef __ABG_CORPUS_H__
|
|
#define __ABG_CORPUS_H__
|
|
|
|
#include <abg-ir.h>
|
|
|
|
namespace abigail
|
|
{
|
|
|
|
namespace ir
|
|
{
|
|
|
|
/// This is the abstraction of a set of translation units (themselves
|
|
/// seen as bundles of unitary abi artefacts like types and decls)
|
|
/// bundled together as a corpus. A corpus is thus the Application
|
|
/// binary interface of a program, a library or just a set of modules
|
|
/// put together.
|
|
class corpus
|
|
{
|
|
public:
|
|
/// A convenience typedef for std::vector<string>.
|
|
typedef vector<string> strings_type;
|
|
|
|
/// Convenience typedef for std::vector<abigail::ir::function_decl*>
|
|
typedef vector<function_decl*> functions;
|
|
|
|
///Convenience typedef for std::vector<abigail::ir::var_decl*>
|
|
typedef vector<var_decl*> variables;
|
|
|
|
class exported_decls_builder;
|
|
|
|
/// Convenience typedef for shared_ptr<exported_decls_builder>.
|
|
typedef shared_ptr<exported_decls_builder> exported_decls_builder_sptr;
|
|
|
|
/// This abstracts where the corpus comes from. That is, either it
|
|
/// has been read from the native xml format, from DWARF or built
|
|
/// artificially using the library's API.
|
|
enum origin
|
|
{
|
|
ARTIFICIAL_ORIGIN = 0,
|
|
NATIVE_XML_ORIGIN = 1,
|
|
ELF_ORIGIN = 1 << 1,
|
|
DWARF_ORIGIN = 1 << 2,
|
|
CTF_ORIGIN = 1 << 3,
|
|
BTF_ORIGIN = 1 << 4,
|
|
LINUX_KERNEL_BINARY_ORIGIN = 1 << 5
|
|
};
|
|
|
|
private:
|
|
corpus();
|
|
|
|
void set_group(corpus_group*);
|
|
void init_format_version();
|
|
|
|
public:
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
corpus(const ir::environment&, const string& path= "");
|
|
|
|
virtual ~corpus();
|
|
|
|
const environment&
|
|
get_environment() const;
|
|
|
|
void
|
|
add(const translation_unit_sptr&);
|
|
|
|
const translation_units&
|
|
get_translation_units() const;
|
|
|
|
const translation_unit_sptr
|
|
find_translation_unit(const string &path) const;
|
|
|
|
void
|
|
drop_translation_units();
|
|
|
|
type_maps&
|
|
get_types();
|
|
|
|
const type_maps&
|
|
get_types() const;
|
|
|
|
type_maps&
|
|
get_type_per_loc_map();
|
|
|
|
const type_maps&
|
|
get_type_per_loc_map() const;
|
|
|
|
virtual bool
|
|
recording_types_reachable_from_public_interface_supported();
|
|
|
|
void
|
|
record_type_as_reachable_from_public_interfaces(const type_base&);
|
|
|
|
bool
|
|
type_is_reachable_from_public_interfaces(const type_base&) const;
|
|
|
|
const vector<type_base_wptr>&
|
|
get_types_not_reachable_from_public_interfaces() const;
|
|
|
|
const corpus_group*
|
|
get_group() const;
|
|
|
|
corpus_group*
|
|
get_group();
|
|
|
|
origin
|
|
get_origin() const;
|
|
|
|
void
|
|
set_origin(origin);
|
|
|
|
string&
|
|
get_format_major_version_number() const;
|
|
|
|
void
|
|
set_format_major_version_number(const string&);
|
|
|
|
string&
|
|
get_format_minor_version_number() const;
|
|
|
|
void
|
|
set_format_minor_version_number(const string&);
|
|
|
|
string&
|
|
get_path() const;
|
|
|
|
void
|
|
set_path(const string&);
|
|
|
|
const vector<string>&
|
|
get_needed() const;
|
|
|
|
void
|
|
set_needed(const vector<string>&);
|
|
|
|
const string&
|
|
get_soname();
|
|
|
|
void
|
|
set_soname(const string&);
|
|
|
|
const string&
|
|
get_architecture_name() const;
|
|
|
|
void
|
|
set_architecture_name(const string&);
|
|
|
|
virtual bool
|
|
is_empty() const;
|
|
|
|
bool
|
|
operator==(const corpus&) const;
|
|
|
|
void
|
|
set_symtab(symtab_reader::symtab_sptr);
|
|
|
|
const symtab_reader::symtab_sptr&
|
|
get_symtab() const;
|
|
|
|
virtual const string_elf_symbols_map_type&
|
|
get_fun_symbol_map() const;
|
|
|
|
const string_elf_symbols_map_type&
|
|
get_undefined_fun_symbol_map() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_sorted_fun_symbols() const;
|
|
|
|
const elf_symbols&
|
|
get_sorted_undefined_fun_symbols() const;
|
|
|
|
virtual const string_elf_symbols_map_type&
|
|
get_var_symbol_map() const;
|
|
|
|
const string_elf_symbols_map_type&
|
|
get_undefined_var_symbol_map() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_sorted_var_symbols() const;
|
|
|
|
const elf_symbols&
|
|
get_sorted_undefined_var_symbols() const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_function_symbol(const string& n) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_function_symbol(const string& symbol_name,
|
|
const elf_symbol::version& version) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_function_symbol(const elf_symbol& symbol) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_variable_symbol(const string& n) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_variable_symbol(const string& symbol_name,
|
|
const elf_symbol::version& version) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_variable_symbol(const elf_symbol& symbol) const;
|
|
|
|
virtual const functions&
|
|
get_functions() const;
|
|
|
|
const vector<function_decl*>*
|
|
lookup_functions(const string& id) const;
|
|
|
|
void
|
|
sort_functions();
|
|
|
|
virtual const variables&
|
|
get_variables() const;
|
|
|
|
void
|
|
sort_variables();
|
|
|
|
virtual const elf_symbols&
|
|
get_unreferenced_function_symbols() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_unreferenced_variable_symbols() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_fns_to_suppress();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_fns_to_suppress() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_vars_to_suppress();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_vars_to_suppress() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_fns_to_keep();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_fns_to_keep() const;
|
|
|
|
vector<string>&
|
|
get_sym_ids_of_fns_to_keep();
|
|
|
|
const vector<string>&
|
|
get_sym_ids_of_fns_to_keep() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_vars_to_keep();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_vars_to_keep() const;
|
|
|
|
vector<string>&
|
|
get_sym_ids_of_vars_to_keep();
|
|
|
|
const vector<string>&
|
|
get_sym_ids_of_vars_to_keep() const;
|
|
|
|
void
|
|
maybe_drop_some_exported_decls();
|
|
|
|
exported_decls_builder_sptr
|
|
get_exported_decls_builder() const;
|
|
|
|
friend class type_base;
|
|
friend class corpus_group;
|
|
};// end class corpus.
|
|
|
|
corpus::origin
|
|
operator|(corpus::origin l, corpus::origin r);
|
|
|
|
corpus::origin
|
|
operator|=(corpus::origin &l, corpus::origin r);
|
|
|
|
corpus::origin
|
|
operator&(corpus::origin l, corpus::origin r);
|
|
|
|
corpus::origin
|
|
operator&=(corpus::origin &l, corpus::origin r);
|
|
|
|
/// Abstracts the building of the set of exported variables and
|
|
/// functions.
|
|
///
|
|
/// Given a function or variable, this type can decide if it belongs
|
|
/// to the list of exported functions and variables based on all the
|
|
/// parameters needed.
|
|
class corpus::exported_decls_builder
|
|
{
|
|
class priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
// Forbid default construction.
|
|
exported_decls_builder();
|
|
|
|
public:
|
|
friend class corpus;
|
|
|
|
exported_decls_builder(functions& fns,
|
|
variables& vars,
|
|
strings_type& fns_suppress_regexps,
|
|
strings_type& vars_suppress_regexps,
|
|
strings_type& fns_keep_regexps,
|
|
strings_type& vars_keep_regexps,
|
|
strings_type& sym_id_of_fns_to_keep,
|
|
strings_type& sym_id_of_vars_to_keep);
|
|
|
|
|
|
const functions&
|
|
exported_functions() const;
|
|
|
|
functions&
|
|
exported_functions();
|
|
|
|
const variables&
|
|
exported_variables() const;
|
|
|
|
variables&
|
|
exported_variables();
|
|
|
|
void
|
|
maybe_add_fn_to_exported_fns(const function_decl*);
|
|
|
|
void
|
|
maybe_add_var_to_exported_vars(const var_decl*);
|
|
}; //corpus::exported_decls_builder
|
|
|
|
/// Abstraction of a group of corpora.
|
|
///
|
|
/// A corpus group is a union of corpora. It provides a unified view
|
|
/// of a set of corpora. It lets you get the set of functions,
|
|
/// variables and symbols that are defined and exported by a set of
|
|
/// corpora.
|
|
class corpus_group : public corpus
|
|
{
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
// Forbid copy
|
|
corpus_group(const corpus_group&);
|
|
|
|
public:
|
|
typedef vector<corpus_sptr> corpora_type;
|
|
|
|
corpus_group(const ir::environment&, const string&);
|
|
|
|
virtual ~corpus_group();
|
|
|
|
void add_corpus(const corpus_sptr&);
|
|
|
|
const corpora_type&
|
|
get_corpora() const;
|
|
|
|
const corpus_sptr
|
|
get_main_corpus() const;
|
|
|
|
corpus_sptr
|
|
get_main_corpus();
|
|
|
|
virtual bool
|
|
is_empty() const;
|
|
|
|
virtual const corpus::functions&
|
|
get_functions() const;
|
|
|
|
virtual const corpus::variables&
|
|
get_variables() const;
|
|
|
|
virtual const string_elf_symbols_map_type&
|
|
get_var_symbol_map() const;
|
|
|
|
virtual const string_elf_symbols_map_type&
|
|
get_fun_symbol_map() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_sorted_fun_symbols() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_sorted_var_symbols() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_unreferenced_function_symbols() const;
|
|
|
|
virtual const elf_symbols&
|
|
get_unreferenced_variable_symbols() const;
|
|
|
|
unordered_set<interned_string, hash_interned_string>*
|
|
get_public_types_pretty_representations();
|
|
|
|
virtual bool
|
|
recording_types_reachable_from_public_interface_supported();
|
|
|
|
bool
|
|
operator==(const corpus_group&) const;
|
|
}; // end class corpus_group
|
|
|
|
}// end namespace ir
|
|
}//end namespace abigail
|
|
#endif //__ABG_CORPUS_H__
|