13 #include "abg-internal.h"
19 #include <unordered_map>
25 ABG_BEGIN_EXPORT_DECLARATIONS
45 typedef shared_ptr<reader> reader_sptr;
48 btf_offset_to_string(const ::btf* btf, uint32_t offset)
51 return "__anonymous__";
52 return btf__name_by_offset(btf, offset) ?:
"(invalid string offset)";
57 typedef std::unordered_map<int, type_or_decl_base_sptr>
58 btf_type_id_to_abi_artifact_map_type;
61 class 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);
400 corpus()->sort_functions();
401 corpus()->sort_variables();
412 build_ir_node_from_btf_type(
int type_id)
415 const btf_type *t =
nullptr;
417 if ((result = lookup_artifact_from_btf_id(type_id)))
421 result = build_ir_node_for_void_type();
423 t = btf__type_by_id(btf_handle(), type_id);
428 int type_kind = btf_kind(t);
433 result = build_int_type(type_id);
437 result = build_float_type(type_id);
440 case BTF_KIND_TYPEDEF:
441 result = build_typedef_type(type_id);
445 result = build_pointer_type(type_id);
449 result = build_array_type(type_id);
453 #ifdef WITH_BTF_ENUM64
454 case BTF_KIND_ENUM64:
456 result = build_enum_type(type_id);
459 case BTF_KIND_STRUCT:
461 result = build_class_or_union_type(type_id);
465 result = build_class_or_union_type(type_id);
469 case BTF_KIND_VOLATILE:
470 case BTF_KIND_RESTRICT:
471 result = build_qualified_type(type_id);
475 result = build_function_decl(type_id);
478 case BTF_KIND_FUNC_PROTO:
479 result = build_function_type(type_id);
483 result = build_variable_decl(type_id);
486 #ifdef WITH_BTF_KIND_TYPE_TAG
487 case BTF_KIND_TYPE_TAG:
489 #ifdef WITH_BTF_KIND_DECL_TAG
490 case BTF_KIND_DECL_TAG:
492 case BTF_KIND_DATASEC:
502 if (type_base_sptr type =
is_type(result))
503 schedule_type_for_canonocalization(type);
505 associate_artifact_to_btf_type_id(result, type_id);
508 add_fn_to_exported_or_undefined_decls(fn.get());
510 add_var_to_exported_or_undefined_decls(var.get());
519 build_ir_node_for_void_type()
521 type_base_sptr t = env().get_void_type();
531 build_ir_node_for_void_pointer_type()
533 type_base_sptr t = env().get_void_pointer_type();
543 build_ir_node_for_variadic_parameter_type()
545 type_base_sptr t = env().get_variadic_parameter_type();
559 build_int_type(
int type_id)
563 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
566 uint32_t info = *
reinterpret_cast<const uint32_t*
>(t + 1);
567 uint64_t byte_size = 0, bit_size = 0;
571 bit_size = byte_size * 8;
573 if (BTF_INT_ENCODING(info) & BTF_INT_CHAR)
575 if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
576 type_name =
"unsigned ";
579 else if (BTF_INT_ENCODING(info) & BTF_INT_BOOL)
581 else if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
583 type_name =
"unsigned ";
584 type_name += btf_offset_to_string(btf_handle(), t->name_off);
587 type_name = btf_offset_to_string(btf_handle(), t->name_off);
590 result.reset(
new type_decl(env(), type_name,
601 build_float_type(
int type_id)
603 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
606 string type_name = btf_offset_to_string(btf_handle(), t->name_off);;
607 uint64_t byte_size = t->size, bit_size = byte_size * 8;
629 build_enum_underlying_type(
const string enum_name, uint64_t enum_size,
630 bool is_anonymous =
true)
632 string underlying_type_name =
637 enum_size, enum_size, location()));
638 result->set_is_anonymous(is_anonymous);
639 result->set_is_artificial(
true);
651 build_enum_type(
int type_id)
653 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
654 int kind = btf_kind(t);
655 #ifdef WITH_BTF_ENUM64
656 ABG_ASSERT(kind == BTF_KIND_ENUM || kind == BTF_KIND_ENUM64);
661 int byte_size = t->size, bit_size = byte_size * 8;
665 enum_name = btf_offset_to_string(btf_handle(), t->name_off);
666 bool is_anonymous = enum_name.empty();
668 int num_enms = btf_vlen(t);
671 if (kind == BTF_KIND_ENUM)
673 const struct btf_enum* e = btf_enum(t);
674 uint32_t e_value = 0;
675 for (
int i = 0; i < num_enms; ++i, ++e)
677 e_name = btf_offset_to_string(btf_handle(), e->name_off);
679 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
682 #ifdef WITH_BTF_ENUM64
683 else if (kind == BTF_KIND_ENUM64)
685 const struct btf_enum64* e =
686 reinterpret_cast<const struct btf_enum64*
>(t + 1);
687 uint64_t e_value = 0;
688 for (
int i = 0; i < num_enms; ++i, ++e)
690 e_name = btf_offset_to_string(btf_handle(), e->name_off);
691 e_value = (
static_cast<uint64_t
>(e->val_hi32) << 32) | e->val_lo32;
692 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
700 build_enum_underlying_type(enum_name, bit_size, is_anonymous);
705 result->set_is_anonymous(is_anonymous);
715 build_typedef_type(
int type_id)
717 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
718 int kind = btf_kind(t);
721 string type_name = btf_offset_to_string(btf_handle(), t->name_off);
722 type_base_sptr underlying_type =
723 is_type(build_ir_node_from_btf_type(t->type));
724 if (!underlying_type)
744 build_pointer_type(
int type_id)
746 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
747 int kind = btf_kind(t);
750 type_base_sptr underlying_type =
751 is_type(build_ir_node_from_btf_type(t->type));
752 if (!underlying_type)
754 if (env().is_void_type(underlying_type))
757 return build_ir_node_for_void_pointer_type();
759 int size = elf_helpers::get_architecture_word_size(elf_handle());
774 build_array_type(
int type_id)
776 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
777 int kind = btf_kind(t);
780 const struct btf_array* arr = btf_array(t);
782 type_base_sptr underlying_type =
783 is_type(build_ir_node_from_btf_type(arr->type));
784 if (!underlying_type)
787 uint64_t lower_bound = 0;
789 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
793 lower_bound, upper_bound,
795 subrange->is_non_finite(!arr->nelems);
800 subranges, location()));
812 build_qualified_type(
int type_id)
814 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
815 int kind = btf_kind(t);
817 || kind == BTF_KIND_VOLATILE
818 || kind == BTF_KIND_RESTRICT);
820 type_base_sptr underlying_type =
821 is_type(build_ir_node_from_btf_type(t->type));
822 if (!underlying_type)
826 if (kind == BTF_KIND_CONST)
827 qual |= qualified_type_def::CV_CONST;
828 else if (kind == BTF_KIND_VOLATILE)
829 qual |= qualified_type_def::CV_VOLATILE;
830 else if (kind == BTF_KIND_RESTRICT)
831 qual |= qualified_type_def::CV_RESTRICT;
835 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
848 build_class_or_union_type(
int type_id)
850 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
852 int kind = btf_kind(t);
854 || kind == BTF_KIND_UNION
855 || kind == BTF_KIND_FWD);
859 type_name = btf_offset_to_string(btf_handle(), t->name_off);
861 bool is_anonymous = type_name.empty();
862 uint64_t size = t->size;
865 bool is_decl_only = (kind == BTF_KIND_FWD);
867 class_or_union_sptr result;
868 if (kind == BTF_KIND_STRUCT
869 || (kind == BTF_KIND_FWD
870 && BTF_INFO_KFLAG(t->info) == 0 ))
871 result.reset(
new class_decl(env(), type_name, size,
875 decl_base::VISIBILITY_DEFAULT,
877 else if (kind == BTF_KIND_UNION
878 || (kind == BTF_KIND_FWD
879 && BTF_INFO_KFLAG(t->info) == 1))
880 result.reset(
new union_decl(env(), type_name, size, location(),
881 decl_base::VISIBILITY_DEFAULT,
887 result->set_is_declaration_only(is_decl_only);
891 associate_artifact_to_btf_type_id(result, type_id);
897 const struct btf_member *m =
898 reinterpret_cast<const struct btf_member*
>(t + 1);
899 uint64_t nb_members = btf_vlen(t);
901 for (uint64_t i = 0; i < nb_members; ++i, ++m)
903 type_base_sptr member_type =
904 is_type(build_ir_node_from_btf_type(m->type));
910 member_name = btf_offset_to_string(btf_handle(), m->name_off);
915 uint64_t offset_in_bits =
916 BTF_INFO_KFLAG(t->info)
917 ? BTF_MEMBER_BIT_OFFSET(m->offset)
920 result->add_data_member(data_member,
938 build_function_type(
int type_id)
940 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
941 int kind = btf_kind(t);
944 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
945 if (return_type ==
nullptr)
948 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
952 result->set_return_type(return_type);
954 associate_artifact_to_btf_type_id(result, type_id);
956 uint16_t nb_parms = btf_vlen(t);
957 const struct btf_param* parm =
958 reinterpret_cast<const struct btf_param*
>(t + 1);
961 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
963 type_base_sptr parm_type;
965 bool is_variadic =
false;
967 if (parm->name_off == 0 && parm->type == 0)
970 parm_type = build_ir_node_for_variadic_parameter_type();
974 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
975 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
982 (
new function_decl::parameter(parm_type, parm_name,
983 location(), is_variadic));
984 function_parms.push_back(p);
986 result->set_parameters(function_parms);
988 cur_tu()->bind_function_type_life_time(result);
1001 build_function_decl(
int type_id)
1003 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1004 int kind = btf_kind(t);
1009 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1011 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1015 result.reset(
new function_decl(fn_name, fn_type,
false,
1016 location(), fn_name));
1019 if ((fn_sym = function_symbol_is_exported(fn_name))
1020 || (fn_sym = function_symbol_is_undefined(fn_name)))
1022 result->set_symbol(fn_sym);
1023 if (fn_sym->is_defined())
1024 result->set_is_in_public_symbol_table(
true);
1037 build_variable_decl(
int type_id)
1039 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1040 int kind = btf_kind(t);
1045 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1047 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1051 result.reset(
new var_decl(var_name, var_type, location(),
1055 if ((var_sym = variable_symbol_is_exported(var_name))
1056 || (var_sym = variable_symbol_is_undefined(var_name)))
1058 result->set_symbol(var_sym);
1059 if (var_sym->is_defined())
1060 result->set_is_in_public_symbol_table(
true);
1099 elf_based_reader_sptr
1100 create_reader(
const std::string& elf_path,
1101 const vector<char**>& debug_info_root_paths,
1103 bool load_all_types,
1104 bool linux_kernel_mode)
1106 reader_sptr rdr = reader::create(elf_path, debug_info_root_paths, env,
1107 load_all_types, linux_kernel_mode);
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...
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
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.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Toplevel namespace for libabigail.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
This contains the private implementation of the suppression engine of libabigail. ...
Types of the main internal representation of libabigail.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
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< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
This contains a set of ELF utilities used by the dwarf reader.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
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.
This file contains the declarations of the front-end to analyze the BTF information contained in an E...
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
CV
Bit field values representing the cv qualifiers of the underlying type.