13 #include "abg-internal.h"
19 #include <unordered_map>
25 ABG_BEGIN_EXPORT_DECLARATIONS
31 ABG_END_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());
235 initialize(
const string& elf_path,
236 const vector<char**>& debug_info_root_paths,
238 bool linux_kernel_mode)
240 reset(elf_path, debug_info_root_paths);
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,
270 initialize(elf_path, 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();
541 build_ir_node_for_variadic_parameter_type()
543 type_base_sptr t = env().get_variadic_parameter_type();
560 build_int_type(
int type_id)
564 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
567 uint32_t info = *
reinterpret_cast<const uint32_t*
>(t + 1);
568 uint64_t byte_size = 0, bit_size = 0;
572 bit_size = byte_size * 8;
574 if (BTF_INT_ENCODING(info) & BTF_INT_CHAR)
576 if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
577 type_name =
"unsigned ";
580 else if (BTF_INT_ENCODING(info) & BTF_INT_BOOL)
582 else if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
584 type_name =
"unsigned ";
585 type_name += btf_offset_to_string(btf_handle(), t->name_off);
588 type_name = btf_offset_to_string(btf_handle(), t->name_off);
591 result.reset(
new type_decl(env(), type_name,
602 build_float_type(
int type_id)
604 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
607 string type_name = btf_offset_to_string(btf_handle(), t->name_off);;
608 uint64_t byte_size = t->size, bit_size = byte_size * 8;
630 build_enum_underlying_type(
const string enum_name, uint64_t enum_size,
631 bool is_anonymous =
true)
633 string underlying_type_name =
638 enum_size, enum_size, location()));
639 result->set_is_anonymous(is_anonymous);
640 result->set_is_artificial(
true);
652 build_enum_type(
int type_id)
654 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
655 int kind = btf_kind(t);
656 #ifdef WITH_BTF_ENUM64
657 ABG_ASSERT(kind == BTF_KIND_ENUM || kind == BTF_KIND_ENUM64);
662 int byte_size = t->size, bit_size = byte_size * 8;
666 enum_name = btf_offset_to_string(btf_handle(), t->name_off);
667 bool is_anonymous = enum_name.empty();
669 int num_enms = btf_vlen(t);
672 if (kind == BTF_KIND_ENUM)
674 const struct btf_enum* e = btf_enum(t);
675 uint32_t e_value = 0;
676 for (
int i = 0; i < num_enms; ++i, ++e)
678 e_name = btf_offset_to_string(btf_handle(), e->name_off);
680 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
683 #ifdef WITH_BTF_ENUM64
684 else if (kind == BTF_KIND_ENUM64)
686 const struct btf_enum64* e =
687 reinterpret_cast<const struct btf_enum64*
>(t + 1);
688 uint64_t e_value = 0;
689 for (
int i = 0; i < num_enms; ++i, ++e)
691 e_name = btf_offset_to_string(btf_handle(), e->name_off);
692 e_value = (
static_cast<uint64_t
>(e->val_hi32) << 32) | e->val_lo32;
693 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
701 build_enum_underlying_type(enum_name, bit_size, is_anonymous);
706 result->set_is_anonymous(is_anonymous);
716 build_typedef_type(
int type_id)
718 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
719 int kind = btf_kind(t);
722 string type_name = btf_offset_to_string(btf_handle(), t->name_off);
723 type_base_sptr underlying_type =
724 is_type(build_ir_node_from_btf_type(t->type));
725 if (!underlying_type)
745 build_pointer_type(
int type_id)
747 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
748 int kind = btf_kind(t);
751 type_base_sptr underlying_type =
752 is_type(build_ir_node_from_btf_type(t->type));
753 if (!underlying_type)
756 int size = elf_helpers::get_architecture_word_size(elf_handle());
771 build_array_type(
int type_id)
773 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
774 int kind = btf_kind(t);
777 const struct btf_array* arr = btf_array(t);
779 type_base_sptr underlying_type =
780 is_type(build_ir_node_from_btf_type(arr->type));
781 if (!underlying_type)
784 uint64_t lower_boud = 0;
786 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
790 lower_boud, upper_bound,
796 subranges, location()));
808 build_qualified_type(
int type_id)
810 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
811 int kind = btf_kind(t);
813 || kind == BTF_KIND_VOLATILE
814 || kind == BTF_KIND_RESTRICT);
816 type_base_sptr underlying_type =
817 is_type(build_ir_node_from_btf_type(t->type));
818 if (!underlying_type)
822 if (kind == BTF_KIND_CONST)
823 qual |= qualified_type_def::CV_CONST;
824 else if (kind == BTF_KIND_VOLATILE)
825 qual |= qualified_type_def::CV_VOLATILE;
826 else if (kind == BTF_KIND_RESTRICT)
827 qual |= qualified_type_def::CV_RESTRICT;
831 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
844 build_class_or_union_type(
int type_id)
846 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
848 int kind = btf_kind(t);
850 || kind == BTF_KIND_UNION
851 || kind == BTF_KIND_FWD);
855 type_name = btf_offset_to_string(btf_handle(), t->name_off);
857 bool is_anonymous = type_name.empty();
858 uint64_t size = t->size;
861 bool is_decl_only = (kind == BTF_KIND_FWD);
863 class_or_union_sptr result;
864 if (kind == BTF_KIND_STRUCT
865 || (kind == BTF_KIND_FWD
866 && BTF_INFO_KFLAG(t->info) == 0 ))
867 result.reset(
new class_decl(env(), type_name, size,
871 decl_base::VISIBILITY_DEFAULT,
873 else if (kind == BTF_KIND_UNION
874 || (kind == BTF_KIND_FWD
875 && BTF_INFO_KFLAG(t->info) == 1))
876 result.reset(
new union_decl(env(), type_name, size, location(),
877 decl_base::VISIBILITY_DEFAULT,
883 result->set_is_declaration_only(is_decl_only);
887 associate_artifact_to_btf_type_id(result, type_id);
893 const struct btf_member *m =
894 reinterpret_cast<const struct btf_member*
>(t + 1);
895 uint64_t nb_members = btf_vlen(t);
897 for (uint64_t i = 0; i < nb_members; ++i, ++m)
899 type_base_sptr member_type =
900 is_type(build_ir_node_from_btf_type(m->type));
906 member_name = btf_offset_to_string(btf_handle(), m->name_off);
911 uint64_t offset_in_bits =
912 BTF_INFO_KFLAG(t->info)
913 ? BTF_MEMBER_BIT_OFFSET(m->offset)
916 result->add_data_member(data_member,
934 build_function_type(
int type_id)
936 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
937 int kind = btf_kind(t);
940 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
941 if (return_type ==
nullptr)
944 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
948 result->set_return_type(return_type);
950 associate_artifact_to_btf_type_id(result, type_id);
952 uint16_t nb_parms = btf_vlen(t);
953 const struct btf_param* parm =
954 reinterpret_cast<const struct btf_param*
>(t + 1);
957 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
959 type_base_sptr parm_type;
961 bool is_variadic =
false;
963 if (parm->name_off == 0 && parm->type == 0)
966 parm_type = build_ir_node_for_variadic_parameter_type();
970 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
971 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
978 (
new function_decl::parameter(parm_type, parm_name,
979 location(), is_variadic));
980 function_parms.push_back(p);
982 result->set_parameters(function_parms);
984 cur_tu()->bind_function_type_life_time(result);
997 build_function_decl(
int type_id)
999 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1000 int kind = btf_kind(t);
1005 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1007 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1011 result.reset(
new function_decl(fn_name, fn_type,
false,
1012 location(), fn_name));
1015 if ((fn_sym = function_symbol_is_exported(fn_name)))
1017 result->set_symbol(fn_sym);
1018 result->set_is_in_public_symbol_table(
true);
1031 build_variable_decl(
int type_id)
1033 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1034 int kind = btf_kind(t);
1039 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1041 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1045 result.reset(
new var_decl(var_name, var_type, location(),
1049 if ((var_sym = variable_symbol_is_exported(var_name)))
1051 result->set_symbol(var_sym);
1052 result->set_is_in_public_symbol_table(
true);
1091 elf_based_reader_sptr
1093 const vector<char**>& debug_info_root_paths,
1095 bool load_all_types,
1096 bool linux_kernel_mode)
1098 reader_sptr rdr = reader::create(elf_path, debug_info_root_paths, env,
1099 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 ...
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.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
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.
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.