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