13 #include "abg-internal.h"
19 #include <unordered_map>
25 ABG_BEGIN_EXPORT_DECLARATIONS
31 ABG_END_EXPORT_DECLARATIONS
46 typedef shared_ptr<reader> reader_sptr;
49 btf_offset_to_string(const ::btf* btf, uint32_t offset)
52 return "__anonymous__";
53 return btf__name_by_offset(btf, offset) ?:
"(invalid string offset)";
58 typedef std::unordered_map<int, type_or_decl_base_sptr>
59 btf_type_id_to_abi_artifact_map_type;
62 class reader :
public elf_based_reader
64 ::btf* btf_handle_ =
nullptr;
66 vector<type_base_sptr> types_to_canonicalize_;
67 btf_type_id_to_abi_artifact_map_type btf_type_id_to_artifacts_;
75 if (btf_handle_ ==
nullptr)
77 btf_handle_ = btf__parse(corpus_path().c_str(),
nullptr);
79 std::cerr <<
"Could not parse BTF information from file '"
80 << corpus_path().c_str() <<
"'" << std::endl;
90 {
return options().env;}
97 {
return const_cast<reader*
>(
this)->env();}
137 btf_type_id_to_abi_artifact_map_type&
138 btf_type_id_to_artifacts()
139 {
return btf_type_id_to_artifacts_;}
146 const btf_type_id_to_abi_artifact_map_type&
147 btf_type_id_to_artifacts()
const
148 {
return btf_type_id_to_artifacts_;}
158 lookup_artifact_from_btf_id(
int btf_id)
160 auto i = btf_type_id_to_artifacts().find(btf_id);
161 if (i != btf_type_id_to_artifacts().end())
174 {btf_type_id_to_artifacts()[btf_type_id] = artifact;}
181 schedule_type_for_canonocalization(
const type_base_sptr& t)
182 {types_to_canonicalize_.push_back(t);}
191 types_to_canonicalize_.end(),
192 [](
const vector<type_base_sptr>::const_iterator& i)
199 #ifdef WITH_BTF__GET_NR_TYPES
200 #define GET_NB_TYPES btf__get_nr_types
203 #ifdef WITH_BTF__TYPE_CNT
205 #define GET_NB_TYPES btf__type_cnt
213 return GET_NB_TYPES(
const_cast<reader*
>(
this)->btf_handle());
237 const vector<char**>& debug_info_root_paths,
239 bool linux_kernel_mode)
242 btf__free(btf_handle_);
243 options().load_all_types = load_all_types;
244 options().load_in_linux_kernel_mode = linux_kernel_mode;
262 reader(
const string& elf_path,
263 const vector<char**>& debug_info_root_paths,
264 environment& environment,
266 bool linux_kernel_mode)
267 : elf_based_reader(elf_path,
268 debug_info_root_paths,
272 load_all_types, linux_kernel_mode);
292 static btf::reader_sptr
293 create(
const string& elf_path,
294 const vector<char**>& debug_info_root_paths,
295 environment& environment,
297 bool linux_kernel_mode)
299 reader_sptr result(
new reader(elf_path, debug_info_root_paths, environment,
300 load_all_types, linux_kernel_mode));
307 btf__free(btf_handle_);
317 read_corpus(status& status)
323 origin |= corpus::BTF_ORIGIN;
324 corpus()->set_origin(origin);
326 if ((status & STATUS_NO_SYMBOLS_FOUND)
327 || !(status & STATUS_OK))
331 return corpus_sptr();
333 if (find_btf_section() ==
nullptr)
334 status |= STATUS_DEBUG_INFO_NOT_FOUND;
336 read_debug_info_into_corpus();
347 read_debug_info_into_corpus()
352 (
new translation_unit(env(),
"", 64));
353 corpus()->add(artificial_tu);
354 cur_tu(artificial_tu);
356 int number_of_types = nr_btf_types();
357 int first_type_id = 1;
361 for (
int type_id = first_type_id;
362 type_id < number_of_types;
369 bool do_construct_ir_node =
false;
371 const btf_type* t = btf__type_by_id(btf_handle(), type_id);
374 name = btf_offset_to_string(btf_handle(), t->name_off);
376 int kind = btf_kind(t);
377 if (kind == BTF_KIND_FUNC)
380 if (btf_vlen(t) == BTF_FUNC_GLOBAL
381 || btf_vlen(t) == BTF_FUNC_EXTERN
382 || function_symbol_is_exported(name))
383 do_construct_ir_node =
true;
385 else if (kind == BTF_KIND_VAR)
388 if (btf_vlen(t) == BTF_VAR_GLOBAL_ALLOCATED
389 || btf_vlen(t) == BTF_VAR_GLOBAL_EXTERN
390 || variable_symbol_is_exported(name))
391 do_construct_ir_node =
true;
393 else if (options().load_all_types)
394 do_construct_ir_node =
true;
396 if (do_construct_ir_node)
397 build_ir_node_from_btf_type(type_id);
401 corpus()->sort_functions();
402 corpus()->sort_variables();
413 build_ir_node_from_btf_type(
int type_id)
416 const btf_type *t =
nullptr;
418 if ((result = lookup_artifact_from_btf_id(type_id)))
422 result = build_ir_node_for_void_type();
424 t = btf__type_by_id(btf_handle(), type_id);
429 int type_kind = btf_kind(t);
434 result = build_int_type(type_id);
438 result = build_float_type(type_id);
441 case BTF_KIND_TYPEDEF:
442 result = build_typedef_type(type_id);
446 result = build_pointer_type(type_id);
450 result = build_array_type(type_id);
454 #ifdef WITH_BTF_ENUM64
455 case BTF_KIND_ENUM64:
457 result = build_enum_type(type_id);
460 case BTF_KIND_STRUCT:
462 result = build_class_or_union_type(type_id);
466 result = build_class_or_union_type(type_id);
470 case BTF_KIND_VOLATILE:
471 case BTF_KIND_RESTRICT:
472 result = build_qualified_type(type_id);
476 result = build_function_decl(type_id);
479 case BTF_KIND_FUNC_PROTO:
480 result = build_function_type(type_id);
484 result = build_variable_decl(type_id);
487 #ifdef WITH_BTF_KIND_TYPE_TAG
488 case BTF_KIND_TYPE_TAG:
490 #ifdef WITH_BTF_KIND_DECL_TAG
491 case BTF_KIND_DECL_TAG:
493 case BTF_KIND_DATASEC:
503 if (type_base_sptr type =
is_type(result))
504 schedule_type_for_canonocalization(type);
506 associate_artifact_to_btf_type_id(result, type_id);
509 add_fn_to_exported_or_undefined_decls(fn.get());
511 add_var_to_exported_or_undefined_decls(var.get());
520 build_ir_node_for_void_type()
522 type_base_sptr t = env().get_void_type();
532 build_ir_node_for_void_pointer_type()
534 type_base_sptr t = env().get_void_pointer_type();
544 build_ir_node_for_variadic_parameter_type()
546 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)
755 if (env().is_void_type(underlying_type))
758 return build_ir_node_for_void_pointer_type();
760 int size = elf_helpers::get_architecture_word_size(elf_handle());
775 build_array_type(
int type_id)
777 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
778 int kind = btf_kind(t);
781 const struct btf_array* arr = btf_array(t);
783 type_base_sptr underlying_type =
784 is_type(build_ir_node_from_btf_type(arr->type));
785 if (!underlying_type)
788 uint64_t lower_bound = 0;
790 uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
794 lower_bound, upper_bound,
796 subrange->is_non_finite(!arr->nelems);
801 subranges, location()));
813 build_qualified_type(
int type_id)
815 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
816 int kind = btf_kind(t);
818 || kind == BTF_KIND_VOLATILE
819 || kind == BTF_KIND_RESTRICT);
821 type_base_sptr underlying_type =
822 is_type(build_ir_node_from_btf_type(t->type));
823 if (!underlying_type)
827 if (kind == BTF_KIND_CONST)
828 qual |= qualified_type_def::CV_CONST;
829 else if (kind == BTF_KIND_VOLATILE)
830 qual |= qualified_type_def::CV_VOLATILE;
831 else if (kind == BTF_KIND_RESTRICT)
832 qual |= qualified_type_def::CV_RESTRICT;
836 qualified_type_def_sptr result(
new qualified_type_def(underlying_type,
849 build_class_or_union_type(
int type_id)
851 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
853 int kind = btf_kind(t);
855 || kind == BTF_KIND_UNION
856 || kind == BTF_KIND_FWD);
860 type_name = btf_offset_to_string(btf_handle(), t->name_off);
862 bool is_anonymous = type_name.empty();
863 uint64_t size = t->size;
866 bool is_decl_only = (kind == BTF_KIND_FWD);
868 class_or_union_sptr result;
869 if (kind == BTF_KIND_STRUCT
870 || (kind == BTF_KIND_FWD
871 && BTF_INFO_KFLAG(t->info) == 0 ))
872 result.reset(
new class_decl(env(), type_name, size,
876 decl_base::VISIBILITY_DEFAULT,
878 else if (kind == BTF_KIND_UNION
879 || (kind == BTF_KIND_FWD
880 && BTF_INFO_KFLAG(t->info) == 1))
881 result.reset(
new union_decl(env(), type_name, size, location(),
882 decl_base::VISIBILITY_DEFAULT,
888 result->set_is_declaration_only(is_decl_only);
892 associate_artifact_to_btf_type_id(result, type_id);
898 const struct btf_member *m =
899 reinterpret_cast<const struct btf_member*
>(t + 1);
900 uint64_t nb_members = btf_vlen(t);
902 for (uint64_t i = 0; i < nb_members; ++i, ++m)
904 type_base_sptr member_type =
905 is_type(build_ir_node_from_btf_type(m->type));
911 member_name = btf_offset_to_string(btf_handle(), m->name_off);
916 uint64_t offset_in_bits =
917 BTF_INFO_KFLAG(t->info)
918 ? BTF_MEMBER_BIT_OFFSET(m->offset)
921 result->add_data_member(data_member,
939 build_function_type(
int type_id)
941 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
942 int kind = btf_kind(t);
945 type_base_sptr return_type =
is_type(build_ir_node_from_btf_type(t->type));
946 if (return_type ==
nullptr)
949 int address_size = elf_helpers::get_architecture_word_size(elf_handle());
953 result->set_return_type(return_type);
955 associate_artifact_to_btf_type_id(result, type_id);
957 uint16_t nb_parms = btf_vlen(t);
958 const struct btf_param* parm =
959 reinterpret_cast<const struct btf_param*
>(t + 1);
962 for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
964 type_base_sptr parm_type;
966 bool is_variadic =
false;
968 if (parm->name_off == 0 && parm->type == 0)
971 parm_type = build_ir_node_for_variadic_parameter_type();
975 parm_name = btf_offset_to_string(btf_handle(), parm->name_off);
976 parm_type =
is_type(build_ir_node_from_btf_type(parm->type));
983 (
new function_decl::parameter(parm_type, parm_name,
984 location(), is_variadic));
985 function_parms.push_back(p);
987 result->set_parameters(function_parms);
989 cur_tu()->bind_function_type_life_time(result);
1002 build_function_decl(
int type_id)
1004 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1005 int kind = btf_kind(t);
1010 string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1012 type_base_sptr fn_type =
is_type(build_ir_node_from_btf_type(t->type));
1016 result.reset(
new function_decl(fn_name, fn_type,
false,
1017 location(), fn_name));
1020 if ((fn_sym = function_symbol_is_exported(fn_name))
1021 || (fn_sym = function_symbol_is_undefined(fn_name)))
1023 result->set_symbol(fn_sym);
1024 if (fn_sym->is_defined())
1025 result->set_is_in_public_symbol_table(
true);
1038 build_variable_decl(
int type_id)
1040 const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1041 int kind = btf_kind(t);
1046 string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1048 type_base_sptr var_type =
is_type(build_ir_node_from_btf_type(t->type));
1052 result.reset(
new var_decl(var_name, var_type, location(),
1056 if ((var_sym = variable_symbol_is_exported(var_name))
1057 || (var_sym = variable_symbol_is_undefined(var_name)))
1059 result->set_symbol(var_sym);
1060 if (var_sym->is_defined())
1061 result->set_is_in_public_symbol_table(
true);
1100 elf_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...
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)
Create and return a new read context to process CTF information from a given ELF file.
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.