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