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)";
60typedef std::unordered_map<const btf_type*, type_or_decl_base_sptr>
61btf_type_to_abi_artifact_map_type;
78class reader :
public elf_based_reader
80 ::btf* base_btf_handle_ =
nullptr;
83 string base_btf_file_name_;
84 ::btf* split_btf_handle_ =
nullptr;
87 string split_btf_file_name_;
90 vector<::btf*> split_btfs_to_free_;
92 vector<type_base_sptr> types_to_canonicalize_;
93 btf_type_to_abi_artifact_map_type btf_type_to_artifacts_;
103 {
return options().do_log;}
112 {options().do_log = f;}
122 {
return options().show_stats;}
132 {options().show_stats = f;}
146 if (base_btf_handle_ ==
nullptr)
148 base_btf_handle_ = btf__parse(corpus_path().c_str(),
nullptr);
149 if (!base_btf_handle_)
151 std::cerr <<
"Could not parse base BTF information from file '"
152 << corpus_path().c_str() <<
"'" << std::endl;
155 base_btf_file_name_ = corpus_path();
157 return base_btf_handle_;
173 if (!base_btf_handle_)
175 std::cerr <<
"Base BTF information not present. "
176 <<
"Not attempting to parse split BTF information"
181 if (corpus_path().empty() || corpus_path() == base_btf_file_name_)
183 std::cerr <<
"BTF reader not initialized with split file name. "
184 <<
"Not attending to read split BTF information"
189 split_btf_handle_ = btf__parse_split(corpus_path().c_str(),
191 if (!split_btf_handle_)
193 std::cerr <<
"Could not read split BTF information from file "
194 << corpus_path() << std::endl;
197 split_btf_file_name_ = corpus_path();
199 return split_btf_handle_;
215 if (split_btf_handle_)
216 return split_btf_handle_;
218 if (!base_btf_handle_)
219 return base_btf_handle();
221 if (corpus_path() != base_btf_file_name_)
225 return read_split_btf();
227 return base_btf_handle();
235 {
return options().env;}
242 {
return const_cast<reader*
>(
this)->env();}
282 btf_type_to_abi_artifact_map_type&
283 btf_type_to_artifacts()
284 {
return btf_type_to_artifacts_;}
291 const btf_type_to_abi_artifact_map_type&
292 btf_type_to_artifacts()
const
293 {
return btf_type_to_artifacts_;}
303 lookup_artifact_from_btf_type(
const btf_type* t)
305 auto i = btf_type_to_artifacts().find(t);
306 if (i != btf_type_to_artifacts().end())
319 {btf_type_to_artifacts()[t] = artifact;}
326 schedule_type_for_canonicalization(
const type_base_sptr& t)
328 if (t && !t->get_naked_canonical_type())
329 types_to_canonicalize_.push_back(t);
338 tools_utils::timer cn_timer;
341 std::cerr <<
"BTF Reader is going to canonicalize "
343 << types_to_canonicalize_.size()
345 corpus_sptr c = corpus();
347 std::cerr <<
" from corpus " << corpus()->get_path() <<
"\n";
352 types_to_canonicalize_.end(),
353 [](
const vector<type_base_sptr>::const_iterator& i)
354 {return *i;}, do_log(), show_stats());
359 std::cerr <<
"BTF Reader finished types "
360 <<
"sorting, hashing & canonicalizing in: "
372 nr_btf_types(const ::btf* handle)
const
374#ifdef WITH_BTF__GET_NR_TYPES
375#define GET_NB_TYPES btf__get_nr_types
378#ifdef WITH_BTF__TYPE_CNT
380#define GET_NB_TYPES btf__type_cnt
388 return GET_NB_TYPES(handle);
412 const vector<char**>& debug_info_root_paths,
414 bool linux_kernel_mode)
416 if (split_btf_handle_)
422 split_btfs_to_free_.push_back(split_btf_handle_);
423 split_btf_handle_ =
nullptr;
426 split_btf_file_name_.clear();
427 types_to_canonicalize_.clear();
430 corpus_path(elf_path);
431 options().load_all_types = load_all_types;
432 options().load_in_linux_kernel_mode = linux_kernel_mode;
450 reader(
const string& elf_path,
451 const vector<char**>& debug_info_root_paths,
452 environment& environment,
454 bool linux_kernel_mode)
455 : elf_based_reader(elf_path,
456 debug_info_root_paths,
460 load_all_types, linux_kernel_mode);
480 static btf::reader_sptr
481 create(
const string& elf_path,
482 const vector<char**>& debug_info_root_paths,
483 environment& environment,
485 bool linux_kernel_mode)
487 reader_sptr result(
new reader(elf_path, debug_info_root_paths, environment,
488 load_all_types, linux_kernel_mode));
495 for (
auto b : split_btfs_to_free_)
497 btf__free(split_btf_handle_);
498 btf__free(base_btf_handle_);
499 split_btf_handle_ =
nullptr;
500 base_btf_handle_ =
nullptr;
510 read_corpus(status& status)
516 origin |= corpus::BTF_ORIGIN;
517 corpus()->set_origin(origin);
520 origin |= corpus_group()->get_origin();
521 corpus_group()->set_origin(origin);
524 if ((status & STATUS_NO_SYMBOLS_FOUND)
525 || !(status & STATUS_OK))
529 return corpus_sptr();
531 if (find_btf_section() ==
nullptr)
532 status |= STATUS_DEBUG_INFO_NOT_FOUND;
534 read_debug_info_into_corpus();
545 read_debug_info_into_corpus()
548 return corpus_sptr();
551 (
new translation_unit(env(),
"", 64));
552 corpus()->add(artificial_tu);
553 cur_tu(artificial_tu);
555#ifdef WITH_DEBUG_SELF_COMPARISON
556 if (env().self_comparison_debug_is_on())
558 corpus_group_sptr g = corpus_group();
560 env().set_self_comparison_debug_input(g);
562 env().set_self_comparison_debug_input(corpus());
566 int number_of_types = nr_btf_types(btf_handle());
567 int first_type_id = 1;
569 const ::btf* base = btf__base_btf(btf_handle());
582 first_type_id = nr_btf_types(base);
587 for (
int type_id = first_type_id;
588 type_id < number_of_types;
595 bool do_construct_ir_node =
false;
597 const btf_type* t = btf__type_by_id(btf_handle(), type_id);
600 name = btf_offset_to_string(btf_handle(), t->name_off);
602 int kind = btf_kind(t);
603 if (kind == BTF_KIND_FUNC)
606 if (btf_vlen(t) == BTF_FUNC_GLOBAL
607 || btf_vlen(t) == BTF_FUNC_EXTERN
608 || function_symbol_is_exported(name))
609 do_construct_ir_node =
true;
611 else if (kind == BTF_KIND_VAR)
614 if (btf_vlen(t) == BTF_VAR_GLOBAL_ALLOCATED
615 || btf_vlen(t) == BTF_VAR_GLOBAL_EXTERN
616 || variable_symbol_is_exported(name))
617 do_construct_ir_node =
true;
619 else if (options().load_all_types)
620 do_construct_ir_node =
true;
622 if (do_construct_ir_node)
623 build_ir_node_from_btf_type(type_id);
627 corpus()->sort_functions();
628 corpus()->sort_variables();
639 build_ir_node_from_btf_type(
int type_id)
642 const btf_type *t =
nullptr;
644 t = btf__type_by_id(btf_handle(), type_id);
646 if ((result = lookup_artifact_from_btf_type(t)))
652 int type_kind = btf_kind(t);
658 result = build_ir_node_for_void_type();
662 result = build_int_type(type_id);
666 result = build_float_type(type_id);
669 case BTF_KIND_TYPEDEF:
670 result = build_typedef_type(type_id);
674 result = build_pointer_type(type_id);
678 result = build_array_type(type_id);
682#ifdef WITH_BTF_ENUM64
683 case BTF_KIND_ENUM64:
685 result = build_enum_type(type_id);
688 case BTF_KIND_STRUCT:
690 result = build_class_or_union_type(type_id);
694 result = build_class_or_union_type(type_id);
698 case BTF_KIND_VOLATILE:
699 case BTF_KIND_RESTRICT:
700 result = build_qualified_type(type_id);
704 result = build_function_decl(type_id);
707 case BTF_KIND_FUNC_PROTO:
708 result = build_function_type(type_id);
712 result = build_variable_decl(type_id);
715#ifdef WITH_BTF_KIND_TYPE_TAG
716 case BTF_KIND_TYPE_TAG:
719#ifdef WITH_BTF_KIND_DECL_TAG
720 case BTF_KIND_DECL_TAG:
723 case BTF_KIND_DATASEC:
733 if (type_base_sptr type =
is_type(result))
734 schedule_type_for_canonicalization(type);
736 associate_artifact_to_btf_type(result, t);
739 add_fn_to_exported_or_undefined_decls(fn.get());
741 add_var_to_exported_or_undefined_decls(var);
750 build_ir_node_for_void_type()
752 type_base_sptr t = env().get_void_type();
754 schedule_type_for_canonicalization(t);
762 build_ir_node_for_void_pointer_type()
764 type_base_sptr t = env().get_void_pointer_type();
766 schedule_type_for_canonicalization(t);
774 build_ir_node_for_variadic_parameter_type()
776 type_base_sptr t = env().get_variadic_parameter_type();
779 schedule_type_for_canonicalization(t);
790 build_int_type(
int type_id)
794 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
798 uint64_t byte_size = 0, bit_size = 0;
802 bit_size = byte_size * 8;
804 if (BTF_INT_ENCODING(info) & BTF_INT_CHAR)
806 if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
807 type_name =
"unsigned ";
810 else if (BTF_INT_ENCODING(info) & BTF_INT_BOOL)
812 else if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
814 type_name =
"unsigned ";
815 type_name += btf_offset_to_string(btf_handle(), t->name_off);
818 type_name = btf_offset_to_string(btf_handle(), t->name_off);
821 result.reset(
new type_decl(env(), type_name,
832 build_float_type(
int type_id)
834 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
837 string type_name = btf_offset_to_string(btf_handle(), t->name_off);;
838 uint64_t byte_size = t->size, bit_size = byte_size * 8;
860 build_enum_underlying_type(
const string enum_name, uint64_t enum_size,
861 bool is_anonymous =
true)
863 string underlying_type_name =
868 enum_size, enum_size, location()));
869 result->set_is_anonymous(is_anonymous);
870 result->set_is_artificial(
true);
872 schedule_type_for_canonicalization(result);
882 build_enum_type(
int type_id)
884 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
885 int kind = btf_kind(t);
886#ifdef WITH_BTF_ENUM64
887 ABG_ASSERT(kind == BTF_KIND_ENUM || kind == BTF_KIND_ENUM64);
892 int byte_size = t->size, bit_size = byte_size * 8;
896 enum_name = btf_offset_to_string(btf_handle(), t->name_off);
897 bool is_anonymous = enum_name.empty();
899 int num_enms = btf_vlen(t);
902 if (kind == BTF_KIND_ENUM)
904 const struct btf_enum* e = btf_enum(t);
906 for (
int i = 0; i < num_enms; ++i, ++e)
908 e_name = btf_offset_to_string(btf_handle(), e->name_off);
910 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
913#ifdef WITH_BTF_ENUM64
914 else if (kind == BTF_KIND_ENUM64)
916 const struct btf_enum64* e =
917 reinterpret_cast<const struct btf_enum64*
>(t + 1);
918 uint64_t e_value = 0;
919 for (
int i = 0; i < num_enms; ++i, ++e)
921 e_name = btf_offset_to_string(btf_handle(), e->name_off);
922 e_value = (
static_cast<uint64_t
>(e->val_hi32) << 32) | e->val_lo32;
923 enms.push_back(enum_type_decl::enumerator(e_name, e_value));
931 build_enum_underlying_type(enum_name, bit_size, is_anonymous);
936 result->set_is_anonymous(is_anonymous);
946 build_typedef_type(
int type_id)
948 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
949 int kind = btf_kind(t);
952 string type_name = btf_offset_to_string(btf_handle(), t->name_off);
953 type_base_sptr underlying_type =
954 is_type(build_ir_node_from_btf_type(t->type));
955 if (!underlying_type)
975 build_pointer_type(
int type_id)
977 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
978 int kind = btf_kind(t);
981 type_base_sptr underlying_type =
982 is_type(build_ir_node_from_btf_type(t->type));
983 if (!underlying_type)
985 if (env().is_void_type(underlying_type))
988 return build_ir_node_for_void_pointer_type();
990 int size = elf_helpers::get_architecture_word_size(elf_handle());
1005 build_array_type(
int type_id)
1007 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1008 int kind = btf_kind(t);
1011 const struct btf_array* arr = btf_array(t);
1013 type_base_sptr underlying_type =
1014 is_type(build_ir_node_from_btf_type(arr->type));
1015 if (!underlying_type)
1018 uint64_t lower_bound = 0;
1020 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
1024 lower_bound, upper_bound,
1026 subrange->is_non_finite(!arr->nelems);
1027 subrange->set_size_in_bits(cur_tu()->get_address_size());
1029 schedule_type_for_canonicalization(subrange);
1032 subranges, location()));
1044 build_qualified_type(
int type_id)
1046 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1047 int kind = btf_kind(t);
1049 || kind == BTF_KIND_VOLATILE
1050 || kind == BTF_KIND_RESTRICT);
1052 type_base_sptr underlying_type =
1053 is_type(build_ir_node_from_btf_type(t->type));
1054 if (!underlying_type)
1058 if (kind == BTF_KIND_CONST)
1059 qual |= qualified_type_def::CV_CONST;
1060 else if (kind == BTF_KIND_VOLATILE)
1061 qual |= qualified_type_def::CV_VOLATILE;
1062 else if (kind == BTF_KIND_RESTRICT)
1063 qual |= qualified_type_def::CV_RESTRICT;
1067 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
1080 build_class_or_union_type(
int type_id)
1082 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1084 int kind = btf_kind(t);
1086 || kind == BTF_KIND_UNION
1087 || kind == BTF_KIND_FWD);
1091 type_name = btf_offset_to_string(btf_handle(), t->name_off);
1093 bool is_anonymous = type_name.empty();
1094 uint64_t size = t->size;
1097 bool is_decl_only = (kind == BTF_KIND_FWD);
1099 class_or_union_sptr result;
1100 if (kind == BTF_KIND_STRUCT
1101 || (kind == BTF_KIND_FWD
1102 && BTF_INFO_KFLAG(t->info) == 0 ))
1103 result.reset(
new class_decl(env(), type_name, size,
1107 decl_base::VISIBILITY_DEFAULT,
1109 else if (kind == BTF_KIND_UNION
1110 || (kind == BTF_KIND_FWD
1111 && BTF_INFO_KFLAG(t->info) == 1))
1112 result.reset(
new union_decl(env(), type_name, size, location(),
1113 decl_base::VISIBILITY_DEFAULT,
1119 result->set_is_declaration_only(is_decl_only);
1123 associate_artifact_to_btf_type(result, t);
1129 const struct btf_member *m =
1130 reinterpret_cast<const struct btf_member*
>(t + 1);
1131 uint64_t nb_members = btf_vlen(t);
1133 for (uint64_t i = 0; i < nb_members; ++i, ++m)
1135 type_base_sptr member_type =
1136 is_type(build_ir_node_from_btf_type(m->type));
1142 member_name = btf_offset_to_string(btf_handle(), m->name_off);
1147 uint64_t offset_in_bits =
1148 BTF_INFO_KFLAG(t->info)
1149 ? BTF_MEMBER_BIT_OFFSET(m->offset)
1152 result->add_data_member(data_member,
1170 build_function_type(
int type_id)
1172 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1173 int kind = btf_kind(t);
1176 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
1177 if (return_type ==
nullptr)
1180 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
1184 result->set_return_type(return_type);
1186 associate_artifact_to_btf_type(result, t);
1188 uint16_t nb_parms = btf_vlen(t);
1189 const struct btf_param* parm =
1190 reinterpret_cast<const struct btf_param*
>(t + 1);
1193 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
1195 type_base_sptr parm_type;
1197 bool is_variadic =
false;
1199 if (parm->name_off == 0 && parm->type == 0)
1202 parm_type = build_ir_node_for_variadic_parameter_type();
1206 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
1207 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
1214 (
new function_decl::parameter(parm_type, parm_name,
1215 location(), is_variadic));
1216 function_parms.push_back(p);
1218 result->set_parameters(function_parms);
1220 cur_tu()->bind_function_type_life_time(result);
1233 build_function_decl(
int type_id)
1235 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1236 int kind = btf_kind(t);
1241 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1243 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1247 result.reset(
new function_decl(fn_name, fn_type,
false,
1248 location(), fn_name));
1251 if ((fn_sym = function_symbol_is_exported(fn_name))
1252 || (fn_sym = function_symbol_is_undefined(fn_name)))
1254 result->set_symbol(fn_sym);
1255 if (fn_sym->is_defined())
1256 result->set_is_in_public_symbol_table(
true);
1269 build_variable_decl(
int type_id)
1271 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1272 int kind = btf_kind(t);
1277 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1279 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1283 result.reset(
new var_decl(var_name, var_type, location(),
1287 if ((var_sym = variable_symbol_is_exported(var_name))
1288 || (var_sym = variable_symbol_is_undefined(var_name)))
1290 result->set_symbol(var_sym);
1291 if (var_sym->is_defined())
1292 result->set_is_in_public_symbol_table(
true);
1331elf_based_reader_sptr
1333 const vector<char**>& debug_info_root_paths,
1335 bool load_all_types,
1336 bool linux_kernel_mode)
1338 reader_sptr rdr = reader::create(elf_path, debug_info_root_paths, env,
1339 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, bool do_log=false, bool show_stats=false)
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.
void hash_and_canonicalize_types(IteratorType begin, IteratorType end, deref_lambda deref, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
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.