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 §ion_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