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