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