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);
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);
571 uint32_t info = *
reinterpret_cast<const uint32_t*
>(t + 1);
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);
679 uint32_t e_value = 0;
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_boud = 0;
794 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
798 lower_boud, upper_bound,
804 subranges, location()));
816 build_qualified_type(
int type_id)
818 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
819 int kind = btf_kind(t);
821 || kind == BTF_KIND_VOLATILE
822 || kind == BTF_KIND_RESTRICT);
824 type_base_sptr underlying_type =
825 is_type(build_ir_node_from_btf_type(t->type));
826 if (!underlying_type)
830 if (kind == BTF_KIND_CONST)
831 qual |= qualified_type_def::CV_CONST;
832 else if (kind == BTF_KIND_VOLATILE)
833 qual |= qualified_type_def::CV_VOLATILE;
834 else if (kind == BTF_KIND_RESTRICT)
835 qual |= qualified_type_def::CV_RESTRICT;
839 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
852 build_class_or_union_type(
int type_id)
854 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
856 int kind = btf_kind(t);
858 || kind == BTF_KIND_UNION
859 || kind == BTF_KIND_FWD);
863 type_name = btf_offset_to_string(btf_handle(), t->name_off);
865 bool is_anonymous = type_name.empty();
866 uint64_t size = t->size;
869 bool is_decl_only = (kind == BTF_KIND_FWD);
871 class_or_union_sptr result;
872 if (kind == BTF_KIND_STRUCT
873 || (kind == BTF_KIND_FWD
874 && BTF_INFO_KFLAG(t->info) == 0 ))
875 result.reset(
new class_decl(env(), type_name, size,
879 decl_base::VISIBILITY_DEFAULT,
881 else if (kind == BTF_KIND_UNION
882 || (kind == BTF_KIND_FWD
883 && BTF_INFO_KFLAG(t->info) == 1))
884 result.reset(
new union_decl(env(), type_name, size, location(),
885 decl_base::VISIBILITY_DEFAULT,
891 result->set_is_declaration_only(is_decl_only);
895 associate_artifact_to_btf_type_id(result, type_id);
901 const struct btf_member *m =
902 reinterpret_cast<const struct btf_member*
>(t + 1);
903 uint64_t nb_members = btf_vlen(t);
905 for (uint64_t i = 0; i < nb_members; ++i, ++m)
907 type_base_sptr member_type =
908 is_type(build_ir_node_from_btf_type(m->type));
914 member_name = btf_offset_to_string(btf_handle(), m->name_off);
919 uint64_t offset_in_bits =
920 BTF_INFO_KFLAG(t->info)
921 ? BTF_MEMBER_BIT_OFFSET(m->offset)
924 result->add_data_member(data_member,
942 build_function_type(
int type_id)
944 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
945 int kind = btf_kind(t);
948 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
949 if (return_type ==
nullptr)
952 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
956 result->set_return_type(return_type);
958 associate_artifact_to_btf_type_id(result, type_id);
960 uint16_t nb_parms = btf_vlen(t);
961 const struct btf_param* parm =
962 reinterpret_cast<const struct btf_param*
>(t + 1);
965 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
967 type_base_sptr parm_type;
969 bool is_variadic =
false;
971 if (parm->name_off == 0 && parm->type == 0)
974 parm_type = build_ir_node_for_variadic_parameter_type();
978 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
979 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
986 (
new function_decl::parameter(parm_type, parm_name,
987 location(), is_variadic));
988 function_parms.push_back(p);
990 result->set_parameters(function_parms);
992 cur_tu()->bind_function_type_life_time(result);
1005 build_function_decl(
int type_id)
1007 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1008 int kind = btf_kind(t);
1013 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1015 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1019 result.reset(
new function_decl(fn_name, fn_type,
false,
1020 location(), fn_name));
1023 if ((fn_sym = function_symbol_is_exported(fn_name)))
1025 result->set_symbol(fn_sym);
1026 result->set_is_in_public_symbol_table(
true);
1039 build_variable_decl(
int type_id)
1041 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1042 int kind = btf_kind(t);
1047 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1049 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1053 result.reset(
new var_decl(var_name, var_type, location(),
1057 if ((var_sym = variable_symbol_is_exported(var_name)))
1059 result->set_symbol(var_sym);
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.