13#include "abg-internal.h"
19#include <unordered_map>
25ABG_BEGIN_EXPORT_DECLARATIONS
31ABG_END_EXPORT_DECLARATIONS
46typedef shared_ptr<reader> reader_sptr;
49btf_offset_to_string(const ::btf* btf,
uint32_t offset)
52 return "__anonymous__";
53 return btf__name_by_offset(btf, offset) ?:
"(invalid string offset)";
58typedef std::unordered_map<int, type_or_decl_base_sptr>
59btf_type_id_to_abi_artifact_map_type;
62class reader :
public elf_based_reader
64 ::btf* btf_handle_ =
nullptr;
66 vector<type_base_sptr> types_to_canonicalize_;
67 btf_type_id_to_abi_artifact_map_type btf_type_id_to_artifacts_;
75 if (btf_handle_ ==
nullptr)
77 btf_handle_ = btf__parse(corpus_path().c_str(),
nullptr);
79 std::cerr <<
"Could not parse BTF information from file '"
80 << corpus_path().c_str() <<
"'" << std::endl;
90 {
return options().env;}
97 {
return const_cast<reader*
>(
this)->env();}
137 btf_type_id_to_abi_artifact_map_type&
138 btf_type_id_to_artifacts()
139 {
return btf_type_id_to_artifacts_;}
146 const btf_type_id_to_abi_artifact_map_type&
147 btf_type_id_to_artifacts()
const
148 {
return btf_type_id_to_artifacts_;}
158 lookup_artifact_from_btf_id(
int btf_id)
160 auto i = btf_type_id_to_artifacts().find(btf_id);
161 if (i != btf_type_id_to_artifacts().end())
174 {btf_type_id_to_artifacts()[btf_type_id] = artifact;}
181 schedule_type_for_canonocalization(
const type_base_sptr& t)
182 {types_to_canonicalize_.push_back(t);}
191 types_to_canonicalize_.end(),
192 [](
const vector<type_base_sptr>::const_iterator& i)
199#ifdef WITH_BTF__GET_NR_TYPES
200#define GET_NB_TYPES btf__get_nr_types
203#ifdef WITH_BTF__TYPE_CNT
205#define GET_NB_TYPES btf__type_cnt
213 return GET_NB_TYPES(
const_cast<reader*
>(
this)->btf_handle());
237 const vector<char**>& debug_info_root_paths,
239 bool linux_kernel_mode)
241 btf__free(btf_handle_);
242 btf_handle_ =
nullptr;
244 options().load_all_types = load_all_types;
245 options().load_in_linux_kernel_mode = linux_kernel_mode;
263 reader(
const string& elf_path,
264 const vector<char**>& debug_info_root_paths,
265 environment& environment,
267 bool linux_kernel_mode)
268 : elf_based_reader(elf_path,
269 debug_info_root_paths,
273 load_all_types, linux_kernel_mode);
293 static btf::reader_sptr
294 create(
const string& elf_path,
295 const vector<char**>& debug_info_root_paths,
296 environment& environment,
298 bool linux_kernel_mode)
300 reader_sptr result(
new reader(elf_path, debug_info_root_paths, environment,
301 load_all_types, linux_kernel_mode));
308 btf__free(btf_handle_);
309 btf_handle_ =
nullptr;
319 read_corpus(status& status)
325 origin |= corpus::BTF_ORIGIN;
326 corpus()->set_origin(origin);
328 if ((status & STATUS_NO_SYMBOLS_FOUND)
329 || !(status & STATUS_OK))
333 return corpus_sptr();
335 if (find_btf_section() ==
nullptr)
336 status |= STATUS_DEBUG_INFO_NOT_FOUND;
338 read_debug_info_into_corpus();
349 read_debug_info_into_corpus()
352 return corpus_sptr();
355 (
new translation_unit(env(),
"", 64));
356 corpus()->add(artificial_tu);
357 cur_tu(artificial_tu);
359 int number_of_types = nr_btf_types();
360 int first_type_id = 1;
364 for (
int type_id = first_type_id;
365 type_id < number_of_types;
372 bool do_construct_ir_node =
false;
374 const btf_type* t = btf__type_by_id(btf_handle(), type_id);
377 name = btf_offset_to_string(btf_handle(), t->name_off);
379 int kind = btf_kind(t);
380 if (kind == BTF_KIND_FUNC)
383 if (btf_vlen(t) == BTF_FUNC_GLOBAL
384 || btf_vlen(t) == BTF_FUNC_EXTERN
385 || function_symbol_is_exported(name))
386 do_construct_ir_node =
true;
388 else if (kind == BTF_KIND_VAR)
391 if (btf_vlen(t) == BTF_VAR_GLOBAL_ALLOCATED
392 || btf_vlen(t) == BTF_VAR_GLOBAL_EXTERN
393 || variable_symbol_is_exported(name))
394 do_construct_ir_node =
true;
396 else if (options().load_all_types)
397 do_construct_ir_node =
true;
399 if (do_construct_ir_node)
400 build_ir_node_from_btf_type(type_id);
404 corpus()->sort_functions();
405 corpus()->sort_variables();
416 build_ir_node_from_btf_type(
int type_id)
419 const btf_type *t =
nullptr;
421 if ((result = lookup_artifact_from_btf_id(type_id)))
425 result = build_ir_node_for_void_type();
427 t = btf__type_by_id(btf_handle(), type_id);
432 int type_kind = btf_kind(t);
437 result = build_int_type(type_id);
441 result = build_float_type(type_id);
444 case BTF_KIND_TYPEDEF:
445 result = build_typedef_type(type_id);
449 result = build_pointer_type(type_id);
453 result = build_array_type(type_id);
457#ifdef WITH_BTF_ENUM64
458 case BTF_KIND_ENUM64:
460 result = build_enum_type(type_id);
463 case BTF_KIND_STRUCT:
465 result = build_class_or_union_type(type_id);
469 result = build_class_or_union_type(type_id);
473 case BTF_KIND_VOLATILE:
474 case BTF_KIND_RESTRICT:
475 result = build_qualified_type(type_id);
479 result = build_function_decl(type_id);
482 case BTF_KIND_FUNC_PROTO:
483 result = build_function_type(type_id);
487 result = build_variable_decl(type_id);
490#ifdef WITH_BTF_KIND_TYPE_TAG
491 case BTF_KIND_TYPE_TAG:
494#ifdef WITH_BTF_KIND_DECL_TAG
495 case BTF_KIND_DECL_TAG:
498 case BTF_KIND_DATASEC:
510 if (type_base_sptr type =
is_type(result))
511 schedule_type_for_canonocalization(type);
513 associate_artifact_to_btf_type_id(result, type_id);
516 add_fn_to_exported_or_undefined_decls(fn.get());
518 add_var_to_exported_or_undefined_decls(var.get());
527 build_ir_node_for_void_type()
529 type_base_sptr t = env().get_void_type();
539 build_ir_node_for_void_pointer_type()
541 type_base_sptr t = env().get_void_pointer_type();
551 build_ir_node_for_variadic_parameter_type()
553 type_base_sptr t = env().get_variadic_parameter_type();
567 build_int_type(
int type_id)
571 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
575 uint64_t byte_size = 0, bit_size = 0;
579 bit_size = byte_size * 8;
581 if (BTF_INT_ENCODING(info) & BTF_INT_CHAR)
583 if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
584 type_name =
"unsigned ";
587 else if (BTF_INT_ENCODING(info) & BTF_INT_BOOL)
589 else if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
591 type_name =
"unsigned ";
592 type_name += btf_offset_to_string(btf_handle(), t->name_off);
595 type_name = btf_offset_to_string(btf_handle(), t->name_off);
598 result.reset(
new type_decl(env(), type_name,
609 build_float_type(
int type_id)
611 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
614 string type_name = btf_offset_to_string(btf_handle(), t->name_off);;
615 uint64_t byte_size = t->size, bit_size = byte_size * 8;
637 build_enum_underlying_type(
const string enum_name, uint64_t enum_size,
638 bool is_anonymous =
true)
640 string underlying_type_name =
645 enum_size, enum_size, location()));
646 result->set_is_anonymous(is_anonymous);
647 result->set_is_artificial(
true);
659 build_enum_type(
int type_id)
661 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
662 int kind = btf_kind(t);
663#ifdef WITH_BTF_ENUM64
664 ABG_ASSERT(kind == BTF_KIND_ENUM || kind == BTF_KIND_ENUM64);
669 int byte_size = t->size, bit_size = byte_size * 8;
673 enum_name = btf_offset_to_string(btf_handle(), t->name_off);
674 bool is_anonymous = enum_name.empty();
676 int num_enms = btf_vlen(t);
679 if (kind == BTF_KIND_ENUM)
681 const struct btf_enum* e = btf_enum(t);
683 for (
int i = 0; i < num_enms; ++i, ++e)
685 e_name = btf_offset_to_string(btf_handle(), e->name_off);
687 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
690#ifdef WITH_BTF_ENUM64
691 else if (kind == BTF_KIND_ENUM64)
693 const struct btf_enum64* e =
694 reinterpret_cast<const struct btf_enum64*
>(t + 1);
695 uint64_t e_value = 0;
696 for (
int i = 0; i < num_enms; ++i, ++e)
698 e_name = btf_offset_to_string(btf_handle(), e->name_off);
699 e_value = (
static_cast<uint64_t
>(e->val_hi32) << 32) | e->val_lo32;
700 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
708 build_enum_underlying_type(enum_name, bit_size, is_anonymous);
713 result->set_is_anonymous(is_anonymous);
723 build_typedef_type(
int type_id)
725 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
726 int kind = btf_kind(t);
729 string type_name = btf_offset_to_string(btf_handle(), t->name_off);
730 type_base_sptr underlying_type =
731 is_type(build_ir_node_from_btf_type(t->type));
732 if (!underlying_type)
752 build_pointer_type(
int type_id)
754 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
755 int kind = btf_kind(t);
758 type_base_sptr underlying_type =
759 is_type(build_ir_node_from_btf_type(t->type));
760 if (!underlying_type)
762 if (env().is_void_type(underlying_type))
765 return build_ir_node_for_void_pointer_type();
767 int size = elf_helpers::get_architecture_word_size(elf_handle());
782 build_array_type(
int type_id)
784 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
785 int kind = btf_kind(t);
788 const struct btf_array* arr = btf_array(t);
790 type_base_sptr underlying_type =
791 is_type(build_ir_node_from_btf_type(arr->type));
792 if (!underlying_type)
795 uint64_t lower_bound = 0;
797 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
801 lower_bound, upper_bound,
803 subrange->is_non_finite(!arr->nelems);
804 subrange->set_size_in_bits(cur_tu()->get_address_size());
809 subranges, location()));
821 build_qualified_type(
int type_id)
823 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
824 int kind = btf_kind(t);
826 || kind == BTF_KIND_VOLATILE
827 || kind == BTF_KIND_RESTRICT);
829 type_base_sptr underlying_type =
830 is_type(build_ir_node_from_btf_type(t->type));
831 if (!underlying_type)
835 if (kind == BTF_KIND_CONST)
836 qual |= qualified_type_def::CV_CONST;
837 else if (kind == BTF_KIND_VOLATILE)
838 qual |= qualified_type_def::CV_VOLATILE;
839 else if (kind == BTF_KIND_RESTRICT)
840 qual |= qualified_type_def::CV_RESTRICT;
844 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
857 build_class_or_union_type(
int type_id)
859 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
861 int kind = btf_kind(t);
863 || kind == BTF_KIND_UNION
864 || kind == BTF_KIND_FWD);
868 type_name = btf_offset_to_string(btf_handle(), t->name_off);
870 bool is_anonymous = type_name.empty();
871 uint64_t size = t->size;
874 bool is_decl_only = (kind == BTF_KIND_FWD);
876 class_or_union_sptr result;
877 if (kind == BTF_KIND_STRUCT
878 || (kind == BTF_KIND_FWD
879 && BTF_INFO_KFLAG(t->info) == 0 ))
880 result.reset(
new class_decl(env(), type_name, size,
884 decl_base::VISIBILITY_DEFAULT,
886 else if (kind == BTF_KIND_UNION
887 || (kind == BTF_KIND_FWD
888 && BTF_INFO_KFLAG(t->info) == 1))
889 result.reset(
new union_decl(env(), type_name, size, location(),
890 decl_base::VISIBILITY_DEFAULT,
896 result->set_is_declaration_only(is_decl_only);
900 associate_artifact_to_btf_type_id(result, type_id);
906 const struct btf_member *m =
907 reinterpret_cast<const struct btf_member*
>(t + 1);
908 uint64_t nb_members = btf_vlen(t);
910 for (uint64_t i = 0; i < nb_members; ++i, ++m)
912 type_base_sptr member_type =
913 is_type(build_ir_node_from_btf_type(m->type));
919 member_name = btf_offset_to_string(btf_handle(), m->name_off);
924 uint64_t offset_in_bits =
925 BTF_INFO_KFLAG(t->info)
926 ? BTF_MEMBER_BIT_OFFSET(m->offset)
929 result->add_data_member(data_member,
947 build_function_type(
int type_id)
949 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
950 int kind = btf_kind(t);
953 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
954 if (return_type ==
nullptr)
957 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
961 result->set_return_type(return_type);
963 associate_artifact_to_btf_type_id(result, type_id);
965 uint16_t nb_parms = btf_vlen(t);
966 const struct btf_param* parm =
967 reinterpret_cast<const struct btf_param*
>(t + 1);
970 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
972 type_base_sptr parm_type;
974 bool is_variadic =
false;
976 if (parm->name_off == 0 && parm->type == 0)
979 parm_type = build_ir_node_for_variadic_parameter_type();
983 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
984 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
991 (
new function_decl::parameter(parm_type, parm_name,
992 location(), is_variadic));
993 function_parms.push_back(p);
995 result->set_parameters(function_parms);
997 cur_tu()->bind_function_type_life_time(result);
1010 build_function_decl(
int type_id)
1012 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1013 int kind = btf_kind(t);
1018 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1020 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1024 result.reset(
new function_decl(fn_name, fn_type,
false,
1025 location(), fn_name));
1028 if ((fn_sym = function_symbol_is_exported(fn_name))
1029 || (fn_sym = function_symbol_is_undefined(fn_name)))
1031 result->set_symbol(fn_sym);
1032 if (fn_sym->is_defined())
1033 result->set_is_in_public_symbol_table(
true);
1046 build_variable_decl(
int type_id)
1048 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1049 int kind = btf_kind(t);
1054 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1056 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1060 result.reset(
new var_decl(var_name, var_type, location(),
1064 if ((var_sym = variable_symbol_is_exported(var_name))
1065 || (var_sym = variable_symbol_is_undefined(var_name)))
1067 result->set_symbol(var_sym);
1068 if (var_sym->is_defined())
1069 result->set_is_in_public_symbol_table(
true);
1108elf_based_reader_sptr
1110 const vector<char**>& debug_info_root_paths,
1112 bool load_all_types,
1113 bool linux_kernel_mode)
1115 reader_sptr rdr = reader::create(elf_path, debug_info_root_paths, env,
1116 load_all_types, linux_kernel_mode);
This file contains the declarations of the front-end to analyze the BTF information contained in an E...
This contains a set of ELF utilities used by the dwarf reader.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Types of the main internal representation of libabigail.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
CV
Bit field values representing the cv qualifiers of the underlying type.
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)
Create and return a BTF reader (or front-end) which is an instance of btf::reader.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
void canonicalize_types(const input_iterator &begin, const input_iterator &end, deref_lambda deref)
Compute the canonical type for all the IR types of the system.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Toplevel namespace for libabigail.