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  add_var_to_exported_or_undefined_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  add_fn_to_exported_or_undefined_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  corpus()->sort_functions();
515  corpus()->sort_variables();
516  }
517 
518  /// Add a new type declaration to the given libabigail IR corpus CORP.
519  ///
520  /// @param ctf_dictionary the CTF dictionary being read.
521  /// @param ctf_type the CTF type ID of the source type.
522  ///
523  /// Note that if @ref ctf_type can't reliably be translated to the IR
524  /// then it is simply ignored.
525  ///
526  /// @return a shared pointer to the IR node for the type.
527  type_base_sptr
528  process_ctf_type(ctf_dict_t *ctf_dictionary,
529  ctf_id_t ctf_type)
530  {
531  corpus_sptr corp = corpus();
532  translation_unit_sptr tunit = cur_transl_unit();
533  int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
534  type_base_sptr result;
535 
536  if (lookup_unknown_type(ctf_type))
537  return nullptr;
538 
539  if ((result = lookup_type(ctf_dictionary, ctf_type)))
540  return result;
541 
542  switch (type_kind)
543  {
544  case CTF_K_INTEGER:
545  case CTF_K_FLOAT:
546  {
547  type_decl_sptr type_decl
548  = process_ctf_base_type(this, ctf_dictionary, ctf_type);
549  result = is_type(type_decl);
550  break;
551  }
552  case CTF_K_TYPEDEF:
553  {
554  typedef_decl_sptr typedef_decl
555  = process_ctf_typedef(this, ctf_dictionary, ctf_type);
556  result = is_type(typedef_decl);
557  break;
558  }
559  case CTF_K_POINTER:
560  {
561  pointer_type_def_sptr pointer_type
562  = process_ctf_pointer_type(this, ctf_dictionary, ctf_type);
563  result = pointer_type;
564  break;
565  }
566  case CTF_K_CONST:
567  case CTF_K_VOLATILE:
568  case CTF_K_RESTRICT:
569  {
570  type_base_sptr qualified_type
571  = process_ctf_qualified_type(this, ctf_dictionary, ctf_type);
572  result = qualified_type;
573  break;
574  }
575  case CTF_K_ARRAY:
576  {
577  array_type_def_sptr array_type
578  = process_ctf_array_type(this, ctf_dictionary, ctf_type);
579  result = array_type;
580  break;
581  }
582  case CTF_K_ENUM:
583  {
584  enum_type_decl_sptr enum_type
585  = process_ctf_enum_type(this, ctf_dictionary, ctf_type);
586  result = enum_type;
587  break;
588  }
589  case CTF_K_FUNCTION:
590  {
591  function_type_sptr function_type
592  = process_ctf_function_type(this, ctf_dictionary, ctf_type);
593  result = function_type;
594  break;
595  }
596  case CTF_K_STRUCT:
597  {
598  class_decl_sptr struct_decl
599  = process_ctf_struct_type(this, ctf_dictionary, ctf_type);
600  result = is_type(struct_decl);
601  break;
602  }
603  case CTF_K_FORWARD:
604  result = process_ctf_forward_type(this, ctf_dictionary, ctf_type);
605  break;
606  case CTF_K_UNION:
607  {
608  union_decl_sptr union_decl
609  = process_ctf_union_type(this, ctf_dictionary, ctf_type);
610  result = is_type(union_decl);
611  break;
612  }
613  case CTF_K_UNKNOWN:
614  /* Unknown types are simply ignored. */
615  default:
616  break;
617  }
618 
619  if (!result)
620  {
621  fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type);
622  add_unknown_type(ctf_type);
623  }
624 
625  return result;
626  }
627 
628  /// Given a CTF type id, build the corresponding libabigail IR type.
629  /// If the IR type has been generated it returns the corresponding
630  /// type.
631  ///
632  /// @param ctf_dictionary the CTF dictionary being read.
633  /// @param ctf_type the CTF type ID of the looked type.
634  ///
635  /// Note that if @ref ctf_type can't reliably be translated to the IR
636  /// then a NULL shared pointer is returned.
637  ///
638  /// @return a shared pointer to the IR node for the type.
639  type_base_sptr
640  build_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type)
641  {
642  type_base_sptr result = lookup_type(ctf_dictionary, ctf_type);
643 
644  if (!result)
645  result = process_ctf_type(ctf_dictionary, ctf_type);
646  return result;
647  }
648 
649  /// Read the CTF information in the binary and construct an ABI
650  /// corpus from it.
651  ///
652  /// @param status output parameter. Contains the status of the ABI
653  /// corpus construction.
654  ///
655  /// @return the corpus created as a result of processing the debug
656  /// information.
657  corpus_sptr
658  read_corpus(fe_iface::status &status)
659  {
660  corpus_sptr corp = corpus();
661  status = fe_iface::STATUS_UNKNOWN;
662 
663  corpus::origin origin = corpus()->get_origin();
664  origin |= corpus::CTF_ORIGIN;
665  corp->set_origin(origin);
666 
667  slurp_elf_info(status);
669  return corpus_sptr();
670 
671  if (!(origin & corpus::LINUX_KERNEL_BINARY_ORIGIN)
673  return corp;
674 
675  int errp;
676  if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
677  && corpus_group())
678  {
679  if (ctfa == NULL)
680  {
681  std::string ctfa_filename;
682  if (find_ctfa_file(ctfa_filename))
683  ctfa = ctf_arc_open(ctfa_filename.c_str(), &errp);
684  }
685  }
686  else
687  /* Build the ctfa from the contents of the relevant ELF sections,
688  and process the CTF archive in the read context, if any.
689  Information about the types, variables, functions, etc contained
690  in the archive are added to the given corpus. */
691  ctfa = ctf_arc_bufopen(&ctf_sect, &symtab_sect,
692  &strtab_sect, &errp);
693 
694  env().canonicalization_is_done(false);
695  if (ctfa == NULL)
697  else
698  {
699  process_ctf_archive();
700  corpus()->sort_functions();
701  corpus()->sort_variables();
702  }
703 
704  env().canonicalization_is_done(true);
705 
706  return corp;
707  }
708 
709  /// Destructor of the CTF reader.
710  ~reader()
711  {
712  ctf_close(ctfa);
713  }
714 }; // end class reader.
715 
716 typedef shared_ptr<reader> reader_sptr;
717 
718 /// Build and return a typedef libabigail IR.
719 ///
720 /// @param rdr the read context.
721 /// @param ctf_dictionary the CTF dictionary being read.
722 /// @param ctf_type the CTF type ID of the source type.
723 ///
724 /// @return a shared pointer to the IR node for the typedef.
725 
726 static typedef_decl_sptr
727 process_ctf_typedef(reader *rdr,
728  ctf_dict_t *ctf_dictionary,
729  ctf_id_t ctf_type)
730 {
731  corpus_sptr corp = rdr->corpus();
732  translation_unit_sptr tunit = rdr->cur_transl_unit();
733  typedef_decl_sptr result;
734 
735  ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type);
736  if (ctf_utype == CTF_ERR)
737  return result;
738 
739  const char *typedef_name = ctf_type_name_raw(ctf_dictionary, ctf_type);
740  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
741  if ((result = lookup_typedef_type(typedef_name, *corp)))
742  return result;
743 
744  type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype);
745 
746  if (!utype)
747  return result;
748 
749  result = dynamic_pointer_cast<typedef_decl>
750  (rdr->lookup_type(ctf_dictionary, ctf_type));
751  if (result)
752  return result;
753 
754  result.reset(new typedef_decl(typedef_name, utype, location(),
755  typedef_name /* mangled_name */));
756 
757  /* If this typedef "names" an anonymous type, reflect this fact in
758  the underlying type. In C enum, struct and union types can be
759  anonymous. */
760  if (is_anonymous_type(utype)
761  && (is_enum_type(utype) || is_class_or_union_type(utype)))
762  {
763  decl_base_sptr decl = is_decl(utype);
764  ABG_ASSERT(decl);
765  decl->set_naming_typedef(result);
766  }
767 
768  if (result)
769  {
770  add_decl_to_scope(result, tunit->get_global_scope());
771  rdr->add_type(ctf_dictionary, ctf_type, result);
772  }
773 
774  return result;
775 }
776 
777 /// Build and return an integer or float type declaration libabigail
778 /// IR.
779 ///
780 /// @param rdr the read context.
781 /// @param ctf_dictionary the CTF dictionary being read.
782 /// @param ctf_type the CTF type ID of the source type.
783 ///
784 /// @return a shared pointer to the IR node for the type.
785 
786 static type_decl_sptr
787 process_ctf_base_type(reader *rdr,
788  ctf_dict_t *ctf_dictionary,
789  ctf_id_t ctf_type)
790 {
791  corpus_sptr corp = rdr->corpus();
792  translation_unit_sptr tunit = rdr->cur_transl_unit();
793  type_decl_sptr result;
794 
795  ctf_id_t ctf_ref = ctf_type_reference(ctf_dictionary, ctf_type);
796  const char *type_name = ctf_type_name_raw(ctf_dictionary,
797  (ctf_ref != CTF_ERR) ? ctf_ref : ctf_type);
798 
799  /* Get the type encoding and extract some useful properties of
800  the type from it. In case of any error, just ignore the
801  type. */
802  ctf_encoding_t type_encoding;
803  if (ctf_type_encoding(ctf_dictionary,
804  (ctf_ref != CTF_ERR) ? ctf_ref : ctf_type,
805  &type_encoding))
806  return result;
807 
808  /* Create the IR type corresponding to the CTF type. */
809  if (type_encoding.cte_bits == 0
810  && type_encoding.cte_format == CTF_INT_SIGNED)
811  {
812  /* This is the `void' type. */
813  decl_base_sptr type_declaration = build_ir_node_for_void_type(*rdr,
814  tunit);
815  type_base_sptr void_type = is_type(type_declaration);
816  result = is_type_decl(type_declaration);
817  canonicalize(result);
818  }
819  else
820  {
821  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
822  {
823  string normalized_type_name = type_name;
824  integral_type int_type;
825  if (parse_integral_type(type_name, int_type))
826  normalized_type_name = int_type.to_string();
827  if ((result = lookup_basic_type(normalized_type_name, *corp)))
828  return result;
829  }
830 
831  result = lookup_basic_type(type_name, *corp);
832  if (!result)
833  result.reset(new type_decl(rdr->env(),
834  type_name,
835  type_encoding.cte_bits,
836  /*alignment=*/0,
837  location(),
838  type_name /* mangled_name */));
839 
840  }
841 
842  if (result)
843  {
844  add_decl_to_scope(result, tunit->get_global_scope());
845  rdr->add_type(ctf_dictionary, ctf_type, result);
846  }
847 
848  return result;
849 }
850 
851 /// Build the IR node for a variadic parameter type.
852 ///
853 /// @param rdr the read context to use.
854 ///
855 /// @param tunit the translation unit it should belong to.
856 ///
857 /// @return the variadic parameter type.
858 static decl_base_sptr
859 build_ir_node_for_variadic_parameter_type(reader &rdr,
860  const translation_unit_sptr& tunit)
861 {
862 
863  const ir::environment& env = rdr.env();
864  type_base_sptr t = env.get_variadic_parameter_type();
865  decl_base_sptr type_declaration = get_type_declaration(t);
866  add_decl_to_scope(type_declaration, tunit->get_global_scope());
867  canonicalize(t);
868  return type_declaration;
869 }
870 
871 /// Build the IR node for a void type.
872 ///
873 /// Note that this returns the unique pointer
874 /// environment::get_void_type(), which is added to the current
875 /// translation unit if it's the first it's being used.
876 ///
877 /// @param rdr the read context to use.
878 ///
879 /// @param tunit the translation unit it should belong to.
880 ///
881 /// @return the void type type.
882 static decl_base_sptr
883 build_ir_node_for_void_type(reader& rdr, const translation_unit_sptr& tunit)
884 {
885  const environment& env = rdr.env();
886  type_base_sptr t = env.get_void_type();
887  add_decl_to_scope(is_decl(t), tunit->get_global_scope());
888  canonicalize(t);
889  return is_decl(t);
890 }
891 
892 /// Build the IR node for a void pointer type.
893 ///
894 /// Note that this returns the unique pointer
895 /// environment::get_void_pointer_type(), which is added to the
896 /// current translation unit if it's the first it's being used.
897 ///
898 /// @param rdr the read context to use.
899 ///
900 /// @param tunit the translation unit it should belong to.
901 ///
902 /// @return the void pointer type.
904 build_ir_node_for_void_pointer_type(reader& rdr,
905  const translation_unit_sptr& tunit)
906 {
907  const environment& env = rdr.env();
908  type_base_sptr t = env.get_void_pointer_type();
909  add_decl_to_scope(is_decl(t), tunit->get_global_scope());
910  canonicalize(t);
911  return is_decl(t);
912 }
913 
914 /// Build and return a function type libabigail IR.
915 ///
916 /// @param rdr the read context.
917 /// @param ctf_dictionary the CTF dictionary being read.
918 /// @param ctf_type the CTF type ID of the source type.
919 ///
920 /// @return a shared pointer to the IR node for the function type.
921 
922 static function_type_sptr
923 process_ctf_function_type(reader *rdr,
924  ctf_dict_t *ctf_dictionary,
925  ctf_id_t ctf_type)
926 {
927  corpus_sptr corp = rdr->corpus();
928  translation_unit_sptr tunit = rdr->cur_transl_unit();
929  function_type_sptr result;
930 
931  /* Fetch the function type info from the CTF type. */
932  ctf_funcinfo_t funcinfo;
933  ctf_func_type_info(ctf_dictionary, ctf_type, &funcinfo);
934  int vararg_p = funcinfo.ctc_flags & CTF_FUNC_VARARG;
935 
936  /* Take care first of the result type. */
937  ctf_id_t ctf_ret_type = funcinfo.ctc_return;
938  type_base_sptr ret_type = rdr->build_type(ctf_dictionary, ctf_ret_type);
939  if (!ret_type)
940  return result;
941 
942  /* Now process the argument types. */
943  int argc = funcinfo.ctc_argc;
944  std::vector<ctf_id_t> argv(argc);
945  if (static_cast<ctf_id_t>(ctf_func_type_args(ctf_dictionary, ctf_type,
946  argc, argv.data())) == CTF_ERR)
947  return result;
948 
949  function_decl::parameters function_parms;
950  for (int i = 0; i < argc; i++)
951  {
952  ctf_id_t ctf_arg_type = argv[i];
953  type_base_sptr arg_type = rdr->build_type(ctf_dictionary, ctf_arg_type);
954  if (!arg_type)
955  return result;
956 
958  (new function_decl::parameter(arg_type, "",
959  location(),
960  false,
961  false /* is_artificial */));
962  function_parms.push_back(parm);
963  }
964 
965  if (vararg_p)
966  {
967  type_base_sptr arg_type =
968  is_type(build_ir_node_for_variadic_parameter_type(*rdr, tunit));
969 
971  (new function_decl::parameter(arg_type, "",
972  location(),
973  true,
974  false /* is_artificial */));
975  function_parms.push_back(parm);
976  }
977 
978  result = dynamic_pointer_cast<function_type>
979  (rdr->lookup_type(ctf_dictionary, ctf_type));
980  if (result)
981  return result;
982 
983  /* Ok now the function type itself. */
984  result.reset(new function_type(ret_type,
985  function_parms,
986  tunit->get_address_size(),
987  /*alignment=*/0));
988 
989  if (result)
990  {
991  tunit->bind_function_type_life_time(result);
992  result->set_is_artificial(true);
993  decl_base_sptr function_type_decl = get_type_declaration(result);
994  add_decl_to_scope(function_type_decl, tunit->get_global_scope());
995  rdr->add_type(ctf_dictionary, ctf_type, result);
996  }
997 
998  return result;
999 }
1000 
1001 /// Add member information to a IR struct or union type.
1002 ///
1003 /// @param rdr the read context.
1004 /// @param ctf_dictionary the CTF dictionary being read.
1005 /// @param ctf_type the CTF type ID of the source type.
1006 /// @param sou the IR struct or union type to which add the members.
1007 
1008 static void
1009 process_ctf_sou_members(reader *rdr,
1010  ctf_dict_t *ctf_dictionary,
1011  ctf_id_t ctf_type,
1012  class_or_union_sptr sou)
1013 {
1014  corpus_sptr corp = rdr->corpus();
1015  translation_unit_sptr tunit = rdr->cur_transl_unit();
1016  ssize_t member_size;
1017  ctf_next_t *member_next = NULL;
1018  const char *member_name = NULL;
1019  ctf_id_t member_ctf_type;
1020 
1021  while ((member_size = ctf_member_next(ctf_dictionary, ctf_type,
1022  &member_next, &member_name,
1023  &member_ctf_type,
1024  0 /* flags */)) >= 0)
1025  {
1026  ctf_membinfo_t membinfo;
1027 
1028  if (static_cast<ctf_id_t>(ctf_member_info(ctf_dictionary,
1029  ctf_type,
1030  member_name,
1031  &membinfo)) == CTF_ERR)
1032  return;
1033 
1034  /* Build the IR for the member's type. */
1035  type_base_sptr member_type = rdr->build_type(ctf_dictionary,
1036  member_ctf_type);
1037  if (!member_type)
1038  /* Ignore this member. */
1039  continue;
1040 
1041  /* Create a declaration IR node for the member and add it to the
1042  struct type. */
1043  var_decl_sptr data_member_decl(new var_decl(member_name,
1044  member_type,
1045  location(),
1046  member_name));
1047  sou->add_data_member(data_member_decl,
1048  public_access,
1049  true /* is_laid_out */,
1050  false /* is_static */,
1051  membinfo.ctm_offset);
1052  }
1053  if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
1054  fprintf(stderr, "ERROR from ctf_member_next\n");
1055 }
1056 
1057 /// Create a declaration-only union or struct type and add it to the
1058 /// IR.
1059 ///
1060 /// @param rdr the read context.
1061 /// @param ctf_dictionary the CTF dictionary being read.
1062 /// @param ctf_type the CTF type ID of the source type.
1063 /// @return the resulting IR node created.
1064 
1065 static type_base_sptr
1066 process_ctf_forward_type(reader *rdr,
1067  ctf_dict_t *ctf_dictionary,
1068  ctf_id_t ctf_type)
1069 {
1070  translation_unit_sptr tunit = rdr->cur_transl_unit();
1071  decl_base_sptr result;
1072  std::string type_name = ctf_type_name_raw(ctf_dictionary,
1073  ctf_type);
1074  bool type_is_anonymous = (type_name == "");
1075  uint32_t kind = ctf_type_kind_forwarded (ctf_dictionary, ctf_type);
1076 
1077  if (kind == CTF_K_UNION)
1078  {
1079  union_decl_sptr
1080  union_fwd(new union_decl(rdr->env(),
1081  type_name,
1082  /*alignment=*/0,
1083  location(),
1084  decl_base::VISIBILITY_DEFAULT,
1085  type_is_anonymous));
1086  union_fwd->set_is_declaration_only(true);
1087  result = union_fwd;
1088  }
1089  else
1090  {
1091  if (!type_is_anonymous)
1092  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1093  if ((result = lookup_class_type(type_name, *corp)))
1094  return is_type(result);
1095 
1097  struct_fwd(new class_decl(rdr->env(), type_name,
1098  /*alignment=*/0, /*size=*/0,
1099  true /* is_struct */,
1100  location(),
1101  decl_base::VISIBILITY_DEFAULT,
1102  type_is_anonymous));
1103  struct_fwd->set_is_declaration_only(true);
1104  result = struct_fwd;
1105  }
1106 
1107  if (!result)
1108  return is_type(result);
1109 
1110  add_decl_to_scope(result, tunit->get_global_scope());
1111  rdr->add_type(ctf_dictionary, ctf_type, is_type(result));
1112 
1113  return is_type(result);
1114 }
1115 
1116 /// Build and return a struct type libabigail IR.
1117 ///
1118 /// @param rdr the read context.
1119 /// @param ctf_dictionary the CTF dictionary being read.
1120 /// @param ctf_type the CTF type ID of the source type.
1121 ///
1122 /// @return a shared pointer to the IR node for the struct type.
1123 
1124 static class_decl_sptr
1125 process_ctf_struct_type(reader *rdr,
1126  ctf_dict_t *ctf_dictionary,
1127  ctf_id_t ctf_type)
1128 {
1129  corpus_sptr corp = rdr->corpus();
1130  translation_unit_sptr tunit = rdr->cur_transl_unit();
1131  class_decl_sptr result;
1132  std::string struct_type_name = ctf_type_name_raw(ctf_dictionary,
1133  ctf_type);
1134  bool struct_type_is_anonymous = (struct_type_name == "");
1135 
1136  if (!struct_type_is_anonymous)
1137  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1138  if ((result = lookup_class_type(struct_type_name, *corp)))
1139  return result;
1140 
1141  /* The libabigail IR encodes C struct types in `class' IR nodes. */
1142  result.reset(new class_decl(rdr->env(),
1143  struct_type_name,
1144  ctf_type_size(ctf_dictionary, ctf_type) * 8,
1145  /*alignment=*/0,
1146  true /* is_struct */,
1147  location(),
1148  decl_base::VISIBILITY_DEFAULT,
1149  struct_type_is_anonymous));
1150  if (!result)
1151  return result;
1152 
1153  /* The C type system indirectly supports loops by the mean of
1154  pointers to structs or unions. Since some contained type can
1155  refer to this struct, we have to make it available in the cache
1156  at this point even if the members haven't been added to the IR
1157  node yet. */
1158  add_decl_to_scope(result, tunit->get_global_scope());
1159  rdr->add_type(ctf_dictionary, ctf_type, result);
1160 
1161  /* Now add the struct members as specified in the CTF type description.
1162  This is C, so named types can only be defined in the global
1163  scope. */
1164  process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result);
1165 
1166  return result;
1167 }
1168 
1169 /// Build and return an union type libabigail IR.
1170 ///
1171 /// @param rdr the read context.
1172 /// @param ctf_dictionary the CTF dictionary being read.
1173 /// @param ctf_type the CTF type ID of the source type.
1174 ///
1175 /// @return a shared pointer to the IR node for the union type.
1176 
1177 static union_decl_sptr
1178 process_ctf_union_type(reader *rdr,
1179  ctf_dict_t *ctf_dictionary,
1180  ctf_id_t ctf_type)
1181 {
1182  corpus_sptr corp = rdr->corpus();
1183  translation_unit_sptr tunit = rdr->cur_transl_unit();
1184  union_decl_sptr result;
1185  std::string union_type_name = ctf_type_name_raw(ctf_dictionary,
1186  ctf_type);
1187  bool union_type_is_anonymous = (union_type_name == "");
1188 
1189  if (!union_type_is_anonymous)
1190  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1191  if ((result = lookup_union_type(union_type_name, *corp)))
1192  return result;
1193 
1194  /* Create the corresponding libabigail union IR node. */
1195  result.reset(new union_decl(rdr->env(),
1196  union_type_name,
1197  ctf_type_size(ctf_dictionary, ctf_type) * 8,
1198  location(),
1199  decl_base::VISIBILITY_DEFAULT,
1200  union_type_is_anonymous));
1201  if (!result)
1202  return result;
1203 
1204  /* The C type system indirectly supports loops by the mean of
1205  pointers to structs or unions. Since some contained type can
1206  refer to this union, we have to make it available in the cache
1207  at this point even if the members haven't been added to the IR
1208  node yet. */
1209  add_decl_to_scope(result, tunit->get_global_scope());
1210  rdr->add_type(ctf_dictionary, ctf_type, result);
1211 
1212  /* Now add the union members as specified in the CTF type description.
1213  This is C, so named types can only be defined in the global
1214  scope. */
1215  process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result);
1216 
1217  return result;
1218 }
1219 
1220 /// Build and return an array subrange.
1221 ///
1222 /// @param rdr the read context.
1223 ///
1224 /// @param ctf_dictionary the CTF dictionary where @ref index
1225 /// will be found.
1226 ///
1227 /// @param index the CTF type ID for the array index.
1228 ///
1229 /// @param nelems the elements number of the array.
1230 ///
1231 /// @return a shared pointer to subrange built.
1233 build_array_ctf_range(reader *rdr, ctf_dict_t *dic,
1234  ctf_id_t index, uint64_t nelems)
1235 {
1236  bool is_non_finite = false;
1237  corpus_sptr corp = rdr->corpus();
1238  translation_unit_sptr tunit = rdr->cur_transl_unit();
1240  array_type_def::subrange_type::bound_value lower_bound;
1241  array_type_def::subrange_type::bound_value upper_bound;
1242 
1243  type_base_sptr index_type = rdr->build_type(dic, index);
1244  if (!index_type)
1245  return nullptr;
1246 
1247  lower_bound.set_unsigned(0); /* CTF supports C only. */
1248  upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U);
1249 
1250  /* for VLAs number of array elements is 0 */
1251  if (upper_bound.get_unsigned_value() == 0 && nelems == 0)
1252  is_non_finite = true;
1253 
1254  subrange.reset(new array_type_def::subrange_type(rdr->env(),
1255  "",
1256  lower_bound,
1257  upper_bound,
1258  index_type,
1259  location(),
1260  translation_unit::LANG_C));
1261  if (!subrange)
1262  return nullptr;
1263 
1264  subrange->is_non_finite(is_non_finite);
1265  add_decl_to_scope(subrange, tunit->get_global_scope());
1266  canonicalize(subrange);
1267 
1268  return subrange;
1269 }
1270 
1271 /// Build and return an array type libabigail IR.
1272 ///
1273 /// @param rdr the read context.
1274 ///
1275 /// @param ctf_dictionary the CTF dictionary being read.
1276 ///
1277 /// @param ctf_type the CTF type ID of the source type.
1278 ///
1279 /// @return a shared pointer to the IR node for the array type.
1280 static array_type_def_sptr
1281 process_ctf_array_type(reader *rdr,
1282  ctf_dict_t *ctf_dictionary,
1283  ctf_id_t ctf_type)
1284 {
1285  corpus_sptr corp = rdr->corpus();
1286  translation_unit_sptr tunit = rdr->cur_transl_unit();
1287  array_type_def_sptr result;
1288  ctf_arinfo_t ctf_ainfo;
1289 
1290  /* First, get the information about the CTF array. */
1291  if (static_cast<ctf_id_t>(ctf_array_info(ctf_dictionary,
1292  ctf_type,
1293  &ctf_ainfo)) == CTF_ERR)
1294  return result;
1295 
1296  ctf_id_t ctf_element_type = ctf_ainfo.ctr_contents;
1297  ctf_id_t ctf_index_type = ctf_ainfo.ctr_index;
1298  uint64_t nelems = ctf_ainfo.ctr_nelems;
1301 
1302  int type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type);
1303  while (type_array_kind == CTF_K_ARRAY)
1304  {
1305  if (static_cast<ctf_id_t>(ctf_array_info(ctf_dictionary,
1306  ctf_element_type,
1307  &ctf_ainfo)) == CTF_ERR)
1308  return result;
1309 
1310  subrange = build_array_ctf_range(rdr, ctf_dictionary,
1311  ctf_ainfo.ctr_index,
1312  ctf_ainfo.ctr_nelems);
1313  subranges.push_back(subrange);
1314  ctf_element_type = ctf_ainfo.ctr_contents;
1315  type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type);
1316  }
1317 
1318  std::reverse(subranges.begin(), subranges.end());
1319 
1320  /* Make sure the element type is generated. */
1321  type_base_sptr element_type = rdr->build_type(ctf_dictionary,
1322  ctf_element_type);
1323  if (!element_type)
1324  return result;
1325 
1326  /* Ditto for the index type. */
1327  type_base_sptr index_type = rdr->build_type(ctf_dictionary,
1328  ctf_index_type);
1329  if (!index_type)
1330  return result;
1331 
1332  result = dynamic_pointer_cast<array_type_def>
1333  (rdr->lookup_type(ctf_dictionary, ctf_type));
1334  if (result)
1335  return result;
1336 
1337  subrange = build_array_ctf_range(rdr, ctf_dictionary,
1338  ctf_index_type, nelems);
1339  subranges.push_back(subrange);
1340 
1341  /* Finally build the IR for the array type and return it. */
1342  result.reset(new array_type_def(element_type, subranges, location()));
1343  if (result)
1344  {
1345  decl_base_sptr array_type_decl = get_type_declaration(result);
1346  add_decl_to_scope(array_type_decl, tunit->get_global_scope());
1347  rdr->add_type(ctf_dictionary, ctf_type, result);
1348  }
1349 
1350  return result;
1351 }
1352 
1353 /// Strip qualification from a qualified type, when it makes sense.
1354 ///
1355 /// The C language specification says in [6.7.3]/8:
1356 ///
1357 /// [If the specification of an array type includes any type
1358 /// qualifiers, the element type is so- qualified, not the
1359 /// array type.]
1360 ///
1361 /// In more mundane words, a const array of int is the same as an
1362 /// array of const int.
1363 ///
1364 /// This function thus removes the qualifiers of the array and applies
1365 /// them to the array element. The function then pretends that the
1366 /// array itself it not qualified.
1367 ///
1368 /// It might contain code to strip other cases like this in the
1369 /// future.
1370 ///
1371 /// @param t the type to strip const qualification from.
1372 ///
1373 /// @return the stripped type or just return @p t.
1374 static decl_base_sptr
1375 maybe_strip_qualification(const qualified_type_def_sptr t)
1376 {
1377  if (!t)
1378  return t;
1379 
1380  decl_base_sptr result = t;
1381  type_base_sptr u = t->get_underlying_type();
1382 
1383  if (is_array_type(u))
1384  {
1385  // Let's apply the qualifiers of the array to the array element
1386  // and pretend that the array itself is not qualified, as per
1387  // section [6.7.3]/8 of the C specification.
1388 
1390  ABG_ASSERT(array);
1391  // We should not be editing types that are already canonicalized.
1392  ABG_ASSERT(!array->get_canonical_type());
1393  type_base_sptr element_type = array->get_element_type();
1394 
1395  if (qualified_type_def_sptr qualified = is_qualified_type(element_type))
1396  {
1397  qualified_type_def::CV quals = qualified->get_cv_quals();
1398  quals |= t->get_cv_quals();
1399  // So we apply the qualifiers of the array to the array
1400  // element.
1401  qualified->set_cv_quals(quals);
1402  // Let's pretend that the array is no more qualified.
1403  result = is_decl(u);
1404  }
1405  }
1406 
1407  return result;
1408 }
1409 
1410 /// Build and return a qualified type libabigail IR.
1411 ///
1412 /// @param rdr the read context.
1413 /// @param ctf_dictionary the CTF dictionary being read.
1414 /// @param ctf_type the CTF type ID of the source type.
1415 
1416 static type_base_sptr
1417 process_ctf_qualified_type(reader *rdr,
1418  ctf_dict_t *ctf_dictionary,
1419  ctf_id_t ctf_type)
1420 {
1421  corpus_sptr corp = rdr->corpus();
1422  translation_unit_sptr tunit = rdr->cur_transl_unit();
1423  type_base_sptr result;
1424  int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
1425  ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type);
1426  type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype);
1427  if (!utype)
1428  return result;
1429 
1430  result = dynamic_pointer_cast<type_base>
1431  (rdr->lookup_type(ctf_dictionary, ctf_type));
1432  if (result)
1433  return result;
1434 
1435  qualified_type_def::CV qualifiers = qualified_type_def::CV_NONE;
1436  if (type_kind == CTF_K_CONST)
1437  qualifiers |= qualified_type_def::CV_CONST;
1438  else if (type_kind == CTF_K_VOLATILE)
1439  qualifiers |= qualified_type_def::CV_VOLATILE;
1440  else if (type_kind == CTF_K_RESTRICT)
1441  qualifiers |= qualified_type_def::CV_RESTRICT;
1442  else
1444 
1445  // qualifiers are not be use in functions
1446  if (is_function_type(utype))
1447  return result;
1448 
1449  result.reset(new qualified_type_def(utype, qualifiers, location()));
1450  if (result)
1451  {
1452  // Strip some potentially redundant type qualifiers from
1453  // the qualified type we just built.
1454  decl_base_sptr d = maybe_strip_qualification(is_qualified_type(result));
1455  if (!d)
1456  d = get_type_declaration(result);
1457  ABG_ASSERT(d);
1458 
1459  add_decl_to_scope(d, tunit->get_global_scope());
1460  result = is_type(d);
1461  rdr->add_type(ctf_dictionary, ctf_type, result);
1462  }
1463 
1464  return result;
1465 }
1466 
1467 /// Build and return a pointer type libabigail IR.
1468 ///
1469 /// @param rdr the read context.
1470 /// @param ctf_dictionary the CTF dictionary being read.
1471 /// @param ctf_type the CTF type ID of the source type.
1472 ///
1473 /// @return a shared pointer to the IR node for the pointer type.
1474 
1475 static pointer_type_def_sptr
1476 process_ctf_pointer_type(reader *rdr,
1477  ctf_dict_t *ctf_dictionary,
1478  ctf_id_t ctf_type)
1479 {
1480  corpus_sptr corp = rdr->corpus();
1481  translation_unit_sptr tunit = rdr->cur_transl_unit();
1482  pointer_type_def_sptr result;
1483  ctf_id_t ctf_target_type = ctf_type_reference(ctf_dictionary, ctf_type);
1484  if (ctf_target_type == CTF_ERR)
1485  return result;
1486 
1487  type_base_sptr target_type = rdr->build_type(ctf_dictionary,
1488  ctf_target_type);
1489  if (!target_type)
1490  return result;
1491 
1492  result = dynamic_pointer_cast<pointer_type_def>
1493  (rdr->lookup_type(ctf_dictionary, ctf_type));
1494  if (result)
1495  return result;
1496 
1497  if (rdr->env().is_void_type(target_type))
1498  result = is_pointer_type(build_ir_node_for_void_pointer_type(*rdr, tunit));
1499  else
1500  result.reset(new pointer_type_def(target_type,
1501  ctf_type_size(ctf_dictionary,
1502  ctf_type) * 8,
1503  ctf_type_align(ctf_dictionary,
1504  ctf_type) * 8,
1505  location()));
1506  if (result)
1507  {
1508  add_decl_to_scope(result, tunit->get_global_scope());
1509  rdr->add_type(ctf_dictionary, ctf_type, result);
1510  }
1511 
1512  return result;
1513 }
1514 
1515 /// Build and return an enum type libabigail IR.
1516 ///
1517 /// @param rdr the read context.
1518 /// @param ctf_dictionary the CTF dictionary being read.
1519 /// @param ctf_type the CTF type ID of the source type.
1520 ///
1521 /// @return a shared pointer to the IR node for the enum type.
1522 
1523 static enum_type_decl_sptr
1524 process_ctf_enum_type(reader *rdr,
1525  ctf_dict_t *ctf_dictionary,
1526  ctf_id_t ctf_type)
1527 {
1528  translation_unit_sptr tunit = rdr->cur_transl_unit();
1529  enum_type_decl_sptr result;
1530  ctf_id_t ctf_ref = ctf_type_reference(ctf_dictionary, ctf_type);
1531  std::string enum_name = ctf_type_name_raw(ctf_dictionary,
1532  (ctf_ref != CTF_ERR)
1533  ? ctf_ref : ctf_type);
1534 
1535  if (!enum_name.empty())
1536  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1537  if ((result = lookup_enum_type(enum_name, *corp)))
1538  return result;
1539 
1540  /* Build a signed integral type for the type of the enumerators, aka
1541  the underlying type. The size of the enumerators in bytes is
1542  specified in the CTF enumeration type. */
1543  size_t utype_size_in_bits = ctf_type_size(ctf_dictionary,
1544  (ctf_ref != CTF_ERR)
1545  ? ctf_ref : ctf_type) * 8;
1546  string underlying_type_name =
1548  utype_size_in_bits);
1549 
1550  type_decl_sptr utype;
1551  utype.reset(new type_decl(rdr->env(),
1552  underlying_type_name,
1553  utype_size_in_bits,
1554  utype_size_in_bits,
1555  location()));
1556  utype->set_is_anonymous(true);
1557  utype->set_is_artificial(true);
1558  if (!utype)
1559  return result;
1560 
1561  add_decl_to_scope(utype, tunit->get_global_scope());
1562  canonicalize(utype);
1563 
1564  /* Iterate over the enum entries. */
1566  ctf_next_t *enum_next = NULL;
1567  const char *ename;
1568  int evalue;
1569 
1570  while ((ename = ctf_enum_next(ctf_dictionary, ctf_type, &enum_next, &evalue)))
1571  enms.push_back(enum_type_decl::enumerator(ename, evalue));
1572 
1573  if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
1574  {
1575  fprintf(stderr, "ERROR from ctf_enum_next\n");
1576  return result;
1577  }
1578 
1579  result.reset(new enum_type_decl(enum_name.c_str(), location(),
1580  utype, enms, enum_name.c_str()));
1581  if (result)
1582  {
1583  add_decl_to_scope(result, tunit->get_global_scope());
1584  rdr->add_type(ctf_dictionary, ctf_type, result);
1585  }
1586 
1587  return result;
1588 }
1589 
1590 /// Given a symbol name, lookup the corresponding CTF information in
1591 /// the default dictionary (CTF archive member provided by the caller)
1592 /// If the search is not success, the looks for the symbol name
1593 /// in _all_ archive members.
1594 ///
1595 /// @param ctfa the CTF archive.
1596 /// @param dict the default dictionary to looks for.
1597 /// @param sym_name the symbol name.
1598 /// @param corp the IR corpus.
1599 ///
1600 /// Note that if @ref sym_name is found in other than its default dictionary
1601 /// @ref ctf_dict will be updated and it must be explicitly closed by its
1602 /// caller.
1603 ///
1604 /// @return a valid CTF type id, if @ref sym_name was found, CTF_ERR otherwise.
1605 
1606 static ctf_id_t
1607 lookup_symbol_in_ctf_archive(ctf_archive_t *ctfa, ctf_dict_t **ctf_dict,
1608  const char *sym_name)
1609 {
1610  int ctf_err;
1611  ctf_dict_t *dict = *ctf_dict;
1612  ctf_id_t ctf_type = ctf_lookup_by_symbol_name(dict, sym_name);
1613 
1614  if (ctf_type != CTF_ERR)
1615  return ctf_type;
1616 
1617  /* Probably --ctf-variables option was used by ld, so symbol type
1618  definition must be found in the CTF Variable section. */
1619  ctf_type = ctf_lookup_variable(dict, sym_name);
1620 
1621  /* Not lucky, then, search in whole archive */
1622  if (ctf_type == CTF_ERR)
1623  {
1624  ctf_dict_t *fp;
1625  ctf_next_t *i = NULL;
1626  const char *arcname;
1627 
1628  while ((fp = ctf_archive_next(ctfa, &i, &arcname, 1, &ctf_err)) != NULL)
1629  {
1630  if ((ctf_type = ctf_lookup_by_symbol_name (fp, sym_name)) == CTF_ERR)
1631  ctf_type = ctf_lookup_variable(fp, sym_name);
1632 
1633  if (ctf_type != CTF_ERR)
1634  {
1635  *ctf_dict = fp;
1636  break;
1637  }
1638  ctf_dict_close(fp);
1639  }
1640  }
1641 
1642  return ctf_type;
1643 }
1644 
1645 /// Fill a CTF section description with the information in a given ELF
1646 /// section.
1647 ///
1648 /// @param elf_section the ELF section from which to get.
1649 /// @param ctf_section the CTF section to fill with the raw data.
1650 
1651 static void
1652 fill_ctf_section(const Elf_Scn *elf_section, ctf_sect_t *ctf_section)
1653 {
1654  GElf_Shdr section_header_mem, *section_header;
1655  Elf_Data *section_data;
1656 
1657  section_header = gelf_getshdr(const_cast<Elf_Scn*>(elf_section),
1658  &section_header_mem);
1659  section_data = elf_getdata(const_cast<Elf_Scn*>(elf_section), 0);
1660 
1661  ABG_ASSERT (section_header != NULL);
1662  ABG_ASSERT (section_data != NULL);
1663 
1664  ctf_section->cts_name = ""; /* This is not actually used by libctf. */
1665  ctf_section->cts_data = (char *) section_data->d_buf;
1666  ctf_section->cts_size = section_data->d_size;
1667  ctf_section->cts_entsize = section_header->sh_entsize;
1668 }
1669 
1670 /// Create and return a new read context to process CTF information
1671 /// from a given ELF file.
1672 ///
1673 /// @param elf_path the patch of some ELF file.
1674 /// @param env a libabigail IR environment.
1675 
1676 elf_based_reader_sptr
1677 create_reader(const std::string& elf_path,
1678  const vector<char**>& debug_info_root_paths,
1679  environment& env)
1680 {
1681  reader_sptr result(new reader(elf_path,
1682  debug_info_root_paths,
1683  env));
1684  return result;
1685 }
1686 
1687 /// Re-initialize a reader so that it can re-used to read
1688 /// another binary.
1689 ///
1690 /// @param rdr the context to re-initialize.
1691 ///
1692 /// @param elf_path the path to the elf file the context is to be used
1693 /// for.
1694 ///
1695 /// @param environment the environment used by the current context.
1696 /// This environment contains resources needed by the reader and by
1697 /// the types and declarations that are to be created later. Note
1698 /// that ABI artifacts that are to be compared all need to be created
1699 /// within the same environment.
1700 ///
1701 /// Please also note that the life time of this environment object
1702 /// must be greater than the life time of the resulting @ref
1703 /// reader the context uses resources that are allocated in the
1704 /// environment.
1705 void
1706 reset_reader(elf_based_reader& rdr,
1707  const std::string& elf_path,
1708  const vector<char**>& debug_info_root_path)
1709 {
1710  ctf::reader& r = dynamic_cast<reader&>(rdr);
1711  r.initialize(elf_path, debug_info_root_path);
1712 }
1713 
1714 /// Returns a key to be use in types_map dict conformed by
1715 /// dictionary id and the CTF type id for a given type.
1716 ///
1717 /// CTF id types are unique by child dictionary, but CTF id
1718 /// types in parent dictionary are unique across the all
1719 /// dictionaries in the CTF archive, to differentiate
1720 /// one each other this member function relies in
1721 /// ctf_type_isparent function.
1722 ///
1723 /// @param dic the pointer to CTF dictionary where the @p type
1724 /// was found.
1725 ///
1726 /// @param type the id for given CTF type.
1727 static std::string
1728 dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type)
1729 {
1730  std::stringstream key;
1731 
1732  if (ctf_type_isparent (dic, ctf_type))
1733  key << std::hex << ctf_type;
1734  else
1735  key << std::hex << ctf_type << '-' << ctf_cuname(dic);
1736  return key.str();
1737 }
1738 
1739 } // End of namespace ctf
1740 } // 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:8625
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10665
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
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
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:12410
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:209
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.
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
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:254
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:11178
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:165
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:28453
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:12304
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:2763
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Definition: abg-ir.cc:15880
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
void add_var_to_exported_or_undefined_decls(const var_decl *var)
Add the representation of the ABI of a variable to the set of exported or undefined declarations of t...
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:267
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10605
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
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:3138
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3131
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:50
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:12372
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10298
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:160
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:1714
void add_fn_to_exported_or_undefined_decls(const function_decl *fn)
Add the representation of the ABI of a function to the set of exported declarations or undefined decl...
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.
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
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:10716
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:173
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:191
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
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 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:2540
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
The status is in an unknown state.
Definition: abg-fe-iface.h:40
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
Definition: abg-ir.cc:16389
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2533
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:242
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
bool base_name(string const &path, string &file_name)
Return the file name part of a file part.
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
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:2244