libabigail
abg-btf-reader.cc
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2022-2025 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// This file contains the definitions of the front-end to analyze the
11 /// BTF information contained in an ELF file.
12 
13 #include "abg-internal.h"
14 
15 #ifdef WITH_BTF
16 
17 #include <bpf/btf.h>
18 #include <iostream>
19 #include <unordered_map>
20 
21 #include "abg-elf-helpers.h"
22 #include "abg-ir-priv.h"
23 
24 // <headers defining libabigail's API go under here>
25 ABG_BEGIN_EXPORT_DECLARATIONS
26 
27 #include "abg-btf-reader.h"
28 #include "abg-ir.h"
29 #include "abg-tools-utils.h"
30 
32 // </headers defining libabigail's API>
33 
34 namespace abigail
35 {
36 using namespace ir;
37 
38 /// Namespace of the reader for the BTF debug information.
39 namespace btf
40 {
41 
42 class reader;
43 
44 /// A convenience typedef for a shared pointer to
45 /// abigail::btf::reader.
46 typedef shared_ptr<reader> reader_sptr;
47 
48 static const char*
49 btf_offset_to_string(const ::btf* btf, uint32_t offset)
50 {
51  if (!offset)
52  return "__anonymous__";
53  return btf__name_by_offset(btf, offset) ?: "(invalid string offset)";
54 }
55 
56 /// A convenience typedef of a map that associates a btf type to a
57 /// libabigail ABI artifact. The type is allocated inside a given btf
58 /// handle (of type ::btf*). All handles (one for each kernel binary)
59 /// should be kept around until a complete corpus group is built.
60 typedef std::unordered_map<const btf_type*, type_or_decl_base_sptr>
61 btf_type_to_abi_artifact_map_type;
62 
63 /// The BTF front-end abstraction type.
64 ///
65 /// Note that one instance of front-end is meant to analyze one
66 /// vmlinux file and all its associated modules. For now, the
67 /// front-end doesn't know how to analyze a module without having
68 /// analyzed a vmlinux first.
69 ///
70 /// The BTF information of a vmlinux is parsed with the btf__parse
71 /// function. The result is called a "base BTF" handle.
72 ///
73 /// The BTF information of a kernel module is parsed with the function
74 /// btf__parse_split. The result is called a "split BTF" handle. A
75 /// split BTF handle references information that are in the base BTF
76 /// handle. The base BTF handle can be retrieved from a split BTF
77 /// handle using btf__base_btf.
78 class reader : public elf_based_reader
79 {
80  ::btf* base_btf_handle_ = nullptr;
81  // The path to the binary that contains the base BTF information
82  // held in base_btf_handle_
83  string base_btf_file_name_;
84  ::btf* split_btf_handle_ = nullptr;
85  // The path to the binary that contains the split BTF information
86  // held in split_btf_handle_
87  string split_btf_file_name_;
88  // A vector of (split) BTF objects that are to be freed once the
89  // corpus group is built for an entire kernel (vmliunx + modules).
90  vector<::btf*> split_btfs_to_free_;
91  translation_unit_sptr cur_tu_;
92  vector<type_base_sptr> types_to_canonicalize_;
93  btf_type_to_abi_artifact_map_type btf_type_to_artifacts_;
94 
95  /// Getter of the "do_log" flag.
96  ///
97  /// This flag tells if we should log about various internal
98  /// details.
99  ///
100  /// return the "do_log" flag.
101  bool
102  do_log() const
103  {return options().do_log;}
104 
105  /// Setter of the "do_log" flag.
106  ///
107  /// This flag tells if we should log about various internal details.
108  ///
109  /// @param f the new value of the flag.
110  void
111  do_log(bool f)
112  {options().do_log = f;}
113 
114  /// Getter of the "show_stats" flag.
115  ///
116  /// This flag tells if we should emit statistics about various
117  /// internal stuff.
118  ///
119  /// @return the value of the flag.
120  bool
121  show_stats() const
122  {return options().show_stats;}
123 
124  /// Setter of the "show_stats" flag.
125  ///
126  /// This flag tells if we should emit statistics about various
127  /// internal stuff.
128  ///
129  /// @param f the value of the flag.
130  void
131  show_stats(bool f)
132  {options().show_stats = f;}
133 
134  /// Getter of the handle to the base BTF object of the current
135  /// binary being analyzed.
136  ///
137  /// The base BTF object ALWAYS represents the BTF information of the
138  /// vmlinux binary, even if the current binary being analyzed is a
139  /// kernel module.
140  ///
141  /// @return handle to the base BTF object of the current binary
142  /// being analyzed.
143  ::btf*
144  base_btf_handle()
145  {
146  if (base_btf_handle_ == nullptr)
147  {
148  base_btf_handle_ = btf__parse(corpus_path().c_str(), nullptr);
149  if (!base_btf_handle_)
150  {
151  std::cerr << "Could not parse base BTF information from file '"
152  << corpus_path().c_str() << "'" << std::endl;
153  return nullptr;
154  }
155  base_btf_file_name_ = corpus_path();
156  }
157  return base_btf_handle_;
158  }
159 
160  /// Read the BTF information of the current binary which path is
161  /// @ref fe_iface::corpus_path() and return its associated object
162  /// handle. This is called the split BTF object.
163  ///
164  /// Note that this function expects the base BTF object (the one for
165  /// the vmlinux binary) to be already present, otherwise, it returns
166  /// nullptr.
167  ///
168  /// @return the split BTF object for the file designed by
169  /// fe_iface::corpus_path().
170  ::btf*
171  read_split_btf()
172  {
173  if (!base_btf_handle_)
174  {
175  std::cerr << "Base BTF information not present. "
176  << "Not attempting to parse split BTF information"
177  << std::endl;
178  return nullptr;
179  }
180 
181  if (corpus_path().empty() || corpus_path() == base_btf_file_name_)
182  {
183  std::cerr << "BTF reader not initialized with split file name. "
184  << "Not attending to read split BTF information"
185  << std::endl;
186  return nullptr;
187  }
188 
189  split_btf_handle_ = btf__parse_split(corpus_path().c_str(),
190  base_btf_handle());
191  if (!split_btf_handle_)
192  {
193  std::cerr << "Could not read split BTF information from file "
194  << corpus_path() << std::endl;
195  return nullptr;
196  }
197  split_btf_file_name_ = corpus_path();
198 
199  return split_btf_handle_;
200  }
201 
202  /// Getter of the handle to the BTF object as returned by libbpf.
203  ///
204  /// This returns the handle to the current BTF object. If the
205  /// current BTF object is for a vmlinux binary, then it's the base
206  /// BTF object that is returned. Otherwise, if the current BTF
207  /// object if for a kernel module then it's the split BTF object
208  /// that is returned.
209  ///
210  /// @return the handle to the BTF object of the current binary being
211  /// analyeed by this front-end.
212  ::btf*
213  btf_handle()
214  {
215  if (split_btf_handle_)
216  return split_btf_handle_;
217 
218  if (!base_btf_handle_)
219  return base_btf_handle();
220 
221  if (corpus_path() != base_btf_file_name_)
222  // The reader was re-initialized with a corpus_path that is
223  // different from the the BTF base file. That means we are
224  // instructed to read a split BTF file information.
225  return read_split_btf();
226 
227  return base_btf_handle();
228  }
229 
230  /// Getter of the environment of the current front-end.
231  ///
232  /// @return The environment of the current front-end.
233  environment&
234  env()
235  {return options().env;}
236 
237  /// Getter of the environment of the current front-end.
238  ///
239  /// @return The environment of the current front-end.
240  const environment&
241  env() const
242  {return const_cast<reader*>(this)->env();}
243 
244  /// Getter of the current translation unit being built.
245  ///
246  /// Actually, BTF doesn't keep track of the translation unit each
247  /// ABI artifact originates from. So an "artificial" translation
248  /// unit is built. It contains all the ABI artifacts of the binary.
249  ///
250  /// @return The current translation unit being built.
252  cur_tu()
253  {return cur_tu_;}
254 
255  /// Getter of the current translation unit being built.
256  ///
257  /// Actually, BTF doesn't keep track of the translation unit each
258  /// ABI artifact originates from. So an "artificial" translation
259  /// unit is built. It contains all the ABI artifacts of the binary.
260  ///
261  /// @return The current translation unit being built.
262  const translation_unit_sptr&
263  cur_tu() const
264  {return cur_tu_;}
265 
266  /// Getter of the current translation unit being built.
267  ///
268  /// Actually, BTF doesn't keep track of the translation unit each
269  /// ABI artifact originates from. So an "artificial" translation
270  /// unit is built. It contains all the ABI artifacts of the binary.
271  ///
272  /// @return The current translation unit being built.
273  void
274  cur_tu(const translation_unit_sptr& tu)
275  {cur_tu_ = tu;}
276 
277  /// Getter of the map that associates a BTF type to the internal
278  /// representation of an ABI artifact.
279  ///
280  /// @return The map that associates a BTF type to the IR of an ABI
281  /// artifact.
282  btf_type_to_abi_artifact_map_type&
283  btf_type_to_artifacts()
284  {return btf_type_to_artifacts_;}
285 
286  /// Getter of the map that associates a BTF type to the IR of an ABI
287  /// artifact.
288  ///
289  /// @return The map that associates a BTF type to the IR of an ABI
290  /// artifact.
291  const btf_type_to_abi_artifact_map_type&
292  btf_type_to_artifacts() const
293  {return btf_type_to_artifacts_;}
294 
295  /// Get the IR of the ABI artifact that is associated to a given BTF
296  /// type.
297  ///
298  /// If no ABI artifact is associated to the BTF type, then return
299  /// nullptr.
300  ///
301  /// @return the ABI artifact that is associated to a given BTF type.
303  lookup_artifact_from_btf_type(const btf_type* t)
304  {
305  auto i = btf_type_to_artifacts().find(t);
306  if (i != btf_type_to_artifacts().end())
307  return i->second;
308  return type_or_decl_base_sptr();
309  }
310 
311  /// Associate an ABI artifact to a given BTF type.
312  ///
313  /// @param artifact the ABI artifact to consider.
314  ///
315  /// @param btf_type_id the BTF type to associate to @p artifact.
316  void
317  associate_artifact_to_btf_type(const type_or_decl_base_sptr& artifact,
318  const btf_type* t)
319  {btf_type_to_artifacts()[t] = artifact;}
320 
321  /// Schecule a type for canonicalization at the end of the debug
322  /// info loading.
323  ///
324  /// @param t the type to schedule.
325  void
326  schedule_type_for_canonicalization(const type_base_sptr& t)
327  {
328  if (t && !t->get_naked_canonical_type())
329  types_to_canonicalize_.push_back(t);
330  }
331 
332  /// Canonicalize all the types scheduled for canonicalization using
333  /// abigail::ir::canonicalize_types() which performs some sanity
334  /// checking around type canonicalization if necessary.
335  void
337  {
338  tools_utils::timer cn_timer;
339  if (do_log())
340  {
341  std::cerr << "BTF Reader is going to canonicalize "
342  << std::dec
343  << types_to_canonicalize_.size()
344  << " types";
345  corpus_sptr c = corpus();
346  if (c)
347  std::cerr << " from corpus " << corpus()->get_path() << "\n";
348  cn_timer.start();
349  }
350 
351  ir::hash_and_canonicalize_types(types_to_canonicalize_.begin(),
352  types_to_canonicalize_.end(),
353  [](const vector<type_base_sptr>::const_iterator& i)
354  {return *i;}, do_log(), show_stats());
355 
356  if (do_log())
357  {
358  cn_timer.stop();
359  std::cerr << "BTF Reader finished types "
360  << "sorting, hashing & canonicalizing in: "
361  << cn_timer << "\n";
362  }
363 
364  }
365 
366  /// Getter of the number of types carried by a given BTF object.
367  ///
368  /// @param handle the BTF object to consider.
369  ///
370  /// @return the number of types carried by a given BTF object.
371  uint64_t
372  nr_btf_types(const ::btf* handle) const
373  {
374 #ifdef WITH_BTF__GET_NR_TYPES
375 #define GET_NB_TYPES btf__get_nr_types
376 #endif
377 
378 #ifdef WITH_BTF__TYPE_CNT
379 #undef GET_NB_TYPES
380 #define GET_NB_TYPES btf__type_cnt
381 #endif
382 
383 #ifndef GET_NB_TYPES
385  return 0;
386 #endif
387 
388  return GET_NB_TYPES(handle);
389  }
390 
391 protected:
392  reader() = delete;
393 
394  /// Initializer of the current instance of @ref btf::reader.
395  ///
396  /// This frees the resources used by the current instance of @ref
397  /// btf::reader and gets it ready to analyze another ELF
398  /// file.
399  ///
400  /// @param elf_path the path to the ELF file to read from.
401  ///
402  /// @param debug_info_root_paths the paths where to look for
403  /// seperate debug info.
404  ///
405  /// @param load_all_types if true, then load all the types described
406  /// in the binary, rather than loading only the types reachable from
407  /// the exported decls.
408  ///
409  /// @param linux_kernel_mode
410  void
411  initialize(const string& elf_path,
412  const vector<string>& debug_info_root_paths,
413  bool load_all_types,
414  bool linux_kernel_mode)
415  {
416  if (split_btf_handle_)
417  {
418  // We need to keep this split_btf_handle_ on the side so that
419  // we can free it when we are done analyzing all the kernel
420  // modules. We cannot free it right now because the memory of
421  // all btf types lives in it.
422  split_btfs_to_free_.push_back(split_btf_handle_);
423  split_btf_handle_ = nullptr;
424  }
425 
426  split_btf_file_name_.clear();
427  types_to_canonicalize_.clear();
428  cur_tu_.reset();
429  elf_based_reader::initialize(elf_path, debug_info_root_paths);
430  corpus_path(elf_path);
431  options().load_all_types = load_all_types;
432  options().load_in_linux_kernel_mode = linux_kernel_mode;
433  }
434 
435  /// Constructor of the btf::reader type.
436  ///
437  /// @param elf_path the path to the ELF file to analyze.
438  ///
439  /// @param debug_info_root_paths the set of directory where to look
440  /// debug info from, for cases where the debug is split.
441  ///
442  /// @param environment the environment of the current front-end.
443  ///
444  /// @param load_all_types if true load all the types described by
445  /// the BTF debug info, as opposed to loading only the types
446  /// reachable from the decls that are defined and exported.
447  ///
448  /// @param linux_kernel_mode if true, then consider the binary being
449  /// analyzed as a linux kernel binary.
450  reader(const string& elf_path,
451  const vector<string>& debug_info_root_paths,
452  environment& environment,
453  bool load_all_types,
454  bool linux_kernel_mode)
455  : elf_based_reader(elf_path,
456  debug_info_root_paths,
457  environment)
458  {
459  initialize(elf_path, debug_info_root_paths,
460  load_all_types, linux_kernel_mode);
461  }
462 
463 public:
464 
465  /// Constructor of the btf::reader type.
466  ///
467  /// @param elf_path the path to the ELF file to analyze.
468  ///
469  /// @param debug_info_root_paths the set of directory where to look
470  /// debug info from, for cases where the debug is split.
471  ///
472  /// @param environment the environment of the current front-end.
473  ///
474  /// @param load_all_types if true load all the types described by
475  /// the BTF debug info, as opposed to loading only the types
476  /// reachable from the decls that are defined and exported.
477  ///
478  /// @param linux_kernel_mode if true, then consider the binary being
479  /// analyzed as a linux kernel binary.
480  static btf::reader_sptr
481  create(const string& elf_path,
482  const vector<string>& debug_info_root_paths,
483  environment& environment,
484  bool load_all_types,
485  bool linux_kernel_mode)
486  {
487  reader_sptr result(new reader(elf_path, debug_info_root_paths, environment,
488  load_all_types, linux_kernel_mode));
489  return result;
490  }
491 
492  /// Destructor of the btf::reader type.
493  ~reader()
494  {
495  for (auto b : split_btfs_to_free_)
496  btf__free(b);
497  btf__free(split_btf_handle_);
498  btf__free(base_btf_handle_);
499  split_btf_handle_ = nullptr;
500  base_btf_handle_ = nullptr;
501  }
502 
503  /// Read the ELF information as well as the BTF type information to
504  /// build an ABI corpus.
505  ///
506  /// @param status output parameter. The status of the analysis.
507  ///
508  /// @return the resulting ABI corpus.
509  corpus_sptr
510  read_corpus(status& status)
511  {
512  // Read the properties of the ELF file.
513  elf::reader::read_corpus(status);
514 
515  corpus::origin origin = corpus()->get_origin();
516  origin |= corpus::BTF_ORIGIN;
517  corpus()->set_origin(origin);
518  if (corpus_group())
519  {
520  origin |= corpus_group()->get_origin();
521  corpus_group()->set_origin(origin);
522  }
523 
524  if ((status & STATUS_NO_SYMBOLS_FOUND)
525  || !(status & STATUS_OK))
526  // Either we couldn't find ELF symbols or something went badly
527  // wrong. There is nothing we can do with this ELF file. Bail
528  // out.
529  return corpus_sptr();
530 
531  if (find_btf_section() == nullptr)
532  status |= STATUS_DEBUG_INFO_NOT_FOUND;
533 
534  read_debug_info_into_corpus();
535 
536  status |= STATUS_OK;
537 
538  return corpus();
539  }
540 
541  /// Read the BTF debug info to construct the ABI corpus.
542  ///
543  /// @return the resulting ABI corpus.
544  corpus_sptr
545  read_debug_info_into_corpus()
546  {
547  if (!btf_handle())
548  return corpus_sptr();
549 
550  translation_unit_sptr artificial_tu
551  (new translation_unit(env(), "", /*address_size=*/64));
552  corpus()->add(artificial_tu);
553  cur_tu(artificial_tu);
554 
555 #ifdef WITH_DEBUG_SELF_COMPARISON
556  if (env().self_comparison_debug_is_on())
557  {
558  corpus_group_sptr g = corpus_group();
559  if (g)
560  env().set_self_comparison_debug_input(g);
561  else
562  env().set_self_comparison_debug_input(corpus());
563  }
564 #endif
565 
566  int number_of_types = nr_btf_types(btf_handle());
567  int first_type_id = 1;
568  // Are we looking at the BTF for a kernel module?
569  const ::btf* base = btf__base_btf(btf_handle());
570  if (base)
571  {
572  // So, base is non-nil. This means we are looking at the BTF
573  // for a kernel module and base points to the BTF for the
574  // corresponding vmlinux. That base BTF should be the same as
575  // base_btf_handle().
576  ABG_ASSERT(base == base_btf_handle());
577 
578  // The ID of the first type that is contained in this BTF
579  // representing a kernel module is the number of types
580  // contained in the base BTF (i.e, the BTF for the vmlinux
581  // binary).
582  first_type_id = nr_btf_types(base);
583  }
584 
585  // Let's cycle through whatever is described in the BTF section
586  // and emit libabigail IR for it.
587  for (int type_id = first_type_id;
588  type_id < number_of_types;
589  ++type_id)
590  {
591  // Build IR nodes only for decls (functions and variables)
592  // that have associated ELF symbols that are publicly defined
593  // and exported, unless the user asked to load all types.
594 
595  bool do_construct_ir_node = false;
596 
597  const btf_type* t = btf__type_by_id(btf_handle(), type_id);
598  string name;
599  if (t->name_off)
600  name = btf_offset_to_string(btf_handle(), t->name_off);
601 
602  int kind = btf_kind(t);
603  if (kind == BTF_KIND_FUNC)
604  {
605  ABG_ASSERT(!name.empty());
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;
610  }
611  else if (kind == BTF_KIND_VAR)
612  {
613  ABG_ASSERT(!name.empty());
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;
618  }
619  else if (options().load_all_types)
620  do_construct_ir_node = true;
621 
622  if (do_construct_ir_node)
623  build_ir_node_from_btf_type(type_id);
624  }
625 
627  corpus()->sort_functions();
628  corpus()->sort_variables();
629  return corpus();
630  }
631 
632  /// Build an abigail IR node for a given type described by a BTF
633  /// type ID. The node is added to the ABI corpus.
634  ///
635  /// @param type_id the ID of the type to build and IR node for.
636  ///
637  /// @return the IR node representing the type @p type_id.
639  build_ir_node_from_btf_type(int type_id)
640  {
641  type_or_decl_base_sptr result;
642  const btf_type *t = nullptr;
643 
644  t = btf__type_by_id(btf_handle(), type_id);
645 
646  if ((result = lookup_artifact_from_btf_type(t)))
647  return result;
648 
649  if (!result)
650  {
651  ABG_ASSERT(t);
652  int type_kind = btf_kind(t);
653 
654  switch(type_kind)
655  {
656  case BTF_KIND_UNKN/* Unknown: This is really for the void
657  type. */:
658  result = build_ir_node_for_void_type();
659  break;
660 
661  case BTF_KIND_INT/* Integer */:
662  result = build_int_type(type_id);
663  break;
664 
665  case BTF_KIND_FLOAT/* Floating point */:
666  result = build_float_type(type_id);
667  break;
668 
669  case BTF_KIND_TYPEDEF/* Typedef*/:
670  result = build_typedef_type(type_id);
671  break;
672 
673  case BTF_KIND_PTR/* Pointer */:
674  result = build_pointer_type(type_id);
675  break;
676 
677  case BTF_KIND_ARRAY/* Array */:
678  result = build_array_type(type_id);
679  break;
680 
681  case BTF_KIND_ENUM/* Enumeration up to 32-bit values */:
682 #ifdef WITH_BTF_ENUM64
683  case BTF_KIND_ENUM64/* Enumeration up to 64-bit values */:
684 #endif
685  result = build_enum_type(type_id);
686  break;
687 
688  case BTF_KIND_STRUCT/* Struct */:
689  case BTF_KIND_UNION/* Union */:
690  result = build_class_or_union_type(type_id);
691  break;
692 
693  case BTF_KIND_FWD/* Forward */:
694  result = build_class_or_union_type(type_id);
695  break;
696 
697  case BTF_KIND_CONST/* Const */:
698  case BTF_KIND_VOLATILE/* Volatile */:
699  case BTF_KIND_RESTRICT/* Restrict */:
700  result = build_qualified_type(type_id);
701  break;
702 
703  case BTF_KIND_FUNC/* Function */:
704  result = build_function_decl(type_id);
705  break;
706 
707  case BTF_KIND_FUNC_PROTO/* Function Proto */:
708  result = build_function_type(type_id);
709  break;
710 
711  case BTF_KIND_VAR/* Variable */:
712  result = build_variable_decl(type_id);
713  break;
714 
715 #ifdef WITH_BTF_KIND_TYPE_TAG
716  case BTF_KIND_TYPE_TAG/* Type Tag */:
717  break;
718 #endif
719 #ifdef WITH_BTF_KIND_DECL_TAG
720  case BTF_KIND_DECL_TAG/* Decl Tag */:
721  break;
722 #endif
723  case BTF_KIND_DATASEC/* Section */:
724  break;
725  default:
727  break;
728  }
729  }
730 
731  add_decl_to_scope(is_decl(result), cur_tu()->get_global_scope());
732 
733  if (type_base_sptr type = is_type(result))
734  schedule_type_for_canonicalization(type);
735 
736  associate_artifact_to_btf_type(result, t);
737 
738  if (function_decl_sptr fn = is_function_decl(result))
739  add_fn_to_exported_or_undefined_decls(fn.get());
740  else if (var_decl_sptr var = is_var_decl(result))
741  add_var_to_exported_or_undefined_decls(var);
742 
743  return result;
744  }
745 
746  /// Build an IR node for the "void" type.
747  ///
748  /// @return the IR node for the void type.
749  type_base_sptr
750  build_ir_node_for_void_type()
751  {
752  type_base_sptr t = env().get_void_type();
753  add_decl_to_scope(is_decl(t), cur_tu()->get_global_scope());
754  schedule_type_for_canonicalization(t);
755  return t;
756  }
757 
758  /// Build an IR node for the "void" type.
759  ///
760  /// @return the IR node for the void type.
761  type_base_sptr
762  build_ir_node_for_void_pointer_type()
763  {
764  type_base_sptr t = env().get_void_pointer_type();
765  add_decl_to_scope(is_decl(t), cur_tu()->get_global_scope());
766  schedule_type_for_canonicalization(t);
767  return t;
768  }
769 
770  /// Build an IR node for the "variadic parameter" type.
771  ///
772  /// @return the IR node for the "variadic parameter" type.
773  type_base_sptr
774  build_ir_node_for_variadic_parameter_type()
775  {
776  type_base_sptr t = env().get_variadic_parameter_type();
777  add_decl_to_scope(is_decl(t), cur_tu()->get_global_scope());
778  decl_base_sptr t_decl = get_type_declaration(t);
779  schedule_type_for_canonicalization(t);
780  return t;
781  }
782 
783  /// Build an IR node for an integer type expressed in BTF.
784  ///
785  /// @param t a pointer a BTF type describing an integer.
786  ///
787  /// @return a pointer to @ref type_decl representing an integer
788  /// type.
790  build_int_type(int type_id)
791  {
792  type_decl_sptr result;
793 
794  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
795  ABG_ASSERT(btf_kind(t) == BTF_KIND_INT);
796 
797  uint32_t info = *reinterpret_cast<const uint32_t*>(t + 1);
798  uint64_t byte_size = 0, bit_size = 0;
799  string type_name;
800 
801  byte_size = t->size;
802  bit_size = byte_size * 8;
803 
804  if (BTF_INT_ENCODING(info) & BTF_INT_CHAR)
805  {
806  if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
807  type_name = "unsigned ";
808  type_name += "char";
809  }
810  else if (BTF_INT_ENCODING(info) & BTF_INT_BOOL)
811  type_name = "bool";
812  else if (!(BTF_INT_ENCODING(info) & BTF_INT_SIGNED))
813  {
814  type_name = "unsigned ";
815  type_name += btf_offset_to_string(btf_handle(), t->name_off);
816  }
817  else
818  type_name = btf_offset_to_string(btf_handle(), t->name_off);
819 
820  location loc;
821  result.reset(new type_decl(env(), type_name,
822  bit_size, /*alignment=*/0,
823  loc, type_name));
824 
825  return result;
826  }
827 
828  /// Build an IR node for a float type expressed in BTF.
829  ///
830  /// @return a pointer to @ref type_decl representing a float type.
832  build_float_type(int type_id)
833  {
834  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
835  ABG_ASSERT(btf_kind(t) == BTF_KIND_FLOAT);
836 
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;
839  location loc;
840  type_decl_sptr result(new type_decl(env(), type_name, bit_size,
841  /*alignment=*/0, loc, type_name));
842 
843  return result;
844  }
845 
846  /// Build an IR type that represents the underlying type of an enum type.
847  ///
848  /// This is a sub-routine of the build_enum_type() function.
849  ///
850  /// @param enum_name the name of the enum type this type is an
851  /// underlying type for.
852  ///
853  /// @param enum_size the size of the enum.
854  ///
855  /// @param is_anonymous if true, the enum type is anonymous.
856  ///
857  /// @return a pointer to type_decl that represents a integer type
858  /// that is the underlying type of an enum type.
860  build_enum_underlying_type(const string enum_name, uint64_t enum_size,
861  bool is_anonymous = true)
862  {
863  string underlying_type_name =
865  is_anonymous,
866  enum_size);
867  type_decl_sptr result(new type_decl(env(), underlying_type_name,
868  enum_size, enum_size, location()));
869  result->set_is_anonymous(is_anonymous);
870  result->set_is_artificial(true);
871  add_decl_to_scope(result, cur_tu()->get_global_scope());
872  schedule_type_for_canonicalization(result);
873  return result;
874  }
875 
876  /// Build an IR node that represents an enum type expressed in BTF.
877  ///
878  /// @param type_id the ID of the BTF representation of the enum.
879  ///
880  /// @return a pointer to @ref enum_type_decl representing @p t.
882  build_enum_type(int type_id)
883  {
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);
888 #else
889  ABG_ASSERT(kind == BTF_KIND_ENUM);
890 #endif
891 
892  int byte_size = t->size, bit_size = byte_size * 8;
893 
894  string enum_name;
895  if (t->name_off)
896  enum_name = btf_offset_to_string(btf_handle(), t->name_off);
897  bool is_anonymous = enum_name.empty();
898 
899  int num_enms = btf_vlen(t);
901  string e_name;
902  if (kind == BTF_KIND_ENUM)
903  {
904  const struct btf_enum* e = btf_enum(t);
905  uint32_t e_value = 0;
906  for (int i = 0; i < num_enms; ++i, ++e)
907  {
908  e_name = btf_offset_to_string(btf_handle(), e->name_off);
909  e_value = e->val;
910  enms.push_back(enum_type_decl::enumerator(e_name, e_value));
911  }
912  }
913 #ifdef WITH_BTF_ENUM64
914  else if (kind == BTF_KIND_ENUM64)
915  {
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)
920  {
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));
924  }
925  }
926 #endif
927  else
929 
930  type_decl_sptr underlying_type =
931  build_enum_underlying_type(enum_name, bit_size, is_anonymous);
932  enum_type_decl_sptr result(new enum_type_decl(enum_name,
933  location(),
934  underlying_type,
935  enms, enum_name));
936  result->set_is_anonymous(is_anonymous);
937  return result;
938  }
939 
940  /// Build an IR node for a typedef that is expressed in BTF.
941  ///
942  /// @param type_id the ID of the BTF representation of a typedef.
943  ///
944  /// @return a pointer to @ref typedef_decl representing @p t.
946  build_typedef_type(int type_id)
947  {
948  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
949  int kind = btf_kind(t);
950  ABG_ASSERT(kind == BTF_KIND_TYPEDEF);
951 
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)
956  return type_or_decl_base_sptr();
957 
958  typedef_decl_sptr result(new typedef_decl(type_name, underlying_type,
959  location(),
960  /*linkage_name=*/type_name));
961  if ((is_class_or_union_type(underlying_type)
962  || is_enum_type(underlying_type))
963  && is_anonymous_type(underlying_type))
964  get_type_declaration(underlying_type)->set_naming_typedef(result);
965 
966  return result;
967  }
968 
969  /// Build an IR node representing a pointer described in BTF.
970  ///
971  /// @param type_id the ID of a BTF representation of a pointer type.
972  ///
973  /// @return a pointer to pointer_type_def that represents @p t.
975  build_pointer_type(int type_id)
976  {
977  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
978  int kind = btf_kind(t);
979  ABG_ASSERT(kind == BTF_KIND_PTR);
980 
981  type_base_sptr underlying_type =
982  is_type(build_ir_node_from_btf_type(t->type));
983  if (!underlying_type)
984  return type_or_decl_base_sptr();
985  if (env().is_void_type(underlying_type))
986  // Recognize a pointer to void and return a special unique IR
987  // for it.
988  return build_ir_node_for_void_pointer_type();
989 
990  int size = elf_helpers::get_architecture_word_size(elf_handle());
991  size *= 8;
992  pointer_type_def_sptr result(new pointer_type_def(underlying_type, size,
993  /*alignment=*/0,
994  location()));
995  return result;
996  }
997 
998  /// Build an IR node representing an array type described in BTF.
999  ///
1000  /// @param type_id the ID of the BTF representation of an array
1001  /// type.
1002  ///
1003  /// return a pointer to @ref array_type_def representing @p t.
1005  build_array_type(int type_id)
1006  {
1007  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1008  int kind = btf_kind(t);
1009  ABG_ASSERT(kind == BTF_KIND_ARRAY);
1010 
1011  const struct btf_array* arr = btf_array(t);
1012 
1013  type_base_sptr underlying_type =
1014  is_type(build_ir_node_from_btf_type(arr->type));
1015  if (!underlying_type)
1016  return type_or_decl_base_sptr();
1017 
1018  uint64_t lower_bound = 0;
1019  // Note that arr->nelems can be 0;
1020  uint64_t upper_bound = arr->nelems ? arr->nelems - 1: 0;
1021 
1022  array_type_def::subrange_sptr subrange(new array_type_def::subrange_type
1023  (env(), /*name=*/"",
1024  lower_bound, upper_bound,
1025  location()));
1026  subrange->is_non_finite(!arr->nelems);
1027  subrange->set_size_in_bits(cur_tu()->get_address_size());
1028  add_decl_to_scope(subrange, cur_tu()->get_global_scope());
1029  schedule_type_for_canonicalization(subrange);
1030  array_type_def::subranges_type subranges = {subrange};
1031  array_type_def_sptr result(new array_type_def(underlying_type,
1032  subranges, location()));
1033 
1034  return result;
1035  }
1036 
1037  /// Build an IR node representing a qualified type described in BTF.
1038  ///
1039  /// @param type_id the ID of the BTF representation of an array
1040  /// type.
1041  ///
1042  /// @return a pointer to a qualified_type_def representing @ t.
1044  build_qualified_type(int type_id)
1045  {
1046  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1047  int kind = btf_kind(t);
1048  ABG_ASSERT(kind == BTF_KIND_CONST
1049  || kind == BTF_KIND_VOLATILE
1050  || kind == BTF_KIND_RESTRICT);
1051 
1052  type_base_sptr underlying_type =
1053  is_type(build_ir_node_from_btf_type(t->type));
1054  if (!underlying_type)
1055  return type_or_decl_base_sptr();
1056 
1057  qualified_type_def::CV qual = qualified_type_def::CV_NONE;
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;
1064  else
1066 
1067  qualified_type_def_sptr result(new qualified_type_def(underlying_type,
1068  qual, location()));
1069  return result;
1070  }
1071 
1072  /// Build an IR node for a class or union type expressed in BTF.
1073  ///
1074  /// @param type_id the ID of a pointer to a BTF type describing a
1075  /// class or union type.
1076  ///
1077  /// @return a pointer to either a @ref class_decl or a @ref
1078  /// union_decl type representing the type expressed by @p t.
1080  build_class_or_union_type(int type_id)
1081  {
1082  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1083 
1084  int kind = btf_kind(t);
1085  ABG_ASSERT(kind == BTF_KIND_STRUCT
1086  || kind == BTF_KIND_UNION
1087  || kind == BTF_KIND_FWD);
1088 
1089  string type_name;
1090  if (t->name_off)
1091  type_name = btf_offset_to_string(btf_handle(), t->name_off);
1092 
1093  bool is_anonymous = type_name.empty();
1094  uint64_t size = t->size;
1095  size *= 8;
1096 
1097  bool is_decl_only = (kind == BTF_KIND_FWD);
1098 
1099  class_or_union_sptr result;
1100  if (kind == BTF_KIND_STRUCT
1101  || (kind == BTF_KIND_FWD
1102  && BTF_INFO_KFLAG(t->info) == 0 /*struct*/))
1103  result.reset(new class_decl(env(), type_name, size,
1104  /*alignment=*/0,
1105  /*is_struct=*/true,
1106  location(),
1107  decl_base::VISIBILITY_DEFAULT,
1108  is_anonymous));
1109  else if (kind == BTF_KIND_UNION
1110  || (kind == BTF_KIND_FWD
1111  && BTF_INFO_KFLAG(t->info) == 1/*union*/))
1112  result.reset(new union_decl(env(), type_name, size, location(),
1113  decl_base::VISIBILITY_DEFAULT,
1114  is_anonymous));
1115  else
1117 
1118  if (is_decl_only)
1119  result->set_is_declaration_only(is_decl_only);
1120 
1121  add_decl_to_scope(result, cur_tu()->get_global_scope());
1122 
1123  associate_artifact_to_btf_type(result, t);
1124 
1125  // For defined classes and unions, add data members to the type
1126  // being built.
1127  if (!is_decl_only)
1128  {
1129  const struct btf_member *m =
1130  reinterpret_cast<const struct btf_member*>(t + 1);
1131  uint64_t nb_members = btf_vlen(t);
1132 
1133  for (uint64_t i = 0; i < nb_members; ++i, ++m)
1134  {
1135  type_base_sptr member_type =
1136  is_type(build_ir_node_from_btf_type(m->type));
1137  if (!member_type)
1138  continue;
1139 
1140  string member_name;
1141  if (m->name_off)
1142  member_name = btf_offset_to_string(btf_handle(), m->name_off);
1143  var_decl_sptr data_member(new var_decl(member_name,
1144  member_type,
1145  location(),
1146  /*linkage_name=*/""));
1147  uint64_t offset_in_bits =
1148  BTF_INFO_KFLAG(t->info)
1149  ? BTF_MEMBER_BIT_OFFSET(m->offset)
1150  : m->offset;
1151 
1152  result->add_data_member(data_member,
1153  public_access,
1154  /*is_laid_out=*/true,
1155  /*is_static=*/false,
1156  offset_in_bits);
1157  }
1158  }
1159  return result;
1160  }
1161 
1162  /// Build an IR node for a function type expressed in BTF.
1163  ///
1164  /// @param type_id the ID of a pointer to a BTF type describing a
1165  /// function type.
1166  ///
1167  /// @return a pointer to a @ref function_type representing the
1168  /// function type expressed by @p t.
1170  build_function_type(int type_id)
1171  {
1172  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1173  int kind = btf_kind(t);
1174  ABG_ASSERT(kind == BTF_KIND_FUNC_PROTO);
1175 
1176  type_base_sptr return_type = is_type(build_ir_node_from_btf_type(t->type));
1177  if (return_type == nullptr)
1178  return type_or_decl_base_sptr();
1179 
1180  int address_size = elf_helpers::get_architecture_word_size(elf_handle());
1181  address_size *= 8;
1182  function_type_sptr result(new function_type(env(), address_size,
1183  /*alignment=*/0));
1184  result->set_return_type(return_type);
1185 
1186  associate_artifact_to_btf_type(result, t);
1187 
1188  uint16_t nb_parms = btf_vlen(t);
1189  const struct btf_param* parm =
1190  reinterpret_cast<const struct btf_param*>(t + 1);
1191 
1192  function_decl::parameters function_parms;
1193  for (uint16_t i = 0; i < nb_parms; ++i, ++parm)
1194  {
1195  type_base_sptr parm_type;
1196  string parm_name;
1197  bool is_variadic = false;
1198 
1199  if (parm->name_off == 0 && parm->type == 0)
1200  {
1201  is_variadic = true;
1202  parm_type = build_ir_node_for_variadic_parameter_type();
1203  }
1204  else
1205  {
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));
1208  }
1209 
1210  if (!parm_type)
1211  continue;
1212 
1214  (new function_decl::parameter(parm_type, parm_name,
1215  location(), is_variadic));
1216  function_parms.push_back(p);
1217  }
1218  result->set_parameters(function_parms);
1219 
1220  cur_tu()->bind_function_type_life_time(result);
1221 
1222  return result;
1223  }
1224 
1225  /// Build an IR node for a function declaration expressed in BTF.
1226  ///
1227  /// @param type_id the ID of a pointer to a BTF "type" which realy
1228  /// describes a function declaration.
1229  ///
1230  /// @return a pointer to a @ref function_decl representing the
1231  /// function declaration expressed by @p t.
1233  build_function_decl(int type_id)
1234  {
1235  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1236  int kind = btf_kind(t);
1237  ABG_ASSERT(kind == BTF_KIND_FUNC);
1238 
1239  function_decl_sptr result;
1240 
1241  string fn_name = btf_offset_to_string(btf_handle(), t->name_off);
1242 
1243  type_base_sptr fn_type = is_type(build_ir_node_from_btf_type(t->type));
1244  if (!fn_type)
1245  return result;
1246 
1247  result.reset(new function_decl(fn_name, fn_type, /*is_inline=*/false,
1248  location(), /*linkage_name=*/fn_name));
1249 
1250  elf_symbol_sptr fn_sym;
1251  if ((fn_sym = function_symbol_is_exported(fn_name))
1252  || (fn_sym = function_symbol_is_undefined(fn_name)))
1253  {
1254  result->set_symbol(fn_sym);
1255  if (fn_sym->is_defined())
1256  result->set_is_in_public_symbol_table(true);
1257  }
1258  return result;
1259  }
1260 
1261  /// Build an IR node for a variable declaration expressed in BTF.
1262  ///
1263  /// @param t a pointer to a BTF "type" describing a variable
1264  /// declaration.
1265  ///
1266  /// @return a pointer to @ref var_decl representing the variable
1267  /// declaration expressed by @p t.
1269  build_variable_decl(int type_id)
1270  {
1271  const btf_type *t = btf__type_by_id(btf_handle(), type_id);
1272  int kind = btf_kind(t);
1273  ABG_ASSERT(kind == BTF_KIND_VAR);
1274 
1275  var_decl_sptr result;
1276 
1277  string var_name = btf_offset_to_string(btf_handle(), t->name_off);
1278 
1279  type_base_sptr var_type = is_type(build_ir_node_from_btf_type(t->type));
1280  if (!var_type)
1281  return result;
1282 
1283  result.reset(new var_decl(var_name, var_type, location(),
1284  /*linkage_name=*/var_name));
1285 
1286  elf_symbol_sptr var_sym;
1287  if ((var_sym = variable_symbol_is_exported(var_name))
1288  || (var_sym = variable_symbol_is_undefined(var_name)))
1289  {
1290  result->set_symbol(var_sym);
1291  if (var_sym->is_defined())
1292  result->set_is_in_public_symbol_table(true);
1293  }
1294  return result;
1295  }
1296 
1297 }; // end class reader.
1298 
1299 /// Create and return a BTF reader (or front-end) which is an instance
1300 /// of @ref btf::reader.
1301 ///
1302 /// @param elf_path the path to the path to the elf file the reader is
1303 /// to be used for.
1304 ///
1305 /// @param debug_info_root_paths a vector to the paths to the
1306 /// directories under which the debug info is to be found for @p
1307 /// elf_path. Pass an empty vector if th debug info is not in a split
1308 /// file.
1309 ///
1310 /// @param environment the environment used by the current context.
1311 /// This environment contains resources needed by the BTF reader and
1312 /// by the types and declarations that are to be created later. Note
1313 /// that ABI artifacts that are to be compared all need to be created
1314 /// within the same environment.
1315 ///
1316 /// Please also note that the life time of this environment object
1317 /// must be greater than the life time of the resulting @ref
1318 /// reader the context uses resources that are allocated in the
1319 /// environment.
1320 ///
1321 /// @param load_all_types if set to false only the types that are
1322 /// reachable from publicly exported declarations (of functions and
1323 /// variables) are read. If set to true then all types found in the
1324 /// debug information are loaded.
1325 ///
1326 /// @param linux_kernel_mode if set to true, then consider the special
1327 /// linux kernel symbol tables when determining if a symbol is
1328 /// exported or not.
1329 ///
1330 /// @return a smart pointer to the resulting btf::reader.
1331 elf_based_reader_sptr
1332 create_reader(const std::string& elf_path,
1333  const vector<string>& debug_info_root_paths,
1334  environment& env,
1335  bool load_all_types,
1336  bool linux_kernel_mode)
1337 {
1338  reader_sptr rdr = reader::create(elf_path, debug_info_root_paths, env,
1339  load_all_types, linux_kernel_mode);
1340  return rdr;
1341 }
1342 
1343 } // end namespace btf
1344 } // end namespace abigail
1345 
1346 #endif //WITH_BTF
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...
Definition: abg-ir.cc:8450
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10807
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:208
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:253
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
Definition: abg-ir.cc:8543
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.
Definition: abg-ir.cc:11396
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:133
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:164
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.
Definition: abg-ir-priv.h:1462
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.
Definition: abg-ir.cc:29165
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.
Definition: abg-ir-priv.h:1524
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:12059
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2798
Toplevel namespace for libabigail.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:266
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10747
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:11100
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3190
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3183
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
Definition: abg-corpus.h:50
This contains the private implementation of the suppression engine of libabigail. ...
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< string > &debug_info_root_paths, environment &env)
Create and return a new read context to process CTF information from a given ELF file.
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.
Definition: abg-ir.cc:10229
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition: abg-fwd.h:118
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:159
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:924
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
Definition: abg-fwd.h:1743
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10695
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition: abg-ir.cc:10858
virtual void initialize(const std::string &elf_path, const vector< string > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:172
void initialize()
The initialization function of libxml2 abstraction layer. This function must be called prior to using...
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4733
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.
Definition: abg-ir.h:2569
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.
Definition: abg-ir.h:2562
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:241
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:223
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2254