13#include "abg-internal.h"
19#include <unordered_map>
25ABG_BEGIN_EXPORT_DECLARATIONS
31ABG_END_EXPORT_DECLARATIONS
45typedef shared_ptr<reader> reader_sptr;
48btf_offset_to_string(const ::btf* btf,
uint32_t offset)
51 return "__anonymous__";
52 return btf__name_by_offset(btf, offset) ?:
"(invalid string offset)";
57typedef std::unordered_map<int, type_or_decl_base_sptr>
58btf_type_id_to_abi_artifact_map_type;
61class reader :
public elf_based_reader
63 ::btf* btf_handle_ =
nullptr;
65 vector<type_base_sptr> types_to_canonicalize_;
66 btf_type_id_to_abi_artifact_map_type btf_type_id_to_artifacts_;
74 if (btf_handle_ ==
nullptr)
76 btf_handle_ = btf__parse(corpus_path().c_str(),
nullptr);
78 std::cerr <<
"Could not parse BTF information from file '"
79 << corpus_path().c_str() <<
"'" << std::endl;
89 {
return options().env;}
96 {
return const_cast<reader*
>(
this)->env();}
136 btf_type_id_to_abi_artifact_map_type&
137 btf_type_id_to_artifacts()
138 {
return btf_type_id_to_artifacts_;}
145 const btf_type_id_to_abi_artifact_map_type&
146 btf_type_id_to_artifacts()
const
147 {
return btf_type_id_to_artifacts_;}
157 lookup_artifact_from_btf_id(
int btf_id)
159 auto i = btf_type_id_to_artifacts().find(btf_id);
160 if (i != btf_type_id_to_artifacts().end())
173 {btf_type_id_to_artifacts()[btf_type_id] = artifact;}
180 schedule_type_for_canonocalization(
const type_base_sptr& t)
181 {types_to_canonicalize_.push_back(t);}
190 types_to_canonicalize_.end(),
191 [](
const vector<type_base_sptr>::const_iterator& i)
198#ifdef WITH_BTF__GET_NR_TYPES
199#define GET_NB_TYPES btf__get_nr_types
202#ifdef WITH_BTF__TYPE_CNT
204#define GET_NB_TYPES btf__type_cnt
212 return GET_NB_TYPES(
const_cast<reader*
>(
this)->btf_handle());
236 const vector<char**>& debug_info_root_paths,
238 bool linux_kernel_mode)
241 btf__free(btf_handle_);
242 options().load_all_types = load_all_types;
243 options().load_in_linux_kernel_mode = linux_kernel_mode;
261 reader(
const string& elf_path,
262 const vector<char**>& debug_info_root_paths,
263 environment& environment,
265 bool linux_kernel_mode)
266 : elf_based_reader(elf_path,
267 debug_info_root_paths,
271 load_all_types, linux_kernel_mode);
291 static btf::reader_sptr
292 create(
const string& elf_path,
293 const vector<char**>& debug_info_root_paths,
294 environment& environment,
296 bool linux_kernel_mode)
298 reader_sptr result(
new reader(elf_path, debug_info_root_paths, environment,
299 load_all_types, linux_kernel_mode));
306 btf__free(btf_handle_);
316 read_corpus(status& status)
322 origin |= corpus::BTF_ORIGIN;
323 corpus()->set_origin(origin);
325 if ((status & STATUS_NO_SYMBOLS_FOUND)
326 || !(status & STATUS_OK))
330 return corpus_sptr();
332 if (find_btf_section() ==
nullptr)
333 status |= STATUS_DEBUG_INFO_NOT_FOUND;
335 read_debug_info_into_corpus();
346 read_debug_info_into_corpus()
351 (
new translation_unit(env(),
"", 64));
352 corpus()->add(artificial_tu);
353 cur_tu(artificial_tu);
355 int number_of_types = nr_btf_types();
356 int first_type_id = 1;
360 for (
int type_id = first_type_id;
361 type_id < number_of_types;
368 bool do_construct_ir_node =
false;
370 const btf_type* t = btf__type_by_id(btf_handle(), type_id);
373 name = btf_offset_to_string(btf_handle(), t->name_off);
375 int kind = btf_kind(t);
376 if (kind == BTF_KIND_FUNC)
379 if (btf_vlen(t) == BTF_FUNC_GLOBAL
380 || btf_vlen(t) == BTF_FUNC_EXTERN
381 || function_symbol_is_exported(name))
382 do_construct_ir_node =
true;
384 else if (kind == BTF_KIND_VAR)
387 if (btf_vlen(t) == BTF_VAR_GLOBAL_ALLOCATED
388 || btf_vlen(t) == BTF_VAR_GLOBAL_EXTERN
389 || variable_symbol_is_exported(name))
390 do_construct_ir_node =
true;
392 else if (options().load_all_types)
393 do_construct_ir_node =
true;
395 if (do_construct_ir_node)
396 build_ir_node_from_btf_type(type_id);
411 build_ir_node_from_btf_type(
int type_id)
414 const btf_type *t =
nullptr;
416 if ((result = lookup_artifact_from_btf_id(type_id)))
420 result = build_ir_node_for_void_type();
422 t = btf__type_by_id(btf_handle(), type_id);
427 int type_kind = btf_kind(t);
432 result = build_int_type(type_id);
436 result = build_float_type(type_id);
439 case BTF_KIND_TYPEDEF:
440 result = build_typedef_type(type_id);
444 result = build_pointer_type(type_id);
448 result = build_array_type(type_id);
452#ifdef WITH_BTF_ENUM64
453 case BTF_KIND_ENUM64:
455 result = build_enum_type(type_id);
458 case BTF_KIND_STRUCT:
460 result = build_class_or_union_type(type_id);
464 result = build_class_or_union_type(type_id);
468 case BTF_KIND_VOLATILE:
469 case BTF_KIND_RESTRICT:
470 result = build_qualified_type(type_id);
474 result = build_function_decl(type_id);
477 case BTF_KIND_FUNC_PROTO:
478 result = build_function_type(type_id);
482 result = build_variable_decl(type_id);
485#ifdef WITH_BTF_KIND_TYPE_TAG
486 case BTF_KIND_TYPE_TAG:
488#ifdef WITH_BTF_KIND_DECL_TAG
489 case BTF_KIND_DECL_TAG:
491 case BTF_KIND_DATASEC:
501 if (type_base_sptr type =
is_type(result))
502 schedule_type_for_canonocalization(type);
504 associate_artifact_to_btf_type_id(result, type_id);
508 if (fn->get_is_in_public_symbol_table())
509 maybe_add_fn_to_exported_decls(fn.get());
513 if (var->get_is_in_public_symbol_table())
514 maybe_add_var_to_exported_decls(var.get());
524 build_ir_node_for_void_type()
526 type_base_sptr t = env().get_void_type();
536 build_ir_node_for_void_pointer_type()
538 type_base_sptr t = env().get_void_pointer_type();
548 build_ir_node_for_variadic_parameter_type()
550 type_base_sptr t = env().get_variadic_parameter_type();
564 build_int_type(
int type_id)
568 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
572 uint64_t byte_size = 0, bit_size = 0;
576 bit_size = byte_size * 8;
578 if (BTF_INT_ENCODING(info) & BTF_INT_CHAR)
580 if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
581 type_name =
"unsigned ";
584 else if (BTF_INT_ENCODING(info) & BTF_INT_BOOL)
586 else if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
588 type_name =
"unsigned ";
589 type_name += btf_offset_to_string(btf_handle(), t->name_off);
592 type_name = btf_offset_to_string(btf_handle(), t->name_off);
595 result.reset(
new type_decl(env(), type_name,
606 build_float_type(
int type_id)
608 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
611 string type_name = btf_offset_to_string(btf_handle(), t->name_off);;
612 uint64_t byte_size = t->size, bit_size = byte_size * 8;
634 build_enum_underlying_type(
const string enum_name, uint64_t enum_size,
635 bool is_anonymous =
true)
637 string underlying_type_name =
642 enum_size, enum_size, location()));
643 result->set_is_anonymous(is_anonymous);
644 result->set_is_artificial(
true);
656 build_enum_type(
int type_id)
658 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
659 int kind = btf_kind(t);
660#ifdef WITH_BTF_ENUM64
661 ABG_ASSERT(kind == BTF_KIND_ENUM || kind == BTF_KIND_ENUM64);
666 int byte_size = t->size, bit_size = byte_size * 8;
670 enum_name = btf_offset_to_string(btf_handle(), t->name_off);
671 bool is_anonymous = enum_name.empty();
673 int num_enms = btf_vlen(t);
676 if (kind == BTF_KIND_ENUM)
678 const struct btf_enum* e = btf_enum(t);
680 for (
int i = 0; i < num_enms; ++i, ++e)
682 e_name = btf_offset_to_string(btf_handle(), e->name_off);
684 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
687#ifdef WITH_BTF_ENUM64
688 else if (kind == BTF_KIND_ENUM64)
690 const struct btf_enum64* e =
691 reinterpret_cast<const struct btf_enum64*
>(t + 1);
692 uint64_t e_value = 0;
693 for (
int i = 0; i < num_enms; ++i, ++e)
695 e_name = btf_offset_to_string(btf_handle(), e->name_off);
696 e_value = (
static_cast<uint64_t
>(e->val_hi32) << 32) | e->val_lo32;
697 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
705 build_enum_underlying_type(enum_name, bit_size, is_anonymous);
710 result->set_is_anonymous(is_anonymous);
720 build_typedef_type(
int type_id)
722 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
723 int kind = btf_kind(t);
726 string type_name = btf_offset_to_string(btf_handle(), t->name_off);
727 type_base_sptr underlying_type =
728 is_type(build_ir_node_from_btf_type(t->type));
729 if (!underlying_type)
749 build_pointer_type(
int type_id)
751 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
752 int kind = btf_kind(t);
755 type_base_sptr underlying_type =
756 is_type(build_ir_node_from_btf_type(t->type));
757 if (!underlying_type)
759 if (env().is_void_type(underlying_type))
762 return build_ir_node_for_void_pointer_type();
764 int size = elf_helpers::get_architecture_word_size(elf_handle());
779 build_array_type(
int type_id)
781 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
782 int kind = btf_kind(t);
785 const struct btf_array* arr = btf_array(t);
787 type_base_sptr underlying_type =
788 is_type(build_ir_node_from_btf_type(arr->type));
789 if (!underlying_type)
792 uint64_t lower_bound = 0;
794 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
798 lower_bound, upper_bound,
800 subrange->is_non_finite(!arr->nelems);
805 subranges, location()));
817 build_qualified_type(
int type_id)
819 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
820 int kind = btf_kind(t);
822 || kind == BTF_KIND_VOLATILE
823 || kind == BTF_KIND_RESTRICT);
825 type_base_sptr underlying_type =
826 is_type(build_ir_node_from_btf_type(t->type));
827 if (!underlying_type)
831 if (kind == BTF_KIND_CONST)
832 qual |= qualified_type_def::CV_CONST;
833 else if (kind == BTF_KIND_VOLATILE)
834 qual |= qualified_type_def::CV_VOLATILE;
835 else if (kind == BTF_KIND_RESTRICT)
836 qual |= qualified_type_def::CV_RESTRICT;
840 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
853 build_class_or_union_type(
int type_id)
855 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
857 int kind = btf_kind(t);
859 || kind == BTF_KIND_UNION
860 || kind == BTF_KIND_FWD);
864 type_name = btf_offset_to_string(btf_handle(), t->name_off);
866 bool is_anonymous = type_name.empty();
867 uint64_t size = t->size;
870 bool is_decl_only = (kind == BTF_KIND_FWD);
872 class_or_union_sptr result;
873 if (kind == BTF_KIND_STRUCT
874 || (kind == BTF_KIND_FWD
875 && BTF_INFO_KFLAG(t->info) == 0 ))
876 result.reset(
new class_decl(env(), type_name, size,
880 decl_base::VISIBILITY_DEFAULT,
882 else if (kind == BTF_KIND_UNION
883 || (kind == BTF_KIND_FWD
884 && BTF_INFO_KFLAG(t->info) == 1))
885 result.reset(
new union_decl(env(), type_name, size, location(),
886 decl_base::VISIBILITY_DEFAULT,
892 result->set_is_declaration_only(is_decl_only);
896 associate_artifact_to_btf_type_id(result, type_id);
902 const struct btf_member *m =
903 reinterpret_cast<const struct btf_member*
>(t + 1);
904 uint64_t nb_members = btf_vlen(t);
906 for (uint64_t i = 0; i < nb_members; ++i, ++m)
908 type_base_sptr member_type =
909 is_type(build_ir_node_from_btf_type(m->type));
915 member_name = btf_offset_to_string(btf_handle(), m->name_off);
920 uint64_t offset_in_bits =
921 BTF_INFO_KFLAG(t->info)
922 ? BTF_MEMBER_BIT_OFFSET(m->offset)
925 result->add_data_member(data_member,
943 build_function_type(
int type_id)
945 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
946 int kind = btf_kind(t);
949 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
950 if (return_type ==
nullptr)
953 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
957 result->set_return_type(return_type);
959 associate_artifact_to_btf_type_id(result, type_id);
961 uint16_t nb_parms = btf_vlen(t);
962 const struct btf_param* parm =
963 reinterpret_cast<const struct btf_param*
>(t + 1);
966 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
968 type_base_sptr parm_type;
970 bool is_variadic =
false;
972 if (parm->name_off == 0 && parm->type == 0)
975 parm_type = build_ir_node_for_variadic_parameter_type();
979 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
980 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
987 (
new function_decl::parameter(parm_type, parm_name,
988 location(), is_variadic));
989 function_parms.push_back(p);
991 result->set_parameters(function_parms);
993 cur_tu()->bind_function_type_life_time(result);
1006 build_function_decl(
int type_id)
1008 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1009 int kind = btf_kind(t);
1014 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1016 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1020 result.reset(
new function_decl(fn_name, fn_type,
false,
1021 location(), fn_name));
1024 if ((fn_sym = function_symbol_is_exported(fn_name)))
1026 result->set_symbol(fn_sym);
1027 result->set_is_in_public_symbol_table(
true);
1040 build_variable_decl(
int type_id)
1042 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1043 int kind = btf_kind(t);
1048 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1050 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1054 result.reset(
new var_decl(var_name, var_type, location(),
1058 if ((var_sym = variable_symbol_is_exported(var_name)))
1060 result->set_symbol(var_sym);
1061 result->set_is_in_public_symbol_table(
true);
1100elf_based_reader_sptr
1102 const vector<char**>& debug_info_root_paths,
1104 bool load_all_types,
1105 bool linux_kernel_mode)
1107 reader_sptr rdr = reader::create(elf_path, debug_info_root_paths, env,
1108 load_all_types, linux_kernel_mode);
This file contains the declarations of the front-end to analyze the BTF information contained in an E...
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &env)
Create and return a new read context to process CTF information from a given ELF file.
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.
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.