libabigail
abg-ctf-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) 2021-2023 Oracle, Inc.
5 //
6 // Author: Jose E. Marchesi
7 
8 /// @file
9 ///
10 /// This file contains the definitions of the entry points to
11 /// de-serialize an instance of @ref abigail::corpus from a file in
12 /// ELF format, containing CTF information.
13 
14 #include "config.h"
15 
16 #include <fcntl.h> /* For open(3) */
17 #include <sstream>
18 #include <iostream>
19 #include <memory>
20 #include <map>
21 #include <algorithm>
22 
23 #include "ctf-api.h"
24 
25 #include "abg-internal.h"
26 #include "abg-ir-priv.h"
27 #include "abg-symtab-reader.h"
28 
29 
30 #include "abg-internal.h"
31 // <headers defining libabigail's API go under here>
32 ABG_BEGIN_EXPORT_DECLARATIONS
33 
34 #include "abg-ctf-reader.h"
35 #include "abg-elf-based-reader.h"
36 #include "abg-corpus.h"
37 #include "abg-tools-utils.h"
38 #include "abg-elf-helpers.h"
39 
40 ABG_END_EXPORT_DECLARATIONS
41 // </headers defining libabigail's API>
42 
43 namespace abigail
44 {
45 /// Namespace of the reader for the CTF debug information
46 namespace ctf
47 {
48 using std::dynamic_pointer_cast;
51 
52 class reader;
53 
54 static typedef_decl_sptr
55 process_ctf_typedef(reader *rdr,
56  ctf_dict_t *ctf_dictionary,
57  ctf_id_t ctf_type);
58 
59 static type_decl_sptr
60 process_ctf_base_type(reader *rdr,
61  ctf_dict_t *ctf_dictionary,
62  ctf_id_t ctf_type);
63 
64 static decl_base_sptr
65 build_ir_node_for_variadic_parameter_type(reader &rdr,
66  const translation_unit_sptr& tunit);
67 
68 static decl_base_sptr
69 build_ir_node_for_void_type(reader& rdr,
70  const translation_unit_sptr& tunit);
71 
73 build_ir_node_for_void_pointer_type(reader& rdr,
74  const translation_unit_sptr& tunit);
75 
76 static function_type_sptr
77 process_ctf_function_type(reader *rdr,
78  ctf_dict_t *ctf_dictionary,
79  ctf_id_t ctf_type);
80 
81 static void
82 process_ctf_sou_members(reader *rdr,
83  ctf_dict_t *ctf_dictionary,
84  ctf_id_t ctf_type,
85  class_or_union_sptr sou);
86 
87 static type_base_sptr
88 process_ctf_forward_type(reader *rdr,
89  ctf_dict_t *ctf_dictionary,
90  ctf_id_t ctf_type);
91 
92 static class_decl_sptr
93 process_ctf_struct_type(reader *rdr,
94  ctf_dict_t *ctf_dictionary,
95  ctf_id_t ctf_type);
96 
97 static union_decl_sptr
98 process_ctf_union_type(reader *rdr,
99  ctf_dict_t *ctf_dictionary,
100  ctf_id_t ctf_type);
101 
102 static array_type_def_sptr
103 process_ctf_array_type(reader *rdr,
104  ctf_dict_t *ctf_dictionary,
105  ctf_id_t ctf_type);
106 
107 static type_base_sptr
108 process_ctf_qualified_type(reader *rdr,
109  ctf_dict_t *ctf_dictionary,
110  ctf_id_t ctf_type);
111 
113 process_ctf_pointer_type(reader *rdr,
114  ctf_dict_t *ctf_dictionary,
115  ctf_id_t ctf_type);
116 
117 static enum_type_decl_sptr
118 process_ctf_enum_type(reader *rdr,
119  ctf_dict_t *ctf_dictionary,
120  ctf_id_t ctf_type);
121 
122 static void
123 fill_ctf_section(const Elf_Scn *elf_section, ctf_sect_t *ctf_section);
124 
125 static ctf_id_t
126 lookup_symbol_in_ctf_archive(ctf_archive_t *ctfa, ctf_dict_t **ctf_dict,
127  const char *sym_name);
128 
129 static std::string
130 dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type);
131 
132 /// The abstraction of a CTF reader.
133 ///
134 /// It groks the type information contains the CTF-specific part of
135 /// the ELF file and builds an ABI corpus out of it.
136 class reader : public elf_based_reader
137 {
138  /// The CTF archive read from FILENAME. If an archive couldn't
139  /// be read from the file then this is NULL.
140  ctf_archive_t *ctfa;
141 
142  /// A map associating CTF type ids with libabigail IR types. This
143  /// is used to reuse already generated types.
145 
146  /// A set associating unknown CTF type ids
147  std::set<ctf_id_t> unknown_types_set;
148 
149  /// Raw contents of several sections from the ELF file. These are
150  /// used by libctf.
151  ctf_sect_t ctf_sect;
152  ctf_sect_t symtab_sect;
153  ctf_sect_t strtab_sect;
154  translation_unit_sptr cur_tu_;
155 
156 public:
157 
158  /// Getter of the exported decls builder object.
159  ///
160  /// @return the exported decls builder.
162  exported_decls_builder()
163  {return corpus()->get_exported_decls_builder().get();}
164 
165  /// Associate a given CTF type ID with a given libabigail IR type.
166  ///
167  /// @param dic the dictionnary the type belongs to.
168  ///
169  /// @param ctf_type the type ID.
170  ///
171  /// @param type the type to associate to the ID.
172  void
173  add_type(ctf_dict_t *dic, ctf_id_t ctf_type, type_base_sptr type)
174  {
175  string key = dic_type_key(dic, ctf_type);
176  types_map.insert(std::make_pair(key, type));
177  }
178 
179  /// Insert a given CTF unknown type ID.
180  ///
181  /// @param ctf_type the unknown type ID to be added.
182  void
183  add_unknown_type(ctf_id_t ctf_type)
184  {
185  unknown_types_set.insert(ctf_type);
186  }
187 
188  /// Lookup a given CTF type ID in the types map.
189  ///
190  /// @param dic the dictionnary the type belongs to.
191  ///
192  /// @param ctf_type the type ID of the type to lookup.
193  type_base_sptr
194  lookup_type(ctf_dict_t *dic, ctf_id_t ctf_type)
195  {
196  type_base_sptr result;
197  std::string key = dic_type_key(dic, ctf_type);
198 
199  auto search = types_map.find(key);
200  if (search != types_map.end())
201  result = search->second;
202 
203  return result;
204  }
205 
206  /// Lookup a given CTF unknown type ID in the unknown set.
207  /// @param ctf_type the unknown type ID to lookup.
208  bool
209  lookup_unknown_type(ctf_id_t ctf_type)
210  { return unknown_types_set.find(ctf_type) != unknown_types_set.end(); }
211 
212  /// Canonicalize all the types stored in the types map.
213  void
214  canonicalize_all_types(void)
215  {
217  (types_map.begin(), types_map.end(),
218  [](const string_type_base_sptr_map_type::const_iterator& i)
219  {return i->second;});
220  }
221 
222  /// Constructor.
223  ///
224  /// @param elf_path the path to the ELF file.
225  ///
226  /// @param debug_info_root_paths vector with the paths
227  /// to directories where .debug file is located.
228  ///
229  /// @param env the environment used by the current context.
230  /// This environment contains resources needed by the reader and by
231  /// the types and declarations that are to be created later. Note
232  /// that ABI artifacts that are to be compared all need to be
233  /// created within the same environment.
234  reader(const string& elf_path,
235  const vector<char**>& debug_info_root_paths,
236  environment& env)
237  : elf_based_reader(elf_path, debug_info_root_paths, env)
238  {
239  initialize();
240  }
241 
242  /// Initializer of the reader.
243  ///
244  /// This is useful to clear out the data used by the reader and get
245  /// it ready to be used again.
246  ///
247  /// Note that the reader eeps the same environment it has been
248  /// originally created with.
249  ///
250  /// Please also note that the life time of this environment object
251  /// must be greater than the life time of the resulting @ref
252  /// reader the context uses resources that are allocated in
253  /// the environment.
254  void
255  initialize()
256  {
257  ctfa = nullptr;
258  types_map.clear();
259  cur_tu_.reset();
260  corpus_group().reset();
261  }
262 
263  /// Initializer of the reader.
264  ///
265  /// @param elf_path the new path to the new ELF file to use.
266  ///
267  /// @param debug_info_root_paths a vector of paths to use to look
268  /// for debug info that is split out into a separate file.
269  ///
270  /// @param load_all_types currently not used.
271  ///
272  /// @param linux_kernel_mode currently not used.
273  ///
274  /// This is useful to clear out the data used by the reader and get
275  /// it ready to be used again.
276  ///
277  /// Note that the reader eeps the same environment it has been
278  /// originally created with.
279  ///
280  /// Please also note that the life time of this environment object
281  /// must be greater than the life time of the resulting @ref
282  /// reader the context uses resources that are allocated in
283  /// the environment.
284  void
285  initialize(const string& elf_path,
286  const vector<char**>& debug_info_root_paths,
287  bool load_all_types = false,
288  bool linux_kernel_mode = false)
289  {
290  load_all_types = load_all_types;
291  linux_kernel_mode = linux_kernel_mode;
292  elf_based_reader::initialize(elf_path, debug_info_root_paths);
293  }
294 
295  /// Setter of the current translation unit.
296  ///
297  /// @param tu the current translation unit being constructed.
298  void
299  cur_transl_unit(translation_unit_sptr tu)
300  {
301  if (tu)
302  cur_tu_ = tu;
303  }
304 
305  /// Getter of the current translation unit.
306  ///
307  /// @return the current translation unit being constructed.
308  const translation_unit_sptr&
309  cur_transl_unit() const
310  {return cur_tu_;}
311 
312  /// Getter of the environment of the current CTF reader.
313  ///
314  /// @return the environment of the current CTF reader.
315  const environment&
316  env() const
317  {return options().env;}
318 
319  /// Getter of the environment of the current CTF reader.
320  ///
321  /// @return the environment of the current CTF reader.
322  environment&
323  env()
324  {return options().env;}
325 
326  /// Look for vmlinux.ctfa file in default directory or in
327  /// directories provided by debug-info-dir command line option,
328  /// it stores location path in @ref ctfa_file.
329  ///
330  /// @param ctfa_file file name found.
331  /// @return true if file is found.
332  bool
333  find_ctfa_file(std::string& ctfa_file)
334  {
335  std::string ctfa_dirname;
336  dir_name(corpus_path(), ctfa_dirname, false);
337 
338  // In corpus group we assume vmlinux as first file to
339  // be processed, so default location for vmlinux.cfa
340  // is vmlinux dirname.
341  ctfa_file = ctfa_dirname + "/vmlinux.ctfa";
342  if (file_exists(ctfa_file))
343  return true;
344 
345  // If it's proccessing a module, then location directory
346  // for vmlinux.ctfa should be provided with --debug-info-dir
347  // option.
348  for (const auto& path : debug_info_root_paths())
349  if (tools_utils::find_file_under_dir(*path, "vmlinux.ctfa", ctfa_file))
350  return true;
351 
352  return false;
353  }
354 
355  /// Slurp certain information from the underlying ELF file, and
356  /// install it the current libabigail corpus associated to the
357  /// current CTF reader.
358  ///
359  /// @param status the resulting status flags.
360  void
361  slurp_elf_info(fe_iface::status& status)
362  {
363  // Read the ELF-specific parts of the corpus.
364  elf::reader::read_corpus(status);
365 
366  corpus_sptr corp = corpus();
367  if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
368  && corpus_group())
369  {
370  // Not finding any debug info so far is expected if we are
371  // building a kABI.
372  status &= static_cast<abigail::fe_iface::status>
373  (~STATUS_DEBUG_INFO_NOT_FOUND);
374  return;
375  }
376 
377  if ((status & STATUS_NO_SYMBOLS_FOUND)
378  || !(status & STATUS_OK))
379  // Either we couldn't find ELF symbols or something went badly
380  // wrong. There is nothing we can do with this ELF file. Bail
381  // out.
382  return;
383 
384  GElf_Ehdr *ehdr, eh_mem;
385  if (!(ehdr = gelf_getehdr(elf_handle(), &eh_mem)))
386  return;
387 
388  // ET_{EXEC,DYN} needs .dyn{sym,str} in ctf_arc_bufopen
389  const char *symtab_name = ".dynsym";
390  const char *strtab_name = ".dynstr";
391 
392  if (ehdr->e_type == ET_REL)
393  {
394  symtab_name = ".symtab";
395  strtab_name = ".strtab";
396  }
397 
398  const Elf_Scn* ctf_scn = find_ctf_section();
399  fill_ctf_section(ctf_scn, &ctf_sect);
400 
401  const Elf_Scn* symtab_scn =
402  elf_helpers::find_section_by_name(elf_handle(), symtab_name);
403  fill_ctf_section(symtab_scn, &symtab_sect);
404 
405  const Elf_Scn* strtab_scn =
406  elf_helpers::find_section_by_name(elf_handle(), strtab_name);
407  fill_ctf_section(strtab_scn, &strtab_sect);
408 
409  status |= fe_iface::STATUS_OK;
410  }
411 
412  /// Process a CTF archive and create libabigail IR for the types,
413  /// variables and function declarations found in the archive, iterating
414  /// over public symbols. The IR is added to the given corpus.
415  void
416  process_ctf_archive()
417  {
418  corpus_sptr corp = corpus();
419  /* We only have a translation unit. */
420  translation_unit_sptr ir_translation_unit =
421  std::make_shared<translation_unit>(env(), "", 64);
422  ir_translation_unit->set_language(translation_unit::LANG_C);
423  corp->add(ir_translation_unit);
424  cur_transl_unit(ir_translation_unit);
425 
426  int ctf_err;
427  ctf_dict_t *ctf_dict, *dict_tmp;
428  const auto symt = symtab();
429  symtab_reader::symtab_filter filter = symt->make_filter();
430  filter.set_public_symbols();
431  std::string dict_name;
432 
433  if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
434  && corpus_group())
435  {
436  tools_utils::base_name(corpus_path(), dict_name);
437  // remove .* suffix
438  std::size_t pos = dict_name.find(".");
439  if (pos != string::npos)
440  dict_name.erase(pos);
441 
442  std::replace(dict_name.begin(), dict_name.end(), '-', '_');
443  }
444 
445  if ((ctf_dict = ctf_dict_open(ctfa,
446  dict_name.empty() ? NULL : dict_name.c_str(),
447  &ctf_err)) == NULL)
448  {
449  fprintf(stderr, "ERROR dictionary not found\n");
450  abort();
451  }
452 
453  dict_tmp = ctf_dict;
454 
455  for (const auto& symbol : symtab_reader::filtered_symtab(*symt, filter))
456  {
457  std::string sym_name = symbol->get_name();
458  ctf_id_t ctf_sym_type;
459 
460  ctf_sym_type = lookup_symbol_in_ctf_archive(ctfa, &ctf_dict,
461  sym_name.c_str());
462  if (ctf_sym_type == CTF_ERR)
463  continue;
464 
465  if (ctf_type_kind(ctf_dict, ctf_sym_type) != CTF_K_FUNCTION)
466  {
467  const char *var_name = sym_name.c_str();
468  type_base_sptr var_type = build_type(ctf_dict, ctf_sym_type);
469  if (!var_type)
470  /* Ignore variable if its type can't be sorted out. */
471  continue;
472 
473  var_decl_sptr var_declaration;
474  var_declaration.reset(new var_decl(var_name,
475  var_type,
476  location(),
477  var_name));
478 
479  var_declaration->set_symbol(symbol);
480  add_decl_to_scope(var_declaration,
481  ir_translation_unit->get_global_scope());
482  var_declaration->set_is_in_public_symbol_table(true);
483  add_var_to_exported_or_undefined_decls(var_declaration.get());
484  }
485  else
486  {
487  const char *func_name = sym_name.c_str();
488  ctf_id_t ctf_sym = ctf_sym_type;
489  type_base_sptr func_type = build_type(ctf_dict, ctf_sym);
490  if (!func_type)
491  /* Ignore function if its type can't be sorted out. */
492  continue;
493 
494  function_decl_sptr func_declaration;
495  func_declaration.reset(new function_decl(func_name,
496  func_type,
497  0 /* is_inline */,
498  location()));
499  func_declaration->set_symbol(symbol);
500  add_decl_to_scope(func_declaration,
501  ir_translation_unit->get_global_scope());
502  func_declaration->set_is_in_public_symbol_table(true);
503  add_fn_to_exported_or_undefined_decls(func_declaration.get());
504  }
505 
506  ctf_dict = dict_tmp;
507  }
508 
509  ctf_dict_close(ctf_dict);
510  /* Canonicalize all the types generated above. This must be
511  done "a posteriori" because the processing of types may
512  require other related types to not be already
513  canonicalized. */
514  canonicalize_all_types();
515  corpus()->sort_functions();
516  corpus()->sort_variables();
517  }
518 
519  /// Add a new type declaration to the given libabigail IR corpus CORP.
520  ///
521  /// @param ctf_dictionary the CTF dictionary being read.
522  /// @param ctf_type the CTF type ID of the source type.
523  ///
524  /// Note that if @ref ctf_type can't reliably be translated to the IR
525  /// then it is simply ignored.
526  ///
527  /// @return a shared pointer to the IR node for the type.
528  type_base_sptr
529  process_ctf_type(ctf_dict_t *ctf_dictionary,
530  ctf_id_t ctf_type)
531  {
532  corpus_sptr corp = corpus();
533  translation_unit_sptr tunit = cur_transl_unit();
534  int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
535  type_base_sptr result;
536 
537  if (lookup_unknown_type(ctf_type))
538  return nullptr;
539 
540  if ((result = lookup_type(ctf_dictionary, ctf_type)))
541  return result;
542 
543  switch (type_kind)
544  {
545  case CTF_K_INTEGER:
546  case CTF_K_FLOAT:
547  {
549  = process_ctf_base_type(this, ctf_dictionary, ctf_type);
550  result = is_type(type_decl);
551  break;
552  }
553  case CTF_K_TYPEDEF:
554  {
556  = process_ctf_typedef(this, ctf_dictionary, ctf_type);
557  result = is_type(typedef_decl);
558  break;
559  }
560  case CTF_K_POINTER:
561  {
562  pointer_type_def_sptr pointer_type
563  = process_ctf_pointer_type(this, ctf_dictionary, ctf_type);
564  result = pointer_type;
565  break;
566  }
567  case CTF_K_CONST:
568  case CTF_K_VOLATILE:
569  case CTF_K_RESTRICT:
570  {
571  type_base_sptr qualified_type
572  = process_ctf_qualified_type(this, ctf_dictionary, ctf_type);
573  result = qualified_type;
574  break;
575  }
576  case CTF_K_ARRAY:
577  {
578  array_type_def_sptr array_type
579  = process_ctf_array_type(this, ctf_dictionary, ctf_type);
580  result = array_type;
581  break;
582  }
583  case CTF_K_ENUM:
584  {
585  enum_type_decl_sptr enum_type
586  = process_ctf_enum_type(this, ctf_dictionary, ctf_type);
587  result = enum_type;
588  break;
589  }
590  case CTF_K_FUNCTION:
591  {
593  = process_ctf_function_type(this, ctf_dictionary, ctf_type);
594  result = function_type;
595  break;
596  }
597  case CTF_K_STRUCT:
598  {
599  class_decl_sptr struct_decl
600  = process_ctf_struct_type(this, ctf_dictionary, ctf_type);
601  result = is_type(struct_decl);
602  break;
603  }
604  case CTF_K_FORWARD:
605  result = process_ctf_forward_type(this, ctf_dictionary, ctf_type);
606  break;
607  case CTF_K_UNION:
608  {
609  union_decl_sptr union_decl
610  = process_ctf_union_type(this, ctf_dictionary, ctf_type);
611  result = is_type(union_decl);
612  break;
613  }
614  case CTF_K_UNKNOWN:
615  /* Unknown types are simply ignored. */
616  default:
617  break;
618  }
619 
620  if (!result)
621  {
622  fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type);
623  add_unknown_type(ctf_type);
624  }
625 
626  return result;
627  }
628 
629  /// Given a CTF type id, build the corresponding libabigail IR type.
630  /// If the IR type has been generated it returns the corresponding
631  /// type.
632  ///
633  /// @param ctf_dictionary the CTF dictionary being read.
634  /// @param ctf_type the CTF type ID of the looked type.
635  ///
636  /// Note that if @ref ctf_type can't reliably be translated to the IR
637  /// then a NULL shared pointer is returned.
638  ///
639  /// @return a shared pointer to the IR node for the type.
640  type_base_sptr
641  build_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type)
642  {
643  type_base_sptr result = lookup_type(ctf_dictionary, ctf_type);
644 
645  if (!result)
646  result = process_ctf_type(ctf_dictionary, ctf_type);
647  return result;
648  }
649 
650  /// Read the CTF information in the binary and construct an ABI
651  /// corpus from it.
652  ///
653  /// @param status output parameter. Contains the status of the ABI
654  /// corpus construction.
655  ///
656  /// @return the corpus created as a result of processing the debug
657  /// information.
658  corpus_sptr
659  read_corpus(fe_iface::status &status)
660  {
661  corpus_sptr corp = corpus();
662  status = fe_iface::STATUS_UNKNOWN;
663 
664  corpus::origin origin = corpus()->get_origin();
665  origin |= corpus::CTF_ORIGIN;
666  corp->set_origin(origin);
667 
668  slurp_elf_info(status);
670  return corpus_sptr();
671 
672  if (!(origin & corpus::LINUX_KERNEL_BINARY_ORIGIN)
674  return corp;
675 
676  int errp;
677  if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
678  && corpus_group())
679  {
680  if (ctfa == NULL)
681  {
682  std::string ctfa_filename;
683  if (find_ctfa_file(ctfa_filename))
684  ctfa = ctf_arc_open(ctfa_filename.c_str(), &errp);
685  }
686  }
687  else
688  /* Build the ctfa from the contents of the relevant ELF sections,
689  and process the CTF archive in the read context, if any.
690  Information about the types, variables, functions, etc contained
691  in the archive are added to the given corpus. */
692  ctfa = ctf_arc_bufopen(&ctf_sect, &symtab_sect,
693  &strtab_sect, &errp);
694 
695  env().canonicalization_is_done(false);
696  if (ctfa == NULL)
698  else
699  {
700  process_ctf_archive();
701  corpus()->sort_functions();
702  corpus()->sort_variables();
703  }
704 
705  env().canonicalization_is_done(true);
706 
707  return corp;
708  }
709 
710  /// Destructor of the CTF reader.
711  ~reader()
712  {
713  ctf_close(ctfa);
714  }
715 }; // end class reader.
716 
717 typedef shared_ptr<reader> reader_sptr;
718 
719 /// Build and return a typedef libabigail IR.
720 ///
721 /// @param rdr the read context.
722 /// @param ctf_dictionary the CTF dictionary being read.
723 /// @param ctf_type the CTF type ID of the source type.
724 ///
725 /// @return a shared pointer to the IR node for the typedef.
726 
727 static typedef_decl_sptr
728 process_ctf_typedef(reader *rdr,
729  ctf_dict_t *ctf_dictionary,
730  ctf_id_t ctf_type)
731 {
732  corpus_sptr corp = rdr->corpus();
733  translation_unit_sptr tunit = rdr->cur_transl_unit();
734  typedef_decl_sptr result;
735 
736  ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type);
737  if (ctf_utype == CTF_ERR)
738  return result;
739 
740  const char *typedef_name = ctf_type_name_raw(ctf_dictionary, ctf_type);
741  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
742  if ((result = lookup_typedef_type(typedef_name, *corp)))
743  return result;
744 
745  type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype);
746 
747  if (!utype)
748  return result;
749 
750  result = dynamic_pointer_cast<typedef_decl>
751  (rdr->lookup_type(ctf_dictionary, ctf_type));
752  if (result)
753  return result;
754 
755  result.reset(new typedef_decl(typedef_name, utype, location(),
756  typedef_name /* mangled_name */));
757 
758  /* If this typedef "names" an anonymous type, reflect this fact in
759  the underlying type. In C enum, struct and union types can be
760  anonymous. */
761  if (is_anonymous_type(utype)
762  && (is_enum_type(utype) || is_class_or_union_type(utype)))
763  {
764  decl_base_sptr decl = is_decl(utype);
765  ABG_ASSERT(decl);
766  decl->set_naming_typedef(result);
767  }
768 
769  if (result)
770  {
771  add_decl_to_scope(result, tunit->get_global_scope());
772  rdr->add_type(ctf_dictionary, ctf_type, result);
773  }
774 
775  return result;
776 }
777 
778 /// Build and return an integer or float type declaration libabigail
779 /// IR.
780 ///
781 /// @param rdr the read context.
782 /// @param ctf_dictionary the CTF dictionary being read.
783 /// @param ctf_type the CTF type ID of the source type.
784 ///
785 /// @return a shared pointer to the IR node for the type.
786 
787 static type_decl_sptr
788 process_ctf_base_type(reader *rdr,
789  ctf_dict_t *ctf_dictionary,
790  ctf_id_t ctf_type)
791 {
792  corpus_sptr corp = rdr->corpus();
793  translation_unit_sptr tunit = rdr->cur_transl_unit();
794  type_decl_sptr result;
795 
796  ctf_id_t ctf_ref = ctf_type_reference(ctf_dictionary, ctf_type);
797  const char *type_name = ctf_type_name_raw(ctf_dictionary,
798  (ctf_ref != CTF_ERR) ? ctf_ref : ctf_type);
799 
800  /* Get the type encoding and extract some useful properties of
801  the type from it. In case of any error, just ignore the
802  type. */
803  ctf_encoding_t type_encoding;
804  if (ctf_type_encoding(ctf_dictionary,
805  (ctf_ref != CTF_ERR) ? ctf_ref : ctf_type,
806  &type_encoding))
807  return result;
808 
809  /* Create the IR type corresponding to the CTF type. */
810  if (type_encoding.cte_bits == 0
811  && type_encoding.cte_format == CTF_INT_SIGNED)
812  {
813  /* This is the `void' type. */
814  decl_base_sptr type_declaration = build_ir_node_for_void_type(*rdr,
815  tunit);
816  type_base_sptr void_type = is_type(type_declaration);
817  result = is_type_decl(type_declaration);
818  canonicalize(result);
819  }
820  else
821  {
822  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
823  {
824  string normalized_type_name = type_name;
825  integral_type int_type;
826  if (parse_integral_type(type_name, int_type))
827  normalized_type_name = int_type.to_string();
828  if ((result = lookup_basic_type(normalized_type_name, *corp)))
829  return result;
830  }
831 
832  result = lookup_basic_type(type_name, *corp);
833  if (!result)
834  result.reset(new type_decl(rdr->env(),
835  type_name,
836  type_encoding.cte_bits,
837  /*alignment=*/0,
838  location(),
839  type_name /* mangled_name */));
840 
841  }
842 
843  if (result)
844  {
845  add_decl_to_scope(result, tunit->get_global_scope());
846  rdr->add_type(ctf_dictionary, ctf_type, result);
847  }
848 
849  return result;
850 }
851 
852 /// Build the IR node for a variadic parameter type.
853 ///
854 /// @param rdr the read context to use.
855 ///
856 /// @param tunit the translation unit it should belong to.
857 ///
858 /// @return the variadic parameter type.
859 static decl_base_sptr
860 build_ir_node_for_variadic_parameter_type(reader &rdr,
861  const translation_unit_sptr& tunit)
862 {
863 
864  const ir::environment& env = rdr.env();
865  type_base_sptr t = env.get_variadic_parameter_type();
866  decl_base_sptr type_declaration = get_type_declaration(t);
867  add_decl_to_scope(type_declaration, tunit->get_global_scope());
868  canonicalize(t);
869  return type_declaration;
870 }
871 
872 /// Build the IR node for a void type.
873 ///
874 /// Note that this returns the unique pointer
875 /// environment::get_void_type(), which is added to the current
876 /// translation unit if it's the first it's being used.
877 ///
878 /// @param rdr the read context to use.
879 ///
880 /// @param tunit the translation unit it should belong to.
881 ///
882 /// @return the void type type.
883 static decl_base_sptr
884 build_ir_node_for_void_type(reader& rdr, const translation_unit_sptr& tunit)
885 {
886  const environment& env = rdr.env();
887  type_base_sptr t = env.get_void_type();
888  add_decl_to_scope(is_decl(t), tunit->get_global_scope());
889  canonicalize(t);
890  return is_decl(t);
891 }
892 
893 /// Build the IR node for a void pointer type.
894 ///
895 /// Note that this returns the unique pointer
896 /// environment::get_void_pointer_type(), which is added to the
897 /// current translation unit if it's the first it's being used.
898 ///
899 /// @param rdr the read context to use.
900 ///
901 /// @param tunit the translation unit it should belong to.
902 ///
903 /// @return the void pointer type.
905 build_ir_node_for_void_pointer_type(reader& rdr,
906  const translation_unit_sptr& tunit)
907 {
908  const environment& env = rdr.env();
909  type_base_sptr t = env.get_void_pointer_type();
910  add_decl_to_scope(is_decl(t), tunit->get_global_scope());
911  canonicalize(t);
912  return is_decl(t);
913 }
914 
915 /// Build and return a function type libabigail IR.
916 ///
917 /// @param rdr the read context.
918 /// @param ctf_dictionary the CTF dictionary being read.
919 /// @param ctf_type the CTF type ID of the source type.
920 ///
921 /// @return a shared pointer to the IR node for the function type.
922 
923 static function_type_sptr
924 process_ctf_function_type(reader *rdr,
925  ctf_dict_t *ctf_dictionary,
926  ctf_id_t ctf_type)
927 {
928  corpus_sptr corp = rdr->corpus();
929  translation_unit_sptr tunit = rdr->cur_transl_unit();
930  function_type_sptr result;
931 
932  /* Fetch the function type info from the CTF type. */
933  ctf_funcinfo_t funcinfo;
934  ctf_func_type_info(ctf_dictionary, ctf_type, &funcinfo);
935  int vararg_p = funcinfo.ctc_flags & CTF_FUNC_VARARG;
936 
937  /* Take care first of the result type. */
938  ctf_id_t ctf_ret_type = funcinfo.ctc_return;
939  type_base_sptr ret_type = rdr->build_type(ctf_dictionary, ctf_ret_type);
940  if (!ret_type)
941  return result;
942 
943  /* Now process the argument types. */
944  int argc = funcinfo.ctc_argc;
945  std::vector<ctf_id_t> argv(argc);
946  if (static_cast<ctf_id_t>(ctf_func_type_args(ctf_dictionary, ctf_type,
947  argc, argv.data())) == CTF_ERR)
948  return result;
949 
950  function_decl::parameters function_parms;
951  for (int i = 0; i < argc; i++)
952  {
953  ctf_id_t ctf_arg_type = argv[i];
954  type_base_sptr arg_type = rdr->build_type(ctf_dictionary, ctf_arg_type);
955  if (!arg_type)
956  return result;
957 
959  (new function_decl::parameter(arg_type, "",
960  location(),
961  false,
962  false /* is_artificial */));
963  function_parms.push_back(parm);
964  }
965 
966  if (vararg_p)
967  {
968  type_base_sptr arg_type =
969  is_type(build_ir_node_for_variadic_parameter_type(*rdr, tunit));
970 
972  (new function_decl::parameter(arg_type, "",
973  location(),
974  true,
975  false /* is_artificial */));
976  function_parms.push_back(parm);
977  }
978 
979  result = dynamic_pointer_cast<function_type>
980  (rdr->lookup_type(ctf_dictionary, ctf_type));
981  if (result)
982  return result;
983 
984  /* Ok now the function type itself. */
985  result.reset(new function_type(ret_type,
986  function_parms,
987  tunit->get_address_size(),
988  /*alignment=*/0));
989 
990  if (result)
991  {
992  tunit->bind_function_type_life_time(result);
993  result->set_is_artificial(true);
994  decl_base_sptr function_type_decl = get_type_declaration(result);
995  add_decl_to_scope(function_type_decl, tunit->get_global_scope());
996  rdr->add_type(ctf_dictionary, ctf_type, result);
997  }
998 
999  return result;
1000 }
1001 
1002 /// Add member information to a IR struct or union type.
1003 ///
1004 /// @param rdr the read context.
1005 /// @param ctf_dictionary the CTF dictionary being read.
1006 /// @param ctf_type the CTF type ID of the source type.
1007 /// @param sou the IR struct or union type to which add the members.
1008 
1009 static void
1010 process_ctf_sou_members(reader *rdr,
1011  ctf_dict_t *ctf_dictionary,
1012  ctf_id_t ctf_type,
1013  class_or_union_sptr sou)
1014 {
1015  corpus_sptr corp = rdr->corpus();
1016  translation_unit_sptr tunit = rdr->cur_transl_unit();
1017  ssize_t member_size;
1018  ctf_next_t *member_next = NULL;
1019  const char *member_name = NULL;
1020  ctf_id_t member_ctf_type;
1021 
1022  while ((member_size = ctf_member_next(ctf_dictionary, ctf_type,
1023  &member_next, &member_name,
1024  &member_ctf_type,
1025  0 /* flags */)) >= 0)
1026  {
1027  ctf_membinfo_t membinfo;
1028 
1029  if (static_cast<ctf_id_t>(ctf_member_info(ctf_dictionary,
1030  ctf_type,
1031  member_name,
1032  &membinfo)) == CTF_ERR)
1033  return;
1034 
1035  /* Build the IR for the member's type. */
1036  type_base_sptr member_type = rdr->build_type(ctf_dictionary,
1037  member_ctf_type);
1038  if (!member_type)
1039  /* Ignore this member. */
1040  continue;
1041 
1042  /* Create a declaration IR node for the member and add it to the
1043  struct type. */
1044  var_decl_sptr data_member_decl(new var_decl(member_name,
1045  member_type,
1046  location(),
1047  member_name));
1048  sou->add_data_member(data_member_decl,
1049  public_access,
1050  true /* is_laid_out */,
1051  false /* is_static */,
1052  membinfo.ctm_offset);
1053  }
1054  if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
1055  fprintf(stderr, "ERROR from ctf_member_next\n");
1056 }
1057 
1058 /// Create a declaration-only union or struct type and add it to the
1059 /// IR.
1060 ///
1061 /// @param rdr the read context.
1062 /// @param ctf_dictionary the CTF dictionary being read.
1063 /// @param ctf_type the CTF type ID of the source type.
1064 /// @return the resulting IR node created.
1065 
1066 static type_base_sptr
1067 process_ctf_forward_type(reader *rdr,
1068  ctf_dict_t *ctf_dictionary,
1069  ctf_id_t ctf_type)
1070 {
1071  translation_unit_sptr tunit = rdr->cur_transl_unit();
1072  decl_base_sptr result;
1073  std::string type_name = ctf_type_name_raw(ctf_dictionary,
1074  ctf_type);
1075  bool type_is_anonymous = (type_name == "");
1076  uint32_t kind = ctf_type_kind_forwarded (ctf_dictionary, ctf_type);
1077 
1078  if (kind == CTF_K_UNION)
1079  {
1080  union_decl_sptr
1081  union_fwd(new union_decl(rdr->env(),
1082  type_name,
1083  /*alignment=*/0,
1084  location(),
1085  decl_base::VISIBILITY_DEFAULT,
1086  type_is_anonymous));
1087  union_fwd->set_is_declaration_only(true);
1088  result = union_fwd;
1089  }
1090  else
1091  {
1092  if (!type_is_anonymous)
1093  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1094  if ((result = lookup_class_type(type_name, *corp)))
1095  return is_type(result);
1096 
1098  struct_fwd(new class_decl(rdr->env(), type_name,
1099  /*alignment=*/0, /*size=*/0,
1100  true /* is_struct */,
1101  location(),
1102  decl_base::VISIBILITY_DEFAULT,
1103  type_is_anonymous));
1104  struct_fwd->set_is_declaration_only(true);
1105  result = struct_fwd;
1106  }
1107 
1108  if (!result)
1109  return is_type(result);
1110 
1111  add_decl_to_scope(result, tunit->get_global_scope());
1112  rdr->add_type(ctf_dictionary, ctf_type, is_type(result));
1113 
1114  return is_type(result);
1115 }
1116 
1117 /// Build and return a struct type libabigail IR.
1118 ///
1119 /// @param rdr the read context.
1120 /// @param ctf_dictionary the CTF dictionary being read.
1121 /// @param ctf_type the CTF type ID of the source type.
1122 ///
1123 /// @return a shared pointer to the IR node for the struct type.
1124 
1125 static class_decl_sptr
1126 process_ctf_struct_type(reader *rdr,
1127  ctf_dict_t *ctf_dictionary,
1128  ctf_id_t ctf_type)
1129 {
1130  corpus_sptr corp = rdr->corpus();
1131  translation_unit_sptr tunit = rdr->cur_transl_unit();
1132  class_decl_sptr result;
1133  std::string struct_type_name = ctf_type_name_raw(ctf_dictionary,
1134  ctf_type);
1135  bool struct_type_is_anonymous = (struct_type_name == "");
1136 
1137  if (!struct_type_is_anonymous)
1138  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1139  if ((result = lookup_class_type(struct_type_name, *corp)))
1140  return result;
1141 
1142  /* The libabigail IR encodes C struct types in `class' IR nodes. */
1143  result.reset(new class_decl(rdr->env(),
1144  struct_type_name,
1145  ctf_type_size(ctf_dictionary, ctf_type) * 8,
1146  /*alignment=*/0,
1147  true /* is_struct */,
1148  location(),
1149  decl_base::VISIBILITY_DEFAULT,
1150  struct_type_is_anonymous));
1151  if (!result)
1152  return result;
1153 
1154  /* The C type system indirectly supports loops by the mean of
1155  pointers to structs or unions. Since some contained type can
1156  refer to this struct, we have to make it available in the cache
1157  at this point even if the members haven't been added to the IR
1158  node yet. */
1159  add_decl_to_scope(result, tunit->get_global_scope());
1160  rdr->add_type(ctf_dictionary, ctf_type, result);
1161 
1162  /* Now add the struct members as specified in the CTF type description.
1163  This is C, so named types can only be defined in the global
1164  scope. */
1165  process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result);
1166 
1167  return result;
1168 }
1169 
1170 /// Build and return an union type libabigail IR.
1171 ///
1172 /// @param rdr the read context.
1173 /// @param ctf_dictionary the CTF dictionary being read.
1174 /// @param ctf_type the CTF type ID of the source type.
1175 ///
1176 /// @return a shared pointer to the IR node for the union type.
1177 
1178 static union_decl_sptr
1179 process_ctf_union_type(reader *rdr,
1180  ctf_dict_t *ctf_dictionary,
1181  ctf_id_t ctf_type)
1182 {
1183  corpus_sptr corp = rdr->corpus();
1184  translation_unit_sptr tunit = rdr->cur_transl_unit();
1185  union_decl_sptr result;
1186  std::string union_type_name = ctf_type_name_raw(ctf_dictionary,
1187  ctf_type);
1188  bool union_type_is_anonymous = (union_type_name == "");
1189 
1190  if (!union_type_is_anonymous)
1191  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1192  if ((result = lookup_union_type(union_type_name, *corp)))
1193  return result;
1194 
1195  /* Create the corresponding libabigail union IR node. */
1196  result.reset(new union_decl(rdr->env(),
1197  union_type_name,
1198  ctf_type_size(ctf_dictionary, ctf_type) * 8,
1199  location(),
1200  decl_base::VISIBILITY_DEFAULT,
1201  union_type_is_anonymous));
1202  if (!result)
1203  return result;
1204 
1205  /* The C type system indirectly supports loops by the mean of
1206  pointers to structs or unions. Since some contained type can
1207  refer to this union, we have to make it available in the cache
1208  at this point even if the members haven't been added to the IR
1209  node yet. */
1210  add_decl_to_scope(result, tunit->get_global_scope());
1211  rdr->add_type(ctf_dictionary, ctf_type, result);
1212 
1213  /* Now add the union members as specified in the CTF type description.
1214  This is C, so named types can only be defined in the global
1215  scope. */
1216  process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result);
1217 
1218  return result;
1219 }
1220 
1221 /// Build and return an array subrange.
1222 ///
1223 /// @param rdr the read context.
1224 ///
1225 /// @param ctf_dictionary the CTF dictionary where @ref index
1226 /// will be found.
1227 ///
1228 /// @param index the CTF type ID for the array index.
1229 ///
1230 /// @param nelems the elements number of the array.
1231 ///
1232 /// @return a shared pointer to subrange built.
1234 build_array_ctf_range(reader *rdr, ctf_dict_t *dic,
1235  ctf_id_t index, uint64_t nelems)
1236 {
1237  bool is_non_finite = false;
1238  corpus_sptr corp = rdr->corpus();
1239  translation_unit_sptr tunit = rdr->cur_transl_unit();
1241  array_type_def::subrange_type::bound_value lower_bound;
1242  array_type_def::subrange_type::bound_value upper_bound;
1243 
1244  type_base_sptr index_type = rdr->build_type(dic, index);
1245  if (!index_type)
1246  return nullptr;
1247 
1248  lower_bound.set_unsigned(0); /* CTF supports C only. */
1249  upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U);
1250 
1251  /* for VLAs number of array elements is 0 */
1252  if (upper_bound.get_unsigned_value() == 0 && nelems == 0)
1253  is_non_finite = true;
1254 
1255  subrange.reset(new array_type_def::subrange_type(rdr->env(),
1256  "",
1257  lower_bound,
1258  upper_bound,
1259  index_type,
1260  location(),
1261  translation_unit::LANG_C));
1262  if (!subrange)
1263  return nullptr;
1264 
1265  subrange->is_non_finite(is_non_finite);
1266  add_decl_to_scope(subrange, tunit->get_global_scope());
1267  canonicalize(subrange);
1268 
1269  return subrange;
1270 }
1271 
1272 /// Build and return an array type libabigail IR.
1273 ///
1274 /// @param rdr the read context.
1275 ///
1276 /// @param ctf_dictionary the CTF dictionary being read.
1277 ///
1278 /// @param ctf_type the CTF type ID of the source type.
1279 ///
1280 /// @return a shared pointer to the IR node for the array type.
1281 static array_type_def_sptr
1282 process_ctf_array_type(reader *rdr,
1283  ctf_dict_t *ctf_dictionary,
1284  ctf_id_t ctf_type)
1285 {
1286  corpus_sptr corp = rdr->corpus();
1287  translation_unit_sptr tunit = rdr->cur_transl_unit();
1288  array_type_def_sptr result;
1289  ctf_arinfo_t ctf_ainfo;
1290 
1291  /* First, get the information about the CTF array. */
1292  if (static_cast<ctf_id_t>(ctf_array_info(ctf_dictionary,
1293  ctf_type,
1294  &ctf_ainfo)) == CTF_ERR)
1295  return result;
1296 
1297  ctf_id_t ctf_element_type = ctf_ainfo.ctr_contents;
1298  ctf_id_t ctf_index_type = ctf_ainfo.ctr_index;
1299  uint64_t nelems = ctf_ainfo.ctr_nelems;
1302 
1303  int type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type);
1304  while (type_array_kind == CTF_K_ARRAY)
1305  {
1306  if (static_cast<ctf_id_t>(ctf_array_info(ctf_dictionary,
1307  ctf_element_type,
1308  &ctf_ainfo)) == CTF_ERR)
1309  return result;
1310 
1311  subrange = build_array_ctf_range(rdr, ctf_dictionary,
1312  ctf_ainfo.ctr_index,
1313  ctf_ainfo.ctr_nelems);
1314  subranges.push_back(subrange);
1315  ctf_element_type = ctf_ainfo.ctr_contents;
1316  type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type);
1317  }
1318 
1319  std::reverse(subranges.begin(), subranges.end());
1320 
1321  /* Make sure the element type is generated. */
1322  type_base_sptr element_type = rdr->build_type(ctf_dictionary,
1323  ctf_element_type);
1324  if (!element_type)
1325  return result;
1326 
1327  /* Ditto for the index type. */
1328  type_base_sptr index_type = rdr->build_type(ctf_dictionary,
1329  ctf_index_type);
1330  if (!index_type)
1331  return result;
1332 
1333  result = dynamic_pointer_cast<array_type_def>
1334  (rdr->lookup_type(ctf_dictionary, ctf_type));
1335  if (result)
1336  return result;
1337 
1338  subrange = build_array_ctf_range(rdr, ctf_dictionary,
1339  ctf_index_type, nelems);
1340  subranges.push_back(subrange);
1341 
1342  /* Finally build the IR for the array type and return it. */
1343  result.reset(new array_type_def(element_type, subranges, location()));
1344  if (result)
1345  {
1346  decl_base_sptr array_type_decl = get_type_declaration(result);
1347  add_decl_to_scope(array_type_decl, tunit->get_global_scope());
1348  rdr->add_type(ctf_dictionary, ctf_type, result);
1349  }
1350 
1351  return result;
1352 }
1353 
1354 /// Strip qualification from a qualified type, when it makes sense.
1355 ///
1356 /// The C language specification says in [6.7.3]/8:
1357 ///
1358 /// [If the specification of an array type includes any type
1359 /// qualifiers, the element type is so- qualified, not the
1360 /// array type.]
1361 ///
1362 /// In more mundane words, a const array of int is the same as an
1363 /// array of const int.
1364 ///
1365 /// This function thus removes the qualifiers of the array and applies
1366 /// them to the array element. The function then pretends that the
1367 /// array itself it not qualified.
1368 ///
1369 /// It might contain code to strip other cases like this in the
1370 /// future.
1371 ///
1372 /// @param t the type to strip const qualification from.
1373 ///
1374 /// @return the stripped type or just return @p t.
1375 static decl_base_sptr
1376 maybe_strip_qualification(const qualified_type_def_sptr t)
1377 {
1378  if (!t)
1379  return t;
1380 
1381  decl_base_sptr result = t;
1382  type_base_sptr u = t->get_underlying_type();
1383 
1384  if (is_array_type(u))
1385  {
1386  // Let's apply the qualifiers of the array to the array element
1387  // and pretend that the array itself is not qualified, as per
1388  // section [6.7.3]/8 of the C specification.
1389 
1391  ABG_ASSERT(array);
1392  // We should not be editing types that are already canonicalized.
1393  ABG_ASSERT(!array->get_canonical_type());
1394  type_base_sptr element_type = array->get_element_type();
1395 
1396  if (qualified_type_def_sptr qualified = is_qualified_type(element_type))
1397  {
1398  qualified_type_def::CV quals = qualified->get_cv_quals();
1399  quals |= t->get_cv_quals();
1400  // So we apply the qualifiers of the array to the array
1401  // element.
1402  qualified->set_cv_quals(quals);
1403  // Let's pretend that the array is no more qualified.
1404  result = is_decl(u);
1405  }
1406  }
1407 
1408  return result;
1409 }
1410 
1411 /// Build and return a qualified type libabigail IR.
1412 ///
1413 /// @param rdr the read context.
1414 /// @param ctf_dictionary the CTF dictionary being read.
1415 /// @param ctf_type the CTF type ID of the source type.
1416 
1417 static type_base_sptr
1418 process_ctf_qualified_type(reader *rdr,
1419  ctf_dict_t *ctf_dictionary,
1420  ctf_id_t ctf_type)
1421 {
1422  corpus_sptr corp = rdr->corpus();
1423  translation_unit_sptr tunit = rdr->cur_transl_unit();
1424  type_base_sptr result;
1425  int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
1426  ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type);
1427  type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype);
1428  if (!utype)
1429  return result;
1430 
1431  result = dynamic_pointer_cast<type_base>
1432  (rdr->lookup_type(ctf_dictionary, ctf_type));
1433  if (result)
1434  return result;
1435 
1436  qualified_type_def::CV qualifiers = qualified_type_def::CV_NONE;
1437  if (type_kind == CTF_K_CONST)
1438  qualifiers |= qualified_type_def::CV_CONST;
1439  else if (type_kind == CTF_K_VOLATILE)
1440  qualifiers |= qualified_type_def::CV_VOLATILE;
1441  else if (type_kind == CTF_K_RESTRICT)
1442  qualifiers |= qualified_type_def::CV_RESTRICT;
1443  else
1445 
1446  // qualifiers are not be use in functions
1447  if (is_function_type(utype))
1448  return result;
1449 
1450  result.reset(new qualified_type_def(utype, qualifiers, location()));
1451  if (result)
1452  {
1453  // Strip some potentially redundant type qualifiers from
1454  // the qualified type we just built.
1455  decl_base_sptr d = maybe_strip_qualification(is_qualified_type(result));
1456  if (!d)
1457  d = get_type_declaration(result);
1458  ABG_ASSERT(d);
1459 
1460  add_decl_to_scope(d, tunit->get_global_scope());
1461  result = is_type(d);
1462  rdr->add_type(ctf_dictionary, ctf_type, result);
1463  }
1464 
1465  return result;
1466 }
1467 
1468 /// Build and return a pointer type libabigail IR.
1469 ///
1470 /// @param rdr the read context.
1471 /// @param ctf_dictionary the CTF dictionary being read.
1472 /// @param ctf_type the CTF type ID of the source type.
1473 ///
1474 /// @return a shared pointer to the IR node for the pointer type.
1475 
1476 static pointer_type_def_sptr
1477 process_ctf_pointer_type(reader *rdr,
1478  ctf_dict_t *ctf_dictionary,
1479  ctf_id_t ctf_type)
1480 {
1481  corpus_sptr corp = rdr->corpus();
1482  translation_unit_sptr tunit = rdr->cur_transl_unit();
1483  pointer_type_def_sptr result;
1484  ctf_id_t ctf_target_type = ctf_type_reference(ctf_dictionary, ctf_type);
1485  if (ctf_target_type == CTF_ERR)
1486  return result;
1487 
1488  type_base_sptr target_type = rdr->build_type(ctf_dictionary,
1489  ctf_target_type);
1490  if (!target_type)
1491  return result;
1492 
1493  result = dynamic_pointer_cast<pointer_type_def>
1494  (rdr->lookup_type(ctf_dictionary, ctf_type));
1495  if (result)
1496  return result;
1497 
1498  if (rdr->env().is_void_type(target_type))
1499  result = is_pointer_type(build_ir_node_for_void_pointer_type(*rdr, tunit));
1500  else
1501  result.reset(new pointer_type_def(target_type,
1502  ctf_type_size(ctf_dictionary,
1503  ctf_type) * 8,
1504  ctf_type_align(ctf_dictionary,
1505  ctf_type) * 8,
1506  location()));
1507  if (result)
1508  {
1509  add_decl_to_scope(result, tunit->get_global_scope());
1510  rdr->add_type(ctf_dictionary, ctf_type, result);
1511  }
1512 
1513  return result;
1514 }
1515 
1516 /// Build and return an enum type libabigail IR.
1517 ///
1518 /// @param rdr the read context.
1519 /// @param ctf_dictionary the CTF dictionary being read.
1520 /// @param ctf_type the CTF type ID of the source type.
1521 ///
1522 /// @return a shared pointer to the IR node for the enum type.
1523 
1524 static enum_type_decl_sptr
1525 process_ctf_enum_type(reader *rdr,
1526  ctf_dict_t *ctf_dictionary,
1527  ctf_id_t ctf_type)
1528 {
1529  translation_unit_sptr tunit = rdr->cur_transl_unit();
1530  enum_type_decl_sptr result;
1531  ctf_id_t ctf_ref = ctf_type_reference(ctf_dictionary, ctf_type);
1532  std::string enum_name = ctf_type_name_raw(ctf_dictionary,
1533  (ctf_ref != CTF_ERR)
1534  ? ctf_ref : ctf_type);
1535 
1536  if (!enum_name.empty())
1537  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1538  if ((result = lookup_enum_type(enum_name, *corp)))
1539  return result;
1540 
1541  /* Build a signed integral type for the type of the enumerators, aka
1542  the underlying type. The size of the enumerators in bytes is
1543  specified in the CTF enumeration type. */
1544  size_t utype_size_in_bits = ctf_type_size(ctf_dictionary,
1545  (ctf_ref != CTF_ERR)
1546  ? ctf_ref : ctf_type) * 8;
1547  string underlying_type_name =
1549  utype_size_in_bits);
1550 
1551  type_decl_sptr utype;
1552  utype.reset(new type_decl(rdr->env(),
1553  underlying_type_name,
1554  utype_size_in_bits,
1555  utype_size_in_bits,
1556  location()));
1557  utype->set_is_anonymous(true);
1558  utype->set_is_artificial(true);
1559  if (!utype)
1560  return result;
1561 
1562  add_decl_to_scope(utype, tunit->get_global_scope());
1563  canonicalize(utype);
1564 
1565  /* Iterate over the enum entries. */
1567  ctf_next_t *enum_next = NULL;
1568  const char *ename;
1569  int evalue;
1570 
1571  while ((ename = ctf_enum_next(ctf_dictionary, ctf_type, &enum_next, &evalue)))
1572  enms.push_back(enum_type_decl::enumerator(ename, evalue));
1573 
1574  if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
1575  {
1576  fprintf(stderr, "ERROR from ctf_enum_next\n");
1577  return result;
1578  }
1579 
1580  result.reset(new enum_type_decl(enum_name.c_str(), location(),
1581  utype, enms, enum_name.c_str()));
1582  if (result)
1583  {
1584  add_decl_to_scope(result, tunit->get_global_scope());
1585  rdr->add_type(ctf_dictionary, ctf_type, result);
1586  }
1587 
1588  return result;
1589 }
1590 
1591 /// Given a symbol name, lookup the corresponding CTF information in
1592 /// the default dictionary (CTF archive member provided by the caller)
1593 /// If the search is not success, the looks for the symbol name
1594 /// in _all_ archive members.
1595 ///
1596 /// @param ctfa the CTF archive.
1597 /// @param dict the default dictionary to looks for.
1598 /// @param sym_name the symbol name.
1599 /// @param corp the IR corpus.
1600 ///
1601 /// Note that if @ref sym_name is found in other than its default dictionary
1602 /// @ref ctf_dict will be updated and it must be explicitly closed by its
1603 /// caller.
1604 ///
1605 /// @return a valid CTF type id, if @ref sym_name was found, CTF_ERR otherwise.
1606 
1607 static ctf_id_t
1608 lookup_symbol_in_ctf_archive(ctf_archive_t *ctfa, ctf_dict_t **ctf_dict,
1609  const char *sym_name)
1610 {
1611  int ctf_err;
1612  ctf_dict_t *dict = *ctf_dict;
1613  ctf_id_t ctf_type = ctf_lookup_by_symbol_name(dict, sym_name);
1614 
1615  if (ctf_type != CTF_ERR)
1616  return ctf_type;
1617 
1618  /* Probably --ctf-variables option was used by ld, so symbol type
1619  definition must be found in the CTF Variable section. */
1620  ctf_type = ctf_lookup_variable(dict, sym_name);
1621 
1622  /* Not lucky, then, search in whole archive */
1623  if (ctf_type == CTF_ERR)
1624  {
1625  ctf_dict_t *fp;
1626  ctf_next_t *i = NULL;
1627  const char *arcname;
1628 
1629  while ((fp = ctf_archive_next(ctfa, &i, &arcname, 1, &ctf_err)) != NULL)
1630  {
1631  if ((ctf_type = ctf_lookup_by_symbol_name (fp, sym_name)) == CTF_ERR)
1632  ctf_type = ctf_lookup_variable(fp, sym_name);
1633 
1634  if (ctf_type != CTF_ERR)
1635  {
1636  *ctf_dict = fp;
1637  break;
1638  }
1639  ctf_dict_close(fp);
1640  }
1641  }
1642 
1643  return ctf_type;
1644 }
1645 
1646 /// Fill a CTF section description with the information in a given ELF
1647 /// section.
1648 ///
1649 /// @param elf_section the ELF section from which to get.
1650 /// @param ctf_section the CTF section to fill with the raw data.
1651 
1652 static void
1653 fill_ctf_section(const Elf_Scn *elf_section, ctf_sect_t *ctf_section)
1654 {
1655  GElf_Shdr section_header_mem, *section_header;
1656  Elf_Data *section_data;
1657 
1658  section_header = gelf_getshdr(const_cast<Elf_Scn*>(elf_section),
1659  &section_header_mem);
1660  section_data = elf_getdata(const_cast<Elf_Scn*>(elf_section), 0);
1661 
1662  ABG_ASSERT (section_header != NULL);
1663  ABG_ASSERT (section_data != NULL);
1664 
1665  ctf_section->cts_name = ""; /* This is not actually used by libctf. */
1666  ctf_section->cts_data = (char *) section_data->d_buf;
1667  ctf_section->cts_size = section_data->d_size;
1668  ctf_section->cts_entsize = section_header->sh_entsize;
1669 }
1670 
1671 /// Create and return a new read context to process CTF information
1672 /// from a given ELF file.
1673 ///
1674 /// @param elf_path the patch of some ELF file.
1675 ///
1676 /// @param debug_info_root_paths the paths to where to find the debug
1677 /// info.
1678 ///
1679 /// @param env a libabigail IR environment.
1680 elf_based_reader_sptr
1681 create_reader(const std::string& elf_path,
1682  const vector<char**>& debug_info_root_paths,
1683  environment& env)
1684 {
1685  reader_sptr result(new reader(elf_path,
1686  debug_info_root_paths,
1687  env));
1688  return result;
1689 }
1690 
1691 /// Re-initialize a reader so that it can re-used to read
1692 /// another binary.
1693 ///
1694 /// @param rdr the context to re-initialize.
1695 ///
1696 /// @param elf_path the path to the elf file the context is to be used
1697 /// for.
1698 ///
1699 /// @param debug_info_root_paths the paths pointing to where to find
1700 /// the debug info.
1701 void
1703  const std::string& elf_path,
1704  const vector<char**>& debug_info_root_path)
1705 {
1706  ctf::reader& r = dynamic_cast<reader&>(rdr);
1707  r.initialize(elf_path, debug_info_root_path);
1708 }
1709 
1710 /// Returns a key to be use in types_map dict conformed by
1711 /// dictionary id and the CTF type id for a given type.
1712 ///
1713 /// CTF id types are unique by child dictionary, but CTF id
1714 /// types in parent dictionary are unique across the all
1715 /// dictionaries in the CTF archive, to differentiate
1716 /// one each other this member function relies in
1717 /// ctf_type_isparent function.
1718 ///
1719 /// @param dic the pointer to CTF dictionary where the @p type
1720 /// was found.
1721 ///
1722 /// @param type the id for given CTF type.
1723 static std::string
1724 dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type)
1725 {
1726  std::stringstream key;
1727 
1728  if (ctf_type_isparent (dic, ctf_type))
1729  key << std::hex << ctf_type;
1730  else
1731  key << std::hex << ctf_type << '-' << ctf_cuname(dic);
1732  return key.str();
1733 }
1734 
1735 } // End of namespace ctf
1736 } // End of namespace abigail
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one.
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,...
Definition: abg-fwd.h:1714
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
The common interface of readers based on ELF.
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
status
The status of the fe_iface::read_corpus call.
Definition: abg-fe-iface.h:38
@ STATUS_NO_SYMBOLS_FOUND
This status is for when the symbols of the ELF binaries could not be read.
Definition: abg-fe-iface.h:54
@ STATUS_DEBUG_INFO_NOT_FOUND
This status is for when the debug info could not be read.
Definition: abg-fe-iface.h:46
@ STATUS_OK
This status is for when the call went OK.
Definition: abg-fe-iface.h:43
@ STATUS_UNKNOWN
The status is in an unknown state.
Definition: abg-fe-iface.h:40
The abstraction of an array type.
Definition: abg-ir.h:2519
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2533
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition: abg-ir.h:2540
Abstracts a class declaration.
Definition: abg-ir.h:4231
Abstracts the building of the set of exported variables and functions.
Definition: abg-corpus.h:334
Abstraction of a group of corpora.
Definition: abg-corpus.h:383
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:25
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
Definition: abg-corpus.h:51
void sort_functions()
Sort the set of functions exported by this corpus.
Definition: abg-corpus.cc:1431
exported_decls_builder_sptr get_exported_decls_builder() const
Getter for the object that is responsible for determining what decls ought to be in the set of export...
Definition: abg-corpus.cc:1731
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:928
void sort_variables()
Sort the set of variables exported by this corpus.
Definition: abg-corpus.cc:1469
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2750
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2763
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:140
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
Definition: abg-ir.cc:3634
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
Definition: abg-ir.cc:3653
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3697
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter....
Definition: abg-ir.cc:3672
Abstraction of a function parameter.
Definition: abg-ir.h:3286
Abstraction for a function declaration.
Definition: abg-ir.h:3111
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3131
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3138
Abstraction of a function type.
Definition: abg-ir.h:3390
The internal representation of an integral type.
Definition: abg-ir-priv.h:46
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
Definition: abg-ir.cc:16471
The source location of a token.
Definition: abg-ir.h:299
The abstraction of a pointer type.
Definition: abg-ir.h:2337
The abstraction of a qualified type.
Definition: abg-ir.h:2226
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2245
A basic type declaration that introduces no scope.
Definition: abg-ir.h:2108
The abstraction of a typedef declaration.
Definition: abg-ir.h:2889
Abstracts a union type declaration.
Definition: abg-ir.h:4486
Abstracts a variable declaration.
Definition: abg-ir.h:3008
Helper class to allow range-for loops on symtabs for C++11 and later code. It serves as a proxy for t...
The symtab filter is the object passed to the symtab object in order to iterate over the symbols in t...
void set_public_symbols(bool new_value=true)
Enable or disable public symbol filtering.
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< char ** > &debug_info_root_path)
Re-initialize a reader so that it can re-used to read another binary.
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.
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
Definition: abg-ir.cc:12227
unordered_map< string, type_base_sptr > string_type_base_sptr_map_type
A convenience typedef for a map which key is a string and which value is a type_base_sptr.
Definition: abg-ir.h:563
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:267
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10665
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:242
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition: abg-ir.cc:10716
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:11178
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:191
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.
Definition: abg-ir-priv.h:1326
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
Definition: abg-ir.cc:10767
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11640
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:209
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:165
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
Definition: abg-ir.cc:12267
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
Definition: abg-ir.cc:16389
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:10897
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:254
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:119
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:134
const type_base_sptr lookup_type(const interned_string &fqn, const translation_unit &tu)
Lookup a type in a translation unit.
Definition: abg-ir.cc:12673
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
Definition: abg-ir.cc:12304
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Definition: abg-ir.cc:15880
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:224
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
Definition: abg-ir.cc:12372
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10605
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:8625
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:28453
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:173
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11261
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10298
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition: abg-ir.cc:11905
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:160
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11620
typedef_decl_sptr lookup_typedef_type(const interned_string &type_name, const translation_unit &tu)
Lookup a typedef type from a translation unit.
Definition: abg-ir.cc:12410
bool find_file_under_dir(const string &root_dir, const string &file_path_to_look_for, string &result)
Find a given file under a root directory and return its absolute path.
bool dir_name(string const &path, string &dir_name, bool keep_separator_at_end)
Return the directory part of a file path.
bool base_name(string const &path, string &file_name)
Return the file name part of a file part.
void initialize()
This function needs to be called before any libabigail function.
bool file_exists(const string &path)
Tests whether a path exists;.
Toplevel namespace for libabigail.