summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillermo E. Martinez <guillermo.e.martinez@oracle.com>2022-05-04 17:29:30 -0500
committerDodji Seketeli <dodji@redhat.com>2022-05-13 09:11:37 +0200
commite64d32bee317837d3b5209fdc087309d58a6f16d (patch)
treef35342aadcc972eea1c7a93b8fb1f5a49cd4b2e7
parentAdd Logic to detect file type by extension (diff)
downloadlibabigail-e64d32bee317837d3b5209fdc087309d58a6f16d.tar.gz
libabigail-e64d32bee317837d3b5209fdc087309d58a6f16d.tar.bz2
libabigail-e64d32bee317837d3b5209fdc087309d58a6f16d.tar.xz
ctf-reader: Add support to read CTF information from the Linux Kernel
This patch is meant to extract ABI information from the CTF data stored in the Linux kernel build directory. It depends on the vmlinux.ctfa archive file. In order to generate the CTF information, the Linux Kernel build system must support the 'make ctf' command, which causes the compiler to be run with -gctf, thus emitting the CTF information for the Kernel. The target 'ctf' in the Linux Makefile generates a 'vmlinux.ctfa' file that will be used by the ctf reader in libabigail. The 'vmlinux.ctfa' archive has multiple 'ctf dictionaries' called "CTF archive members". There is one CTF archive member for built-in kernel modules (in `vmlinux') and one for each out-of-tree kernel module organized in a parent-child hierarchy. There is also a CTF archive member called `shared_ctf' which is a parent dictionary containing shared symbols and CTF types used by more than one kernel object. These common types are stored in 'types_map' in the ctf reader, ignoring the ctf dictionary name. The CTF API has the machinery for looking for a shared type in the parent dictionary referred to in a given child dictionary. This CTF layout can be dumped by using the objdump tool. Due to the fact that the _same_ ctf archive is used to build the vmlinux corpus the corpora of the kernel module (which, by the way, all belong to the same corpus group), the high number of open/close on the CTF archive is very time consuming during the ctf extraction. So, the performance is improved up to 300% (from ~2m:50s to ~50s) by keeping the ctf archive open for a given group, and thus, by using the same ctf_archive_t pointer while building all the various corpora. We just invoke `reset_read_context' for each new corpus. Note that the `read_context::ctfa` data member should be updated if the corpus::origin data member is set to `LINUX_KERNEL_BINARY_ORIGIN' and the file to be process is not 'vmlinux'. Note that `ctf_close' must be called after processing all group's members so it is executed from the destructor of `reader_context'. The basic algorithm used to generate the Linux corpus is the following: 1. Looking for: vmlinux, *.ko objects, and vmlinux.ctfa files. The first files are used to extract the ELF symbols, and the last one contains the CTF type information for non-static variables and functions symbols. 2. `process_ctf_archive' iterates on public symbols for vmlinux and its modules, using the name of the symbol, ctf reader search for CTF information in its dictionary, if the information was found it builds a `var_decl' or `function_decl' depending of `ctf_type_kind' result. This algorithm is also applied to ELF files (exec, dyn, rel), so instead of iterating on all ctf_types it just loops on the public symbols. * abg-elf-reader-common.h: Include ctf-api.h file. (read_and_add_corpus_to_group_from_elf, set_read_context_corpus_group) (reset_read_context, dic_type_key): Declare new member functions. * include/abg-ir.cc (types_defined_same_linux_kernel_corpus_public): Use bitwise to know the corpus `origin'. * src/abg-ctf-reader.cc: Include map, algorithms header files. (read_context::type_map): Change from unordered_map to std::map storing ctf dictionary name as part of the key. (read_context::is_elf_exec): Add new member variable. (read_context::{cur_corpus_, cur_corpus_group_}): Likewise. (read_context::unknown_types_set): Likewise. (read_context::{current_corpus_group, main_corpus_from_current_group, has_corpus_group, current_corpus_is_main_corpus_from_current_group, should_reuse_type_from_corpus_group}): Add new member functions. (read_context::{add_unknown_type, lookup_unknown_type, initialize}): Likewise. (read_context::{add_type, lookup_type}): Add new `ctf_dict_t' type argument. (ctf_reader::{process_ctf_typedef, process_ctf_base_type, process_ctf_function_type, process_ctf_forward_type, process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type, process_ctf_qualified_type, process_ctf_enum_type}): Add code to `reuse' types already registered in main corpus `should_reuse_type_from_corpus_group'. Use new `lookup_type' and `add_type' operations on `read_context::types_map'. Replace function calls to the new ctf interface. Add verifier to not build types duplicated by recursive calling chain. (ctf_reader::process_ctf_type): Add code to return immediately if the ctf type is unknown. Add unknown types to `unknown_types_set'. (ctf_reader::process_ctf_archive): Change comment. Add code to iterate over global symbols, searching by symbol name in the ctf dictionary using `ctf_lookup_{variable,by_symbol_name}' depending of the ELF file type and corpus type, creating a `{var,fuc}_decl' using the return type of `ctf_type_kind'. Also close the ctf dict and call `canonicalize_all_types'. (slurp_elf_info): Set `is_elf_exec' depending of ELF type. Also return success if corpus origin is Linux and symbol table was read. (ctf_reader::read_corpus): Add current corpus. Set corpus origin to `LINUX_KERNEL_BINARY_ORIGIN' if `is_linux_kernel' returns true. Verify the ctf reader status, now the ctf archive is 'opened' using `ctf_arc{open,bufopen}' depending if the corpus origin has `corpus::LINUX_KERNEL_BINARY_ORIGIN' bit set. Use `sort_{function,variables}' calls after extract ctf information. `ctf_close' is called from `read_context' destructor. (read:context::{set_read_context_corpus_group, reset_read_context, read_and_add_corpus_to_group_from_elf, dic_type_key): Add new member function implementation. * include/abg-tools-utils.h (build_corpus_group_from_kernel_dist_under): Add `origin' parameter with default `corpus::DWARF_ORIGIN'. * src/abg-tools-utils.cc: Use `abg-ctf-reader.h' file. (maybe_load_vmlinux_dwarf_corpus): Add new function. (maybe_load_vmlinux_ctf_corpus): Likewise. (build_corpus_group_from_kernel_dist_under): Update comments. Add new `origin' argument. Use `maybe_load_vmlinux_dwarf_corpus' or `maybe_load_vmlinux_ctf_corpus' according to `origin' value. * src/abg-corpus.h (corpus::origin): Update `origin' type values in enum. * src/abg-corpus-priv.h (corpus::priv): Replace `origin' type from `corpus::origin' to `uint32_t'. * src/abg-corpus.cc (corpus::{get,set}_origin): Replace data type from `corpus::origin' to `uint32_t'. * tools/abidw.cc (main): Use of --ctf argument to set format debug. * tests/test-read-ctf.cc: Add new tests to harness. * tests/data/test-read-ctf/test-PR27700.abi: New test expected result. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum-many.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi: Likewise. * tests/data/test-read-common/test-PR26568-2.o: Adjust. * tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise. * tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.c: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise. * tests/data/test-read-ctf/test-callback.abi: Likewise. * tests/data/test-read-ctf/test-callback2.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-ctf.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum.o.abi: Likewise. * tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise. * tests/data/test-read-ctf/test-functions-declaration.abi: Likewise. * tests/data/test-read-ctf/test-list-struct.abi: Likewise. * tests/data/test-read-ctf/test0: Likewise. * tests/data/test-read-ctf/test0.abi: Likewise. * tests/data/test-read-ctf/test0.c: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test2.so.abi: Likewise. * tests/data/test-read-ctf/test2.so.hash.abi: Likewise. * tests/data/test-read-ctf/test3.so.abi: Likewise. * tests/data/test-read-ctf/test3.so.hash.abi: Likewise. * tests/data/test-read-ctf/test4.so.abi: Likewise. * tests/data/test-read-ctf/test4.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/data/test-read-ctf/test7.o.abi: Likewise. * tests/data/test-read-ctf/test8.o.abi: Likewise. * tests/data/test-read-ctf/test9.o.abi: Likewise. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
-rw-r--r--include/abg-corpus.h20
-rw-r--r--include/abg-ctf-reader.h16
-rw-r--r--include/abg-tools-utils.h3
-rw-r--r--src/abg-corpus-priv.h2
-rw-r--r--src/abg-corpus.cc56
-rw-r--r--src/abg-ctf-reader.cc507
-rw-r--r--src/abg-dwarf-reader.cc8
-rw-r--r--src/abg-ir.cc2
-rw-r--r--src/abg-tools-utils.cc317
-rw-r--r--tests/data/test-read-common/test-PR26568-2.obin3048 -> 3488 bytes
-rw-r--r--tests/data/test-read-ctf/PR27700/test-PR27700.abi3
-rw-r--r--tests/data/test-read-ctf/test-PR26568-1.o.abi34
-rw-r--r--tests/data/test-read-ctf/test-PR26568-2.o.abi22
-rw-r--r--tests/data/test-read-ctf/test-PR27700.abi21
-rw-r--r--tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi3
-rw-r--r--tests/data/test-read-ctf/test-ambiguous-struct-B.c2
-rw-r--r--tests/data/test-read-ctf/test-ambiguous-struct-B.obin1344 -> 1344 bytes
-rw-r--r--tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi5
-rw-r--r--tests/data/test-read-ctf/test-anonymous-fields.o.abi18
-rw-r--r--tests/data/test-read-ctf/test-array-of-pointers.abi2
-rw-r--r--tests/data/test-read-ctf/test-callback.abi30
-rw-r--r--tests/data/test-read-ctf/test-callback2.abi2
-rw-r--r--tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi4
-rw-r--r--tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi4
-rw-r--r--tests/data/test-read-ctf/test-dynamic-array.o.abi2
-rw-r--r--tests/data/test-read-ctf/test-enum-ctf.o.abi24
-rw-r--r--tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi69
-rw-r--r--tests/data/test-read-ctf/test-enum-many.o.hash.abi6
-rw-r--r--tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi16
-rw-r--r--tests/data/test-read-ctf/test-enum-symbol.o.hash.abi3
-rw-r--r--tests/data/test-read-ctf/test-enum.o.abi6
-rw-r--r--tests/data/test-read-ctf/test-forward-type-decl.abi2
-rw-r--r--tests/data/test-read-ctf/test-functions-declaration.abi4
-rw-r--r--tests/data/test-read-ctf/test-list-struct.abi4
-rwxr-xr-xtests/data/test-read-ctf/test0bin16656 -> 16896 bytes
-rw-r--r--tests/data/test-read-ctf/test0.abi30
-rw-r--r--tests/data/test-read-ctf/test0.c6
-rw-r--r--tests/data/test-read-ctf/test0.hash.abi18
-rw-r--r--tests/data/test-read-ctf/test1.so.abi11
-rw-r--r--tests/data/test-read-ctf/test1.so.hash.abi7
-rw-r--r--tests/data/test-read-ctf/test2.so.abi8
-rw-r--r--tests/data/test-read-ctf/test2.so.hash.abi8
-rw-r--r--tests/data/test-read-ctf/test3.so.abi4
-rw-r--r--tests/data/test-read-ctf/test3.so.hash.abi4
-rw-r--r--tests/data/test-read-ctf/test4.so.abi6
-rw-r--r--tests/data/test-read-ctf/test4.so.hash.abi6
-rw-r--r--tests/data/test-read-ctf/test5.o.abi36
-rw-r--r--tests/data/test-read-ctf/test7.o.abi43
-rw-r--r--tests/data/test-read-ctf/test8.o.abi2
-rw-r--r--tests/data/test-read-ctf/test9.o.abi2
-rw-r--r--tests/test-read-ctf.cc20
-rw-r--r--tools/abidw.cc7
52 files changed, 1068 insertions, 367 deletions
diff --git a/include/abg-corpus.h b/include/abg-corpus.h
index 652a8294..4ea82f5b 100644
--- a/include/abg-corpus.h
+++ b/include/abg-corpus.h
@@ -44,10 +44,10 @@ public:
44 enum origin 44 enum origin
45 { 45 {
46 ARTIFICIAL_ORIGIN = 0, 46 ARTIFICIAL_ORIGIN = 0,
47 NATIVE_XML_ORIGIN, 47 NATIVE_XML_ORIGIN = 1,
48 DWARF_ORIGIN, 48 DWARF_ORIGIN = 1 << 1,
49 CTF_ORIGIN, 49 CTF_ORIGIN = 1 << 2,
50 LINUX_KERNEL_BINARY_ORIGIN 50 LINUX_KERNEL_BINARY_ORIGIN = 1 << 3
51 }; 51 };
52 52
53private: 53private:
@@ -280,6 +280,18 @@ public:
280 friend class corpus_group; 280 friend class corpus_group;
281};// end class corpus. 281};// end class corpus.
282 282
283corpus::origin
284operator|(corpus::origin l, corpus::origin r);
285
286corpus::origin
287operator|=(corpus::origin &l, corpus::origin r);
288
289corpus::origin
290operator&(corpus::origin l, corpus::origin r);
291
292corpus::origin
293operator&=(corpus::origin &l, corpus::origin r);
294
283/// Abstracts the building of the set of exported variables and 295/// Abstracts the building of the set of exported variables and
284/// functions. 296/// functions.
285/// 297///
diff --git a/include/abg-ctf-reader.h b/include/abg-ctf-reader.h
index 3343f0d8..ba7289aa 100644
--- a/include/abg-ctf-reader.h
+++ b/include/abg-ctf-reader.h
@@ -19,6 +19,8 @@
19#include "abg-suppression.h" 19#include "abg-suppression.h"
20#include "abg-elf-reader-common.h" 20#include "abg-elf-reader-common.h"
21 21
22#include "ctf-api.h"
23
22namespace abigail 24namespace abigail
23{ 25{
24namespace ctf_reader 26namespace ctf_reader
@@ -32,8 +34,22 @@ create_read_context(const std::string& elf_path,
32 ir::environment *env); 34 ir::environment *env);
33corpus_sptr 35corpus_sptr
34read_corpus(read_context *ctxt, elf_reader::status& status); 36read_corpus(read_context *ctxt, elf_reader::status& status);
37
35corpus_sptr 38corpus_sptr
36read_corpus(const read_context_sptr &ctxt, elf_reader::status &status); 39read_corpus(const read_context_sptr &ctxt, elf_reader::status &status);
40
41corpus_sptr
42read_and_add_corpus_to_group_from_elf(read_context*, corpus_group&, elf_reader::status&);
43
44void
45set_read_context_corpus_group(read_context& ctxt, corpus_group_sptr& group);
46
47void
48reset_read_context(read_context_sptr &ctxt,
49 const std::string& elf_path,
50 ir::environment* environment);
51std::string
52dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type);
37} // end namespace ctf_reader 53} // end namespace ctf_reader
38} // end namespace abigail 54} // end namespace abigail
39 55
diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h
index 68e54028..f7dccb24 100644
--- a/include/abg-tools-utils.h
+++ b/include/abg-tools-utils.h
@@ -311,7 +311,8 @@ build_corpus_group_from_kernel_dist_under(const string& root,
311 vector<string>& kabi_wl_paths, 311 vector<string>& kabi_wl_paths,
312 suppr::suppressions_type& supprs, 312 suppr::suppressions_type& supprs,
313 bool verbose, 313 bool verbose,
314 environment_sptr& env); 314 environment_sptr& env,
315 corpus::origin origin = corpus::DWARF_ORIGIN);
315}// end namespace tools_utils 316}// end namespace tools_utils
316 317
317/// A macro that expands to aborting the program when executed. 318/// A macro that expands to aborting the program when executed.
diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h
index 778e3365..d4b9ba32 100644
--- a/src/abg-corpus-priv.h
+++ b/src/abg-corpus-priv.h
@@ -670,7 +670,7 @@ struct corpus::priv
670 environment* env; 670 environment* env;
671 corpus_group* group; 671 corpus_group* group;
672 corpus::exported_decls_builder_sptr exported_decls_builder; 672 corpus::exported_decls_builder_sptr exported_decls_builder;
673 origin origin_; 673 corpus::origin origin_;
674 vector<string> regex_patterns_fns_to_suppress; 674 vector<string> regex_patterns_fns_to_suppress;
675 vector<string> regex_patterns_vars_to_suppress; 675 vector<string> regex_patterns_vars_to_suppress;
676 vector<string> regex_patterns_fns_to_keep; 676 vector<string> regex_patterns_fns_to_keep;
diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc
index a517f384..09047a80 100644
--- a/src/abg-corpus.cc
+++ b/src/abg-corpus.cc
@@ -1560,6 +1560,62 @@ corpus::get_exported_decls_builder() const
1560 return priv_->exported_decls_builder; 1560 return priv_->exported_decls_builder;
1561} 1561}
1562 1562
1563/// Bitwise | operator for the corpus::origin type.
1564///
1565/// @param l the left-hand side operand of the | operation.
1566///
1567/// @param r the right-hand side operand of the | operation.
1568///
1569/// @return the result of the operation.
1570corpus::origin
1571operator|(corpus::origin l, corpus::origin r)
1572{
1573 return static_cast<corpus::origin>
1574 (static_cast<uint32_t>(l) | static_cast<uint32_t>(r));
1575}
1576
1577/// Bitwise |= operator for the corpus::origin type.
1578///
1579/// @param l the left-hand side operand for the |= operation.
1580///
1581/// @param r the right-hand side operand for the |= operation.
1582///
1583/// @return the result of the operation.
1584corpus::origin
1585operator|=(corpus::origin &l, corpus::origin r)
1586{
1587 l = l | r;
1588 return l;
1589}
1590
1591/// Bitwise & operator for the corpus::origin type.
1592///
1593/// @param l the left-hand side operand of the & operation.
1594///
1595/// @param r the right-hand side operand of the & operation.
1596///
1597/// @return the result of the operation.
1598corpus::origin
1599operator&(corpus::origin l, corpus::origin r)
1600{
1601 return static_cast<corpus::origin>
1602 (static_cast<uint32_t>(l) & static_cast<uint32_t>(r));
1603}
1604
1605/// Bitwise &= operator for the corpus::origin type.
1606///
1607/// @param l the left-hand side operand of the &= operation.
1608///
1609/// @param r the right-hand side operand of the &= operation.
1610///
1611/// @return the result of the operation.
1612corpus::origin
1613operator&=(corpus::origin &l, corpus::origin r)
1614{
1615 l = l & r;
1616 return l;
1617}
1618
1563// </corpus stuff> 1619// </corpus stuff>
1564 1620
1565// <corpus_group stuff> 1621// <corpus_group stuff>
diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index 2c6839cb..95c81f0e 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -16,6 +16,8 @@
16#include <fcntl.h> /* For open(3) */ 16#include <fcntl.h> /* For open(3) */
17#include <iostream> 17#include <iostream>
18#include <memory> 18#include <memory>
19#include <map>
20#include <algorithm>
19 21
20#include "ctf-api.h" 22#include "ctf-api.h"
21 23
@@ -58,13 +60,19 @@ public:
58 60
59 /// A map associating CTF type ids with libabigail IR types. This 61 /// A map associating CTF type ids with libabigail IR types. This
60 /// is used to reuse already generated types. 62 /// is used to reuse already generated types.
61 unordered_map<ctf_id_t,type_base_sptr> types_map; 63 unordered_map<string,type_base_sptr> types_map;
64
65 /// A set associating unknown CTF type ids
66 std::set<ctf_id_t> unknown_types_set;
62 67
63 /// libelf handler for the ELF file from which we read the CTF data, 68 /// libelf handler for the ELF file from which we read the CTF data,
64 /// and the corresponding file descriptor. 69 /// and the corresponding file descriptor.
65 Elf *elf_handler; 70 Elf *elf_handler;
66 int elf_fd; 71 int elf_fd;
67 72
73 /// set when ELF is ET_EXEC
74 bool is_elf_exec;
75
68 /// The symtab read from the ELF file. 76 /// The symtab read from the ELF file.
69 symtab_reader::symtab_sptr symtab; 77 symtab_reader::symtab_sptr symtab;
70 78
@@ -74,28 +82,124 @@ public:
74 ctf_sect_t symtab_sect; 82 ctf_sect_t symtab_sect;
75 ctf_sect_t strtab_sect; 83 ctf_sect_t strtab_sect;
76 84
85 corpus_sptr cur_corpus_;
86 corpus_group_sptr cur_corpus_group_;
87
88 /// Getter of the current corpus group being constructed.
89 ///
90 /// @return current the current corpus being constructed, if any, or
91 /// nil.
92 const corpus_group_sptr
93 current_corpus_group() const
94 {return cur_corpus_group_;}
95
96 /// Test if there is a corpus group being built.
97 ///
98 /// @return if there is a corpus group being built, false otherwise.
99 bool
100 has_corpus_group() const
101 {return bool(cur_corpus_group_);}
102
103 /// Return the main corpus from the current corpus group, if any.
104 ///
105 /// @return the main corpus of the current corpus group, if any, nil
106 /// if no corpus group is being constructed.
107 corpus_sptr
108 main_corpus_from_current_group()
109 {
110 if (cur_corpus_group_)
111 return cur_corpus_group_->get_main_corpus();
112 return corpus_sptr();
113 }
114
115 /// Test if the current corpus being built is the main corpus of the
116 /// current corpus group.
117 ///
118 /// @return return true iff the current corpus being built is the
119 /// main corpus of the current corpus group.
120 bool
121 current_corpus_is_main_corpus_from_current_group()
122 {
123 corpus_sptr main_corpus = main_corpus_from_current_group();
124
125 if (main_corpus && main_corpus.get() == cur_corpus_.get())
126 return true;
127
128 return false;
129 }
130
131 /// Return true if the current corpus is part of a corpus group
132 /// being built and if it's not the main corpus of the group.
133 ///
134 /// For instance, this would return true if we are loading a linux
135 /// kernel *module* that is part of the current corpus group that is
136 /// being built. In this case, it means we should re-use types
137 /// coming from the "vmlinux" binary that is the main corpus of the
138 /// group.
139 ///
140 /// @return the corpus group the current corpus belongs to, if the
141 /// current corpus is part of a corpus group being built. Nil otherwise.
142 corpus_sptr
143 should_reuse_type_from_corpus_group()
144 {
145 if (has_corpus_group())
146 if (corpus_sptr main_corpus = main_corpus_from_current_group())
147 if (!current_corpus_is_main_corpus_from_current_group())
148 return current_corpus_group();
149
150 return corpus_sptr();
151 }
152
77 /// Associate a given CTF type ID with a given libabigail IR type. 153 /// Associate a given CTF type ID with a given libabigail IR type.
78 void add_type(ctf_id_t ctf_type, type_base_sptr type) 154 ///
155 /// @param dic the dictionnary the type belongs to.
156 ///
157 /// @param ctf_type the type ID.
158 ///
159 /// @param type the type to associate to the ID.
160 void
161 add_type(ctf_dict_t *dic, ctf_id_t ctf_type, type_base_sptr type)
162 {
163 string key = dic_type_key(dic, ctf_type);
164 types_map.insert(std::make_pair(key, type));
165 }
166
167 /// Insert a given CTF unknown type ID.
168 ///
169 /// @param ctf_type the unknown type ID to be added.
170 void
171 add_unknown_type(ctf_id_t ctf_type)
79 { 172 {
80 types_map.insert(std::make_pair(ctf_type, type)); 173 unknown_types_set.insert(ctf_type);
81 } 174 }
82 175
83 /// Lookup a given CTF type ID in the types map. 176 /// Lookup a given CTF type ID in the types map.
84 /// 177 ///
178 /// @param dic the dictionnary the type belongs to.
179 ///
85 /// @param ctf_type the type ID of the type to lookup. 180 /// @param ctf_type the type ID of the type to lookup.
86 type_base_sptr lookup_type(ctf_id_t ctf_type) 181 type_base_sptr
182 lookup_type(ctf_dict_t *dic, ctf_id_t ctf_type)
87 { 183 {
88 type_base_sptr result; 184 type_base_sptr result;
185 std::string key = dic_type_key(dic, ctf_type);
89 186
90 auto search = types_map.find(ctf_type); 187 auto search = types_map.find(key);
91 if (search != types_map.end()) 188 if (search != types_map.end())
92 result = search->second; 189 result = search->second;
93 190
94 return result; 191 return result;
95 } 192 }
96 193
194 /// Lookup a given CTF unknown type ID in the unknown set.
195 /// @param ctf_type the unknown type ID to lookup.
196 bool
197 lookup_unknown_type(ctf_id_t ctf_type)
198 { return unknown_types_set.find(ctf_type) != unknown_types_set.end(); }
199
97 /// Canonicalize all the types stored in the types map. 200 /// Canonicalize all the types stored in the types map.
98 void canonicalize_all_types(void) 201 void
202 canonicalize_all_types(void)
99 { 203 {
100 for (auto t = types_map.begin(); t != types_map.end(); t++) 204 for (auto t = types_map.begin(); t != types_map.end(); t++)
101 canonicalize (t->second); 205 canonicalize (t->second);
@@ -103,18 +207,42 @@ public:
103 207
104 /// Constructor. 208 /// Constructor.
105 /// 209 ///
210 /// ctfa data member can be used per courpus group.
211 ///
106 /// @param elf_path the path to the ELF file. 212 /// @param elf_path the path to the ELF file.
107 read_context(const string& elf_path, ir::environment *env) 213 read_context(const string& elf_path, ir::environment *env) :
214 ctfa(NULL)
215 {
216 initialize(elf_path, env);
217 }
218
219 /// Initializer of read_context.
220 ///
221 /// @param elf_path the path to the elf file the context is to be
222 /// used for.
223 ///
224 /// @param environment the environment used by the current context.
225 /// This environment contains resources needed by the reader and by
226 /// the types and declarations that are to be created later. Note
227 /// that ABI artifacts that are to be compared all need to be
228 /// created within the same environment.
229 ///
230 /// Please also note that the life time of this environment object
231 /// must be greater than the life time of the resulting @ref
232 /// read_context the context uses resources that are allocated in
233 /// the environment.
234 void initialize(const string& elf_path, ir::environment *env)
108 { 235 {
109 types_map.clear(); 236 types_map.clear();
110 filename = elf_path; 237 filename = elf_path;
111 ir_env = env; 238 ir_env = env;
112 elf_handler = NULL; 239 elf_handler = NULL;
113 elf_fd = -1; 240 elf_fd = -1;
114 ctfa = NULL; 241 is_elf_exec = false;
242 symtab.reset();
243 cur_corpus_group_.reset();
115 } 244 }
116 245
117 /// Destructor of the @ref read_context type.
118 ~read_context() 246 ~read_context()
119 { 247 {
120 ctf_close(ctfa); 248 ctf_close(ctfa);
@@ -153,13 +281,18 @@ process_ctf_typedef(read_context *ctxt,
153 return result; 281 return result;
154 282
155 const char *typedef_name = ctf_type_name_raw(ctf_dictionary, ctf_type); 283 const char *typedef_name = ctf_type_name_raw(ctf_dictionary, ctf_type);
284 if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group())
285 if (result = lookup_typedef_type(typedef_name, *corp))
286 return result;
287
156 type_base_sptr utype = lookup_type(ctxt, corp, tunit, 288 type_base_sptr utype = lookup_type(ctxt, corp, tunit,
157 ctf_dictionary, ctf_utype); 289 ctf_dictionary, ctf_utype);
158 290
159 if (!utype) 291 if (!utype)
160 return result; 292 return result;
161 293
162 result = dynamic_pointer_cast<typedef_decl>(ctxt->lookup_type(ctf_type)); 294 result = dynamic_pointer_cast<typedef_decl>(ctxt->lookup_type(ctf_dictionary,
295 ctf_type));
163 if (result) 296 if (result)
164 return result; 297 return result;
165 298
@@ -180,7 +313,7 @@ process_ctf_typedef(read_context *ctxt,
180 if (result) 313 if (result)
181 { 314 {
182 add_decl_to_scope(result, tunit->get_global_scope()); 315 add_decl_to_scope(result, tunit->get_global_scope());
183 ctxt->add_type(ctf_type, result); 316 ctxt->add_type(ctf_dictionary, ctf_type, result);
184 } 317 }
185 318
186 return result; 319 return result;
@@ -225,9 +358,20 @@ process_ctf_base_type(read_context *ctxt,
225 type_base_sptr void_type = ctxt->ir_env->get_void_type(); 358 type_base_sptr void_type = ctxt->ir_env->get_void_type();
226 decl_base_sptr type_declaration = get_type_declaration(void_type); 359 decl_base_sptr type_declaration = get_type_declaration(void_type);
227 result = is_type_decl(type_declaration); 360 result = is_type_decl(type_declaration);
361 canonicalize(result);
228 } 362 }
229 else 363 else
230 { 364 {
365 if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group())
366 {
367 string normalized_type_name = type_name;
368 integral_type int_type;
369 if (parse_integral_type(type_name, int_type))
370 normalized_type_name = int_type.to_string();
371 if (result = lookup_basic_type(normalized_type_name, *corp))
372 return result;
373 }
374
231 result = lookup_basic_type(type_name, *corp); 375 result = lookup_basic_type(type_name, *corp);
232 if (!result) 376 if (!result)
233 result.reset(new type_decl(ctxt->ir_env, 377 result.reset(new type_decl(ctxt->ir_env,
@@ -242,7 +386,7 @@ process_ctf_base_type(read_context *ctxt,
242 if (result) 386 if (result)
243 { 387 {
244 add_decl_to_scope(result, tunit->get_global_scope()); 388 add_decl_to_scope(result, tunit->get_global_scope());
245 ctxt->add_type(ctf_type, result); 389 ctxt->add_type(ctf_dictionary, ctf_type, result);
246 } 390 }
247 391
248 return result; 392 return result;
@@ -303,7 +447,8 @@ process_ctf_function_type(read_context *ctxt,
303 function_parms.push_back(parm); 447 function_parms.push_back(parm);
304 } 448 }
305 449
306 result = dynamic_pointer_cast<function_type>(ctxt->lookup_type(ctf_type)); 450 result = dynamic_pointer_cast<function_type>(ctxt->lookup_type(ctf_dictionary,
451 ctf_type));
307 if (result) 452 if (result)
308 return result; 453 return result;
309 454
@@ -319,7 +464,7 @@ process_ctf_function_type(read_context *ctxt,
319 result->set_is_artificial(true); 464 result->set_is_artificial(true);
320 decl_base_sptr function_type_decl = get_type_declaration(result); 465 decl_base_sptr function_type_decl = get_type_declaration(result);
321 add_decl_to_scope(function_type_decl, tunit->get_global_scope()); 466 add_decl_to_scope(function_type_decl, tunit->get_global_scope());
322 ctxt->add_type(ctf_type, result); 467 ctxt->add_type(ctf_dictionary, ctf_type, result);
323 } 468 }
324 469
325 return result; 470 return result;
@@ -419,6 +564,11 @@ process_ctf_forward_type(read_context *ctxt,
419 } 564 }
420 else 565 else
421 { 566 {
567 if (!type_is_anonymous)
568 if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group())
569 if (result = lookup_class_type(type_name, *corp))
570 return is_type(result);
571
422 class_decl_sptr 572 class_decl_sptr
423 struct_fwd(new class_decl(ctxt->ir_env, type_name, 573 struct_fwd(new class_decl(ctxt->ir_env, type_name,
424 /*alignment=*/0, /*size=*/0, 574 /*alignment=*/0, /*size=*/0,
@@ -434,7 +584,7 @@ process_ctf_forward_type(read_context *ctxt,
434 return is_type(result); 584 return is_type(result);
435 585
436 add_decl_to_scope(result, tunit->get_global_scope()); 586 add_decl_to_scope(result, tunit->get_global_scope());
437 ctxt->add_type(ctf_type, is_type(result)); 587 ctxt->add_type(ctf_dictionary, ctf_type, is_type(result));
438 588
439 return is_type(result); 589 return is_type(result);
440} 590}
@@ -458,9 +608,14 @@ process_ctf_struct_type(read_context *ctxt,
458{ 608{
459 class_decl_sptr result; 609 class_decl_sptr result;
460 std::string struct_type_name = ctf_type_name_raw(ctf_dictionary, 610 std::string struct_type_name = ctf_type_name_raw(ctf_dictionary,
461 ctf_type); 611 ctf_type);
462 bool struct_type_is_anonymous = (struct_type_name == ""); 612 bool struct_type_is_anonymous = (struct_type_name == "");
463 613
614 if (!struct_type_is_anonymous)
615 if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group())
616 if (result = lookup_class_type(struct_type_name, *corp))
617 return result;
618
464 /* The libabigail IR encodes C struct types in `class' IR nodes. */ 619 /* The libabigail IR encodes C struct types in `class' IR nodes. */
465 result.reset(new class_decl(ctxt->ir_env, 620 result.reset(new class_decl(ctxt->ir_env,
466 struct_type_name, 621 struct_type_name,
@@ -479,7 +634,7 @@ process_ctf_struct_type(read_context *ctxt,
479 at this point even if the members haven't been added to the IR 634 at this point even if the members haven't been added to the IR
480 node yet. */ 635 node yet. */
481 add_decl_to_scope(result, tunit->get_global_scope()); 636 add_decl_to_scope(result, tunit->get_global_scope());
482 ctxt->add_type(ctf_type, result); 637 ctxt->add_type(ctf_dictionary, ctf_type, result);
483 638
484 /* Now add the struct members as specified in the CTF type description. 639 /* Now add the struct members as specified in the CTF type description.
485 This is C, so named types can only be defined in the global 640 This is C, so named types can only be defined in the global
@@ -512,6 +667,11 @@ process_ctf_union_type(read_context *ctxt,
512 ctf_type); 667 ctf_type);
513 bool union_type_is_anonymous = (union_type_name == ""); 668 bool union_type_is_anonymous = (union_type_name == "");
514 669
670 if (!union_type_is_anonymous)
671 if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group())
672 if (result = lookup_union_type(union_type_name, *corp))
673 return result;
674
515 /* Create the corresponding libabigail union IR node. */ 675 /* Create the corresponding libabigail union IR node. */
516 result.reset(new union_decl(ctxt->ir_env, 676 result.reset(new union_decl(ctxt->ir_env,
517 union_type_name, 677 union_type_name,
@@ -528,7 +688,7 @@ process_ctf_union_type(read_context *ctxt,
528 at this point even if the members haven't been added to the IR 688 at this point even if the members haven't been added to the IR
529 node yet. */ 689 node yet. */
530 add_decl_to_scope(result, tunit->get_global_scope()); 690 add_decl_to_scope(result, tunit->get_global_scope());
531 ctxt->add_type(ctf_type, result); 691 ctxt->add_type(ctf_dictionary, ctf_type, result);
532 692
533 /* Now add the union members as specified in the CTF type description. 693 /* Now add the union members as specified in the CTF type description.
534 This is C, so named types can only be defined in the global 694 This is C, so named types can only be defined in the global
@@ -584,7 +744,8 @@ process_ctf_array_type(read_context *ctxt,
584 if (!index_type) 744 if (!index_type)
585 return result; 745 return result;
586 746
587 result = dynamic_pointer_cast<array_type_def>(ctxt->lookup_type(ctf_type)); 747 result = dynamic_pointer_cast<array_type_def>(ctxt->lookup_type(ctf_dictionary,
748 ctf_type));
588 if (result) 749 if (result)
589 return result; 750 return result;
590 751
@@ -623,7 +784,7 @@ process_ctf_array_type(read_context *ctxt,
623 { 784 {
624 decl_base_sptr array_type_decl = get_type_declaration(result); 785 decl_base_sptr array_type_decl = get_type_declaration(result);
625 add_decl_to_scope(array_type_decl, tunit->get_global_scope()); 786 add_decl_to_scope(array_type_decl, tunit->get_global_scope());
626 ctxt->add_type(ctf_type, result); 787 ctxt->add_type(ctf_dictionary, ctf_type, result);
627 } 788 }
628 789
629 return result; 790 return result;
@@ -652,6 +813,11 @@ process_ctf_qualified_type(read_context *ctxt,
652 if (!utype) 813 if (!utype)
653 return result; 814 return result;
654 815
816 result = dynamic_pointer_cast<type_base>(ctxt->lookup_type(ctf_dictionary,
817 ctf_type));
818 if (result)
819 return result;
820
655 qualified_type_def::CV qualifiers = qualified_type_def::CV_NONE; 821 qualified_type_def::CV qualifiers = qualified_type_def::CV_NONE;
656 if (type_kind == CTF_K_CONST) 822 if (type_kind == CTF_K_CONST)
657 qualifiers |= qualified_type_def::CV_CONST; 823 qualifiers |= qualified_type_def::CV_CONST;
@@ -668,7 +834,7 @@ process_ctf_qualified_type(read_context *ctxt,
668 { 834 {
669 decl_base_sptr qualified_type_decl = get_type_declaration(result); 835 decl_base_sptr qualified_type_decl = get_type_declaration(result);
670 add_decl_to_scope(qualified_type_decl, tunit->get_global_scope()); 836 add_decl_to_scope(qualified_type_decl, tunit->get_global_scope());
671 ctxt->add_type(ctf_type, result); 837 ctxt->add_type(ctf_dictionary, ctf_type, result);
672 } 838 }
673 839
674 return result; 840 return result;
@@ -702,7 +868,8 @@ process_ctf_pointer_type(read_context *ctxt,
702 if (!target_type) 868 if (!target_type)
703 return result; 869 return result;
704 870
705 result = dynamic_pointer_cast<pointer_type_def>(ctxt->lookup_type(ctf_type)); 871 result = dynamic_pointer_cast<pointer_type_def>(ctxt->lookup_type(ctf_dictionary,
872 ctf_type));
706 if (result) 873 if (result)
707 return result; 874 return result;
708 875
@@ -713,7 +880,7 @@ process_ctf_pointer_type(read_context *ctxt,
713 if (result) 880 if (result)
714 { 881 {
715 add_decl_to_scope(result, tunit->get_global_scope()); 882 add_decl_to_scope(result, tunit->get_global_scope());
716 ctxt->add_type(ctf_type, result); 883 ctxt->add_type(ctf_dictionary, ctf_type, result);
717 } 884 }
718 885
719 return result; 886 return result;
@@ -736,6 +903,12 @@ process_ctf_enum_type(read_context *ctxt,
736 ctf_id_t ctf_type) 903 ctf_id_t ctf_type)
737{ 904{
738 enum_type_decl_sptr result; 905 enum_type_decl_sptr result;
906 std::string enum_name = ctf_type_name_raw(ctf_dictionary, ctf_type);
907
908 if (!enum_name.empty())
909 if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group())
910 if (result = lookup_enum_type(enum_name, *corp))
911 return result;
739 912
740 /* Build a signed integral type for the type of the enumerators, aka 913 /* Build a signed integral type for the type of the enumerators, aka
741 the underlying type. The size of the enumerators in bytes is 914 the underlying type. The size of the enumerators in bytes is
@@ -769,13 +942,12 @@ process_ctf_enum_type(read_context *ctxt,
769 return result; 942 return result;
770 } 943 }
771 944
772 const char *enum_name = ctf_type_name_raw(ctf_dictionary, ctf_type); 945 result.reset(new enum_type_decl(enum_name.c_str(), location(),
773 result.reset(new enum_type_decl(enum_name, location(), 946 utype, enms, enum_name.c_str()));
774 utype, enms, enum_name));
775 if (result) 947 if (result)
776 { 948 {
777 add_decl_to_scope(result, tunit->get_global_scope()); 949 add_decl_to_scope(result, tunit->get_global_scope());
778 ctxt->add_type(ctf_type, result); 950 ctxt->add_type(ctf_dictionary, ctf_type, result);
779 } 951 }
780 952
781 return result; 953 return result;
@@ -804,7 +976,10 @@ process_ctf_type(read_context *ctxt,
804 int type_kind = ctf_type_kind(ctf_dictionary, ctf_type); 976 int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
805 type_base_sptr result; 977 type_base_sptr result;
806 978
807 if ((result = ctxt->lookup_type(ctf_type))) 979 if (ctxt->lookup_unknown_type(ctf_type))
980 return nullptr;
981
982 if ((result = ctxt->lookup_type(ctf_dictionary, ctf_type)))
808 return result; 983 return result;
809 984
810 switch (type_kind) 985 switch (type_kind)
@@ -889,7 +1064,10 @@ process_ctf_type(read_context *ctxt,
889 } 1064 }
890 1065
891 if (!result) 1066 if (!result)
892 fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type); 1067 {
1068 fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type);
1069 ctxt->add_unknown_type(ctf_type);
1070 }
893 1071
894 return result; 1072 return result;
895} 1073}
@@ -913,7 +1091,7 @@ lookup_type(read_context *ctxt, corpus_sptr corp,
913 translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, 1091 translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary,
914 ctf_id_t ctf_type) 1092 ctf_id_t ctf_type)
915{ 1093{
916 type_base_sptr result = ctxt->lookup_type(ctf_type); 1094 type_base_sptr result = ctxt->lookup_type(ctf_dictionary, ctf_type);
917 1095
918 if (!result) 1096 if (!result)
919 result = process_ctf_type(ctxt, corp, tunit, ctf_dictionary, ctf_type); 1097 result = process_ctf_type(ctxt, corp, tunit, ctf_dictionary, ctf_type);
@@ -921,8 +1099,8 @@ lookup_type(read_context *ctxt, corpus_sptr corp,
921} 1099}
922 1100
923/// Process a CTF archive and create libabigail IR for the types, 1101/// Process a CTF archive and create libabigail IR for the types,
924/// variables and function declarations found in the archive. The IR 1102/// variables and function declarations found in the archive, iterating
925/// is added to the given corpus. 1103/// over public symbols. The IR is added to the given corpus.
926/// 1104///
927/// @param ctxt the read context containing the CTF archive to 1105/// @param ctxt the read context containing the CTF archive to
928/// process. 1106/// process.
@@ -937,43 +1115,49 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
937 ir_translation_unit->set_language(translation_unit::LANG_C); 1115 ir_translation_unit->set_language(translation_unit::LANG_C);
938 corp->add(ir_translation_unit); 1116 corp->add(ir_translation_unit);
939 1117
940 /* Iterate over the CTF dictionaries in the archive. */
941 int ctf_err; 1118 int ctf_err;
942 ctf_dict_t *ctf_dict; 1119 ctf_dict_t *ctf_dict;
943 ctf_next_t *dict_next = NULL; 1120 const auto symtab = ctxt->symtab;
944 const char *archive_name; 1121 symtab_reader::symtab_filter filter = symtab->make_filter();
1122 filter.set_public_symbols();
1123 std::string dict_name;
945 1124
946 while ((ctf_dict = ctf_archive_next(ctxt->ctfa, &dict_next, &archive_name, 1125 if (corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
947 0 /* skip_parent */, &ctf_err)) != NULL)
948 { 1126 {
949 /* Iterate over the CTF types stored in this archive. */ 1127 tools_utils::base_name(ctxt->filename, dict_name);
950 ctf_id_t ctf_type;
951 int type_flag;
952 ctf_next_t *type_next = NULL;
953 1128
954 while ((ctf_type = ctf_type_next(ctf_dict, &type_next, &type_flag, 1129 if (dict_name != "vmlinux")
955 1 /* want_hidden */)) != CTF_ERR) 1130 // remove .ko suffix
956 { 1131 dict_name.erase(dict_name.length() - 3, 3);
957 process_ctf_type(ctxt, corp, ir_translation_unit, 1132
958 ctf_dict, ctf_type); 1133 std::replace(dict_name.begin(), dict_name.end(), '-', '_');
959 } 1134 }
960 if (ctf_errno(ctf_dict) != ECTF_NEXT_END)
961 fprintf(stderr, "ERROR from ctf_type_next\n");
962 1135
963 /* Canonicalize all the types generated above. This must be 1136 if ((ctf_dict = ctf_dict_open(ctxt->ctfa,
964 done "a posteriori" because the processing of types may 1137 dict_name.empty() ? NULL : dict_name.c_str(),
965 require other related types to not be already 1138 &ctf_err)) == NULL)
966 canonicalized. */ 1139 {
967 ctxt->canonicalize_all_types(); 1140 fprintf(stderr, "ERROR dictionary not found\n");
1141 abort();
1142 }
968 1143
969 /* Iterate over the CTF variables stored in this archive. */ 1144 for (const auto& symbol : symtab_reader::filtered_symtab(*symtab, filter))
1145 {
1146 std::string sym_name = symbol->get_name();
970 ctf_id_t ctf_var_type; 1147 ctf_id_t ctf_var_type;
971 ctf_next_t *var_next = NULL;
972 const char *var_name;
973 1148
974 while ((ctf_var_type = ctf_variable_next(ctf_dict, &var_next, &var_name)) 1149 if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
975 != CTF_ERR) 1150 || ctxt->is_elf_exec)
1151 ctf_var_type= ctf_lookup_variable (ctf_dict, sym_name.c_str());
1152 else
1153 ctf_var_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str());
1154
1155 if (ctf_var_type == (ctf_id_t) -1)
1156 continue;
1157
1158 if (ctf_type_kind (ctf_dict, ctf_var_type) != CTF_K_FUNCTION)
976 { 1159 {
1160 const char *var_name = sym_name.c_str();
977 type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit, 1161 type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit,
978 ctf_dict, ctf_var_type); 1162 ctf_dict, ctf_var_type);
979 if (!var_type) 1163 if (!var_type)
@@ -986,50 +1170,38 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp)
986 location(), 1170 location(),
987 var_name)); 1171 var_name));
988 1172
1173 var_declaration->set_symbol(symbol);
989 add_decl_to_scope(var_declaration, 1174 add_decl_to_scope(var_declaration,
990 ir_translation_unit->get_global_scope()); 1175 ir_translation_unit->get_global_scope());
991 } 1176 }
992 if (ctf_errno(ctf_dict) != ECTF_NEXT_END) 1177 else
993 fprintf(stderr, "ERROR from ctf_variable_next\n"); 1178 {
1179 const char *func_name = sym_name.c_str();
1180 ctf_id_t ctf_sym = ctf_var_type;
1181 type_base_sptr func_type = lookup_type(ctxt, corp, ir_translation_unit,
1182 ctf_dict, ctf_sym);
1183 if (!func_type)
1184 /* Ignore function if its type can't be sorted out. */
1185 continue;
994 1186
995 /* Iterate over the CTF functions stored in this archive. */ 1187 function_decl_sptr func_declaration;
996 ctf_next_t *func_next = NULL; 1188 func_declaration.reset(new function_decl(func_name,
997 const char *func_name = NULL; 1189 func_type,
998 ctf_id_t ctf_sym; 1190 0 /* is_inline */,
1191 location()));
999 1192
1000 while ((ctf_sym = ctf_symbol_next(ctf_dict, &func_next, &func_name, 1193 func_declaration->set_symbol(symbol);
1001 1 /* functions symbols only */) != CTF_ERR)) 1194 add_decl_to_scope(func_declaration,
1002 { 1195 ir_translation_unit->get_global_scope());
1003 ctf_id_t ctf_func_type = ctf_lookup_by_name(ctf_dict, func_name); 1196 }
1004 type_base_sptr func_type = lookup_type(ctxt, corp, ir_translation_unit,
1005 ctf_dict, ctf_func_type);
1006 if (!func_type)
1007 /* Ignore function if its type can't be sorted out. */
1008 continue;
1009
1010 elf_symbols func_elf_symbols = ctxt->symtab->lookup_symbol(func_name);
1011 if (func_elf_symbols.size() == 0
1012 || func_elf_symbols[0]->get_binding() == elf_symbol::LOCAL_BINDING)
1013 /* Ignore local functions. */
1014 continue;
1015
1016 function_decl_sptr func_declaration;
1017 func_declaration.reset(new function_decl(func_name,
1018 func_type,
1019 0 /* is_inline */,
1020 location()));
1021
1022 add_decl_to_scope(func_declaration,
1023 ir_translation_unit->get_global_scope());
1024 }
1025 if (ctf_errno(ctf_dict) != ECTF_NEXT_END)
1026 fprintf(stderr, "ERROR from ctf_symbol_next\n");
1027
1028 ctf_dict_close(ctf_dict);
1029 } 1197 }
1030 if (ctf_err != ECTF_NEXT_END)
1031 fprintf(stderr, "ERROR from ctf_archive_next\n");
1032 1198
1199 ctf_dict_close(ctf_dict);
1200 /* Canonicalize all the types generated above. This must be
1201 done "a posteriori" because the processing of types may
1202 require other related types to not be already
1203 canonicalized. */
1204 ctxt->canonicalize_all_types();
1033} 1205}
1034 1206
1035/// Open the ELF file described by the given read context. 1207/// Open the ELF file described by the given read context.
@@ -1113,6 +1285,7 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp)
1113 /* Set the ELF architecture. */ 1285 /* Set the ELF architecture. */
1114 GElf_Ehdr eh_mem; 1286 GElf_Ehdr eh_mem;
1115 GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem); 1287 GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem);
1288 ctxt->is_elf_exec = (ehdr->e_type == ET_EXEC);
1116 corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine)); 1289 corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine));
1117 1290
1118 /* Read the symtab from the ELF file and set it in the corpus. */ 1291 /* Read the symtab from the ELF file and set it in the corpus. */
@@ -1121,6 +1294,9 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp)
1121 0 /* No suppressions. */); 1294 0 /* No suppressions. */);
1122 corp->set_symtab(ctxt->symtab); 1295 corp->set_symtab(ctxt->symtab);
1123 1296
1297 if (corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
1298 return 1;
1299
1124 /* Get the raw ELF section contents for libctf. */ 1300 /* Get the raw ELF section contents for libctf. */
1125 Elf_Scn *ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS); 1301 Elf_Scn *ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS);
1126 Elf_Scn *symtab_scn = elf_helpers::find_symbol_table_section(ctxt->elf_handler); 1302 Elf_Scn *symtab_scn = elf_helpers::find_symbol_table_section(ctxt->elf_handler);
@@ -1167,6 +1343,7 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
1167 corpus_sptr corp 1343 corpus_sptr corp
1168 = std::make_shared<corpus>(ctxt->ir_env, ctxt->filename); 1344 = std::make_shared<corpus>(ctxt->ir_env, ctxt->filename);
1169 1345
1346 ctxt->cur_corpus_ = corp;
1170 /* Be optimist. */ 1347 /* Be optimist. */
1171 status = elf_reader::STATUS_OK; 1348 status = elf_reader::STATUS_OK;
1172 1349
@@ -1177,25 +1354,52 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
1177 return corp; 1354 return corp;
1178 } 1355 }
1179 1356
1180 /* Set some properties of the corpus first. */ 1357 bool is_linux_kernel = elf_helpers::is_linux_kernel(ctxt->elf_handler);
1181 corp->set_origin(corpus::CTF_ORIGIN); 1358 corpus::origin origin = corpus::CTF_ORIGIN;
1182 if (!slurp_elf_info(ctxt, corp)) 1359
1360 if (is_linux_kernel)
1361 origin |= corpus::LINUX_KERNEL_BINARY_ORIGIN;
1362 corp->set_origin(origin);
1363
1364 if (ctxt->cur_corpus_group_)
1365 ctxt->cur_corpus_group_->add_corpus(ctxt->cur_corpus_);
1366
1367 if (!slurp_elf_info(ctxt, corp) && !is_linux_kernel)
1183 { 1368 {
1184 status = elf_reader::STATUS_NO_SYMBOLS_FOUND; 1369 status = elf_reader::STATUS_NO_SYMBOLS_FOUND;
1185 return corp; 1370 return corp;
1186 } 1371 }
1187 1372
1188 /* Build the ctfa from the contents of the relevant ELF sections,
1189 and process the CTF archive in the read context, if any.
1190 Information about the types, variables, functions, etc contained
1191 in the archive are added to the given corpus. */
1192 int errp; 1373 int errp;
1193 ctxt->ctfa = ctf_arc_bufopen(&ctxt->ctf_sect, &ctxt->symtab_sect, 1374 if (corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
1194 &ctxt->strtab_sect, &errp); 1375 {
1376 std::string filename;
1377 if (tools_utils::base_name(ctxt->filename, filename)
1378 && filename == "vmlinux")
1379 {
1380 std::string vmlinux_ctfa_path = ctxt->filename + ".ctfa";
1381 ctxt->ctfa = ctf_arc_open(vmlinux_ctfa_path.c_str(), &errp);
1382 }
1383 }
1384 else
1385 /* Build the ctfa from the contents of the relevant ELF sections,
1386 and process the CTF archive in the read context, if any.
1387 Information about the types, variables, functions, etc contained
1388 in the archive are added to the given corpus. */
1389 ctxt->ctfa = ctf_arc_bufopen(&ctxt->ctf_sect, &ctxt->symtab_sect,
1390 &ctxt->strtab_sect, &errp);
1391
1392 ctxt->ir_env->canonicalization_is_done(false);
1195 if (ctxt->ctfa == NULL) 1393 if (ctxt->ctfa == NULL)
1196 status = elf_reader::STATUS_DEBUG_INFO_NOT_FOUND; 1394 status = elf_reader::STATUS_DEBUG_INFO_NOT_FOUND;
1197 else 1395 else
1198 process_ctf_archive(ctxt, corp); 1396 {
1397 process_ctf_archive(ctxt, corp);
1398 ctxt->cur_corpus_->sort_functions();
1399 ctxt->cur_corpus_->sort_variables();
1400 }
1401
1402 ctxt->ir_env->canonicalization_is_done(true);
1199 1403
1200 /* Cleanup and return. */ 1404 /* Cleanup and return. */
1201 close_elf_handler(ctxt); 1405 close_elf_handler(ctxt);
@@ -1216,5 +1420,94 @@ corpus_sptr
1216read_corpus(const read_context_sptr &ctxt, elf_reader::status &status) 1420read_corpus(const read_context_sptr &ctxt, elf_reader::status &status)
1217{return read_corpus(ctxt.get(), status);} 1421{return read_corpus(ctxt.get(), status);}
1218 1422
1423/// Set the @ref corpus_group being created to the current read context.
1424///
1425/// @param ctxt the read_context to consider.
1426///
1427/// @param group the @ref corpus_group to set.
1428void
1429set_read_context_corpus_group(read_context& ctxt,
1430 corpus_group_sptr& group)
1431{
1432 ctxt.cur_corpus_group_ = group;
1433}
1434
1435/// Read a corpus and add it to a given @ref corpus_group.
1436///
1437/// @param ctxt the reading context to consider.
1438///
1439/// @param group the @ref corpus_group to add the new corpus to.
1440///
1441/// @param status output parameter. The status of the read. It is set
1442/// by this function upon its completion.
1443corpus_sptr
1444read_and_add_corpus_to_group_from_elf(read_context* ctxt,
1445 corpus_group& group,
1446 elf_reader::status& status)
1447{
1448 corpus_sptr result;
1449 corpus_sptr corp = read_corpus(ctxt, status);
1450 if (status & elf_reader::STATUS_OK)
1451 {
1452 if (!corp->get_group())
1453 group.add_corpus(corp);
1454 result = corp;
1455 }
1456
1457 return result;
1458}
1459
1460/// Re-initialize a read_context so that it can re-used to read
1461/// another binary.
1462///
1463/// @param ctxt the context to re-initialize.
1464///
1465/// @param elf_path the path to the elf file the context is to be used
1466/// for.
1467///
1468/// @param environment the environment used by the current context.
1469/// This environment contains resources needed by the reader and by
1470/// the types and declarations that are to be created later. Note
1471/// that ABI artifacts that are to be compared all need to be created
1472/// within the same environment.
1473///
1474/// Please also note that the life time of this environment object
1475/// must be greater than the life time of the resulting @ref
1476/// read_context the context uses resources that are allocated in the
1477/// environment.
1478void
1479reset_read_context(read_context_sptr &ctxt,
1480 const std::string& elf_path,
1481 ir::environment* environment)
1482{
1483 if (ctxt)
1484 ctxt->initialize(elf_path, environment);
1485}
1486
1487/// Returns a key to be use in types_map dict conformed by
1488/// dictionary id and the CTF type id for a given type.
1489///
1490/// CTF id types are unique by child dictionary, but CTF id
1491/// types in parent dictionary are unique across the all
1492/// dictionaries in the CTF archive, to differentiate
1493/// one each other this member function relies in
1494/// ctf_type_isparent function.
1495///
1496/// @param dic the pointer to CTF dictionary where the @p type
1497/// was found.
1498///
1499/// @param type the id for given CTF type.
1500std::string
1501dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type)
1502{
1503 std::stringstream key;
1504
1505 if (ctf_type_isparent (dic, ctf_type))
1506 key << std::hex << ctf_type;
1507 else
1508 key << std::hex << ctf_type << '-' << ctf_cuname(dic);
1509 return key.str();
1510}
1511
1219} // End of namespace ctf_reader 1512} // End of namespace ctf_reader
1220} // End of namespace abigail 1513} // End of namespace abigail
diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index dc82cf3b..7bf2375d 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -14444,10 +14444,12 @@ read_debug_info_into_corpus(read_context& ctxt)
14444 // First set some mundane properties of the corpus gathered from 14444 // First set some mundane properties of the corpus gathered from
14445 // ELF. 14445 // ELF.
14446 ctxt.current_corpus()->set_path(ctxt.elf_path()); 14446 ctxt.current_corpus()->set_path(ctxt.elf_path());
14447
14448 corpus::origin origin = corpus::DWARF_ORIGIN;
14447 if (is_linux_kernel(ctxt.elf_handle())) 14449 if (is_linux_kernel(ctxt.elf_handle()))
14448 ctxt.current_corpus()->set_origin(corpus::LINUX_KERNEL_BINARY_ORIGIN); 14450 origin |= corpus::LINUX_KERNEL_BINARY_ORIGIN;
14449 else 14451 ctxt.current_corpus()->set_origin(origin);
14450 ctxt.current_corpus()->set_origin(corpus::DWARF_ORIGIN); 14452
14451 ctxt.current_corpus()->set_soname(ctxt.dt_soname()); 14453 ctxt.current_corpus()->set_soname(ctxt.dt_soname());
14452 ctxt.current_corpus()->set_needed(ctxt.dt_needed()); 14454 ctxt.current_corpus()->set_needed(ctxt.dt_needed());
14453 ctxt.current_corpus()->set_architecture_name(ctxt.elf_architecture()); 14455 ctxt.current_corpus()->set_architecture_name(ctxt.elf_architecture());
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 0ef5e8b2..4e907620 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -13498,7 +13498,7 @@ types_defined_same_linux_kernel_corpus_public(const type_base& t1,
13498 /// kernel corpus, let's move on. Otherwise bail out. 13498 /// kernel corpus, let's move on. Otherwise bail out.
13499 if (!(t1_corpus && t2_corpus 13499 if (!(t1_corpus && t2_corpus
13500 && t1_corpus == t2_corpus 13500 && t1_corpus == t2_corpus
13501 && (t1_corpus->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN) 13501 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
13502 && (is_class_or_union_type(&t1) 13502 && (is_class_or_union_type(&t1)
13503 || is_enum_type(&t1)))) 13503 || is_enum_type(&t1))))
13504 return false; 13504 return false;
diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc
index 1f0f6fa8..f30c3f1d 100644
--- a/src/abg-tools-utils.cc
+++ b/src/abg-tools-utils.cc
@@ -44,6 +44,9 @@
44#include <sstream> 44#include <sstream>
45 45
46#include "abg-dwarf-reader.h" 46#include "abg-dwarf-reader.h"
47#ifdef WITH_CTF
48#include "abg-ctf-reader.h"
49#endif
47#include "abg-internal.h" 50#include "abg-internal.h"
48#include "abg-regex.h" 51#include "abg-regex.h"
49 52
@@ -2486,6 +2489,223 @@ get_binary_paths_from_kernel_dist(const string& dist_root,
2486 module_paths); 2489 module_paths);
2487} 2490}
2488 2491
2492/// If the @ref origin is DWARF_ORIGIN it build a @ref corpus_group
2493/// made of vmlinux kernel file and the linux kernel modules found
2494/// under @p root directory and under its sub-directories, recursively.
2495///
2496/// @param origin the debug type information in vmlinux kernel and
2497/// the linux kernel modules to be used to build the corpora @p group.
2498///
2499/// @param the group @ref corpus_group to be built.
2500///
2501/// @param vmlinux the path to the vmlinux binary.
2502///
2503/// @param modules a vector with the paths to the linux kernel
2504/// modules.
2505///
2506/// @param root the path of the directory under which the kernel
2507/// kernel modules were found.
2508///
2509/// @param di_root the directory in aboslute path which debug
2510/// info is to be found for binaries under director @p root
2511///
2512/// @param suppr_paths the paths to the suppression specifications to
2513/// apply while loading the binaries.
2514///
2515/// @param kabi_wl_path the paths to the kabi whitelist files to take
2516/// into account while loading the binaries.
2517///
2518/// @param supprs the suppressions resulting from parsing the
2519/// suppression specifications at @p suppr_paths. This is set by this
2520/// function.
2521///
2522/// @param verbose true if the function has to emit some verbose
2523/// messages.
2524///
2525/// @param t time to trace time spent in each step.
2526///
2527/// @param env the environment to create the corpus_group in.
2528static void
2529maybe_load_vmlinux_dwarf_corpus(corpus::origin origin,
2530 corpus_group_sptr& group,
2531 const string& vmlinux,
2532 vector<string>& modules,
2533 const string& root,
2534 vector<char**>& di_roots,
2535 vector<string>& suppr_paths,
2536 vector<string>& kabi_wl_paths,
2537 suppressions_type& supprs,
2538 bool verbose,
2539 timer& t,
2540 environment_sptr& env)
2541{
2542 if (!(origin & corpus::DWARF_ORIGIN))
2543 return;
2544
2545 abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
2546 dwarf_reader::read_context_sptr ctxt;
2547 ctxt =
2548 dwarf_reader::create_read_context(vmlinux, di_roots, env.get(),
2549 /*read_all_types=*/false,
2550 /*linux_kernel_mode=*/true);
2551 dwarf_reader::set_do_log(*ctxt, verbose);
2552
2553 t.start();
2554 load_generate_apply_suppressions(*ctxt, suppr_paths,
2555 kabi_wl_paths, supprs);
2556 t.stop();
2557
2558 if (verbose)
2559 std::cerr << "loaded white list and generated suppr spec in: "
2560 << t
2561 << "\n";
2562
2563 group.reset(new corpus_group(env.get(), root));
2564
2565 set_read_context_corpus_group(*ctxt, group);
2566
2567 if (verbose)
2568 std::cerr << "reading kernel binary '"
2569 << vmlinux << "' ...\n" << std::flush;
2570
2571 // Read the vmlinux corpus and add it to the group.
2572 t.start();
2573 read_and_add_corpus_to_group_from_elf(*ctxt, *group, status);
2574 t.stop();
2575
2576 if (verbose)
2577 std::cerr << vmlinux
2578 << " reading DONE:"
2579 << t << "\n";
2580
2581 if (group->is_empty())
2582 return;
2583
2584 // Now add the corpora of the modules to the corpus group.
2585 int total_nb_modules = modules.size();
2586 int cur_module_index = 1;
2587 for (vector<string>::const_iterator m = modules.begin();
2588 m != modules.end();
2589 ++m, ++cur_module_index)
2590 {
2591 if (verbose)
2592 std::cerr << "reading module '"
2593 << *m << "' ("
2594 << cur_module_index
2595 << "/" << total_nb_modules
2596 << ") ... " << std::flush;
2597
2598 reset_read_context(ctxt, *m, di_roots, env.get(),
2599 /*read_all_types=*/false,
2600 /*linux_kernel_mode=*/true);
2601
2602 load_generate_apply_suppressions(*ctxt, suppr_paths,
2603 kabi_wl_paths, supprs);
2604
2605 set_read_context_corpus_group(*ctxt, group);
2606
2607 t.start();
2608 read_and_add_corpus_to_group_from_elf(*ctxt,
2609 *group, status);
2610 t.stop();
2611 if (verbose)
2612 std::cerr << "module '"
2613 << *m
2614 << "' reading DONE: "
2615 << t << "\n";
2616 }
2617}
2618
2619/// If the @ref origin is CTF_ORIGIN it build a @ref corpus_group
2620/// made of vmlinux kernel file and the linux kernel modules found
2621/// under @p root directory and under its sub-directories, recursively.
2622///
2623/// @param origin the debug type information in vmlinux kernel and
2624/// the linux kernel modules to be used to build the corpora @p group.
2625///
2626/// @param group the @ref corpus_group to be built.
2627///
2628/// @param vmlinux the path to the vmlinux binary.
2629///
2630/// @param modules a vector with the paths to the linux kernel
2631/// modules.
2632///
2633/// @param root the path of the directory under which the kernel
2634/// kernel modules were found.
2635///
2636/// @param verbose true if the function has to emit some verbose
2637/// messages.
2638///
2639/// @param t time to trace time spent in each step.
2640///
2641/// @param env the environment to create the corpus_group in.
2642#ifdef WITH_CTF
2643static void
2644maybe_load_vmlinux_ctf_corpus(corpus::origin origin,
2645 corpus_group_sptr& group,
2646 const string& vmlinux,
2647 vector<string>& modules,
2648 const string& root,
2649 bool verbose,
2650 timer& t,
2651 environment_sptr& env)
2652{
2653 if (!(origin & corpus::CTF_ORIGIN))
2654 return;
2655
2656 abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
2657 ctf_reader::read_context_sptr ctxt;
2658 ctxt = ctf_reader::create_read_context(vmlinux, env.get());
2659 group.reset(new corpus_group(env.get(), root));
2660 set_read_context_corpus_group(*ctxt, group);
2661
2662 if (verbose)
2663 std::cerr << "reading kernel binary '"
2664 << vmlinux << "' ...\n" << std::flush;
2665
2666 // Read the vmlinux corpus and add it to the group.
2667 t.start();
2668 read_and_add_corpus_to_group_from_elf(ctxt.get(), *group, status);
2669 t.stop();
2670
2671 if (verbose)
2672 std::cerr << vmlinux
2673 << " reading DONE:"
2674 << t << "\n";
2675
2676 if (group->is_empty())
2677 return;
2678
2679 // Now add the corpora of the modules to the corpus group.
2680 int total_nb_modules = modules.size();
2681 int cur_module_index = 1;
2682 for (vector<string>::const_iterator m = modules.begin();
2683 m != modules.end();
2684 ++m, ++cur_module_index)
2685 {
2686 if (verbose)
2687 std::cerr << "reading module '"
2688 << *m << "' ("
2689 << cur_module_index
2690 << "/" << total_nb_modules
2691 << ") ... " << std::flush;
2692
2693 reset_read_context(ctxt, *m, env.get());
2694 set_read_context_corpus_group(*ctxt, group);
2695
2696 t.start();
2697 read_and_add_corpus_to_group_from_elf(ctxt.get(),
2698 *group, status);
2699 t.stop();
2700 if (verbose)
2701 std::cerr << "module '"
2702 << *m
2703 << "' reading DONE: "
2704 << t << "\n";
2705 }
2706}
2707#endif
2708
2489/// Walk a given directory and build an instance of @ref corpus_group 2709/// Walk a given directory and build an instance of @ref corpus_group
2490/// from the vmlinux kernel binary and the linux kernel modules found 2710/// from the vmlinux kernel binary and the linux kernel modules found
2491/// under that directory and under its sub-directories, recursively. 2711/// under that directory and under its sub-directories, recursively.
@@ -2493,6 +2713,11 @@ get_binary_paths_from_kernel_dist(const string& dist_root,
2493/// The main corpus of the @ref corpus_group is made of the vmlinux 2713/// The main corpus of the @ref corpus_group is made of the vmlinux
2494/// binary. The other corpora are made of the linux kernel binaries. 2714/// binary. The other corpora are made of the linux kernel binaries.
2495/// 2715///
2716/// Depending of the @ref origin it delegates the corpus build @p group
2717/// to:
2718/// @ref maybe_load_vmlinux_dwarf_corpus
2719/// @ref maybe_load_vmlinux_ctf_corpus
2720///
2496/// @param root the path of the directory under which the kernel 2721/// @param root the path of the directory under which the kernel
2497/// kernel modules are to be found. The vmlinux can also be found 2722/// kernel modules are to be found. The vmlinux can also be found
2498/// somewhere under that directory, but if it's not in there, its path 2723/// somewhere under that directory, but if it's not in there, its path
@@ -2528,10 +2753,11 @@ build_corpus_group_from_kernel_dist_under(const string& root,
2528 vector<string>& kabi_wl_paths, 2753 vector<string>& kabi_wl_paths,
2529 suppressions_type& supprs, 2754 suppressions_type& supprs,
2530 bool verbose, 2755 bool verbose,
2531 environment_sptr& env) 2756 environment_sptr& env,
2757 corpus::origin origin)
2532{ 2758{
2533 string vmlinux = vmlinux_path; 2759 string vmlinux = vmlinux_path;
2534 corpus_group_sptr result; 2760 corpus_group_sptr group;
2535 vector<string> modules; 2761 vector<string> modules;
2536 2762
2537 if (verbose) 2763 if (verbose)
@@ -2548,7 +2774,6 @@ build_corpus_group_from_kernel_dist_under(const string& root,
2548 if (verbose) 2774 if (verbose)
2549 std::cerr << "DONE: " << t << "\n"; 2775 std::cerr << "DONE: " << t << "\n";
2550 2776
2551 dwarf_reader::read_context_sptr ctxt;
2552 if (got_binary_paths) 2777 if (got_binary_paths)
2553 { 2778 {
2554 shared_ptr<char> di_root = 2779 shared_ptr<char> di_root =
@@ -2556,86 +2781,18 @@ build_corpus_group_from_kernel_dist_under(const string& root,
2556 char *di_root_ptr = di_root.get(); 2781 char *di_root_ptr = di_root.get();
2557 vector<char**> di_roots; 2782 vector<char**> di_roots;
2558 di_roots.push_back(&di_root_ptr); 2783 di_roots.push_back(&di_root_ptr);
2559 abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
2560 corpus_group_sptr group;
2561 if (!vmlinux.empty())
2562 {
2563 ctxt =
2564 dwarf_reader::create_read_context(vmlinux, di_roots ,env.get(),
2565 /*read_all_types=*/false,
2566 /*linux_kernel_mode=*/true);
2567 dwarf_reader::set_do_log(*ctxt, verbose);
2568
2569 t.start();
2570 load_generate_apply_suppressions(*ctxt, suppr_paths,
2571 kabi_wl_paths, supprs);
2572 t.stop();
2573
2574 if (verbose)
2575 std::cerr << "loaded white list and generated suppr spec in: "
2576 << t
2577 << "\n";
2578
2579 group.reset(new corpus_group(env.get(), root));
2580
2581 set_read_context_corpus_group(*ctxt, group);
2582
2583 if (verbose)
2584 std::cerr << "reading kernel binary '"
2585 << vmlinux << "' ...\n" << std::flush;
2586
2587 // Read the vmlinux corpus and add it to the group.
2588 t.start();
2589 read_and_add_corpus_to_group_from_elf(*ctxt, *group, status);
2590 t.stop();
2591
2592 if (verbose)
2593 std::cerr << vmlinux
2594 << " reading DONE:"
2595 << t << "\n";
2596 }
2597 2784
2598 if (!group->is_empty()) 2785 maybe_load_vmlinux_dwarf_corpus(origin, group, vmlinux,
2599 { 2786 modules, root, di_roots,
2600 // Now add the corpora of the modules to the corpus group. 2787 suppr_paths, kabi_wl_paths,
2601 int total_nb_modules = modules.size(); 2788 supprs, verbose, t, env);
2602 int cur_module_index = 1; 2789#ifdef WITH_CTF
2603 for (vector<string>::const_iterator m = modules.begin(); 2790 maybe_load_vmlinux_ctf_corpus(origin, group, vmlinux,
2604 m != modules.end(); 2791 modules, root, verbose, t, env);
2605 ++m, ++cur_module_index) 2792#endif
2606 {
2607 if (verbose)
2608 std::cerr << "reading module '"
2609 << *m << "' ("
2610 << cur_module_index
2611 << "/" << total_nb_modules
2612 << ") ... " << std::flush;
2613
2614 reset_read_context(ctxt, *m, di_roots, env.get(),
2615 /*read_all_types=*/false,
2616 /*linux_kernel_mode=*/true);
2617
2618 load_generate_apply_suppressions(*ctxt, suppr_paths,
2619 kabi_wl_paths, supprs);
2620
2621 set_read_context_corpus_group(*ctxt, group);
2622
2623 t.start();
2624 read_and_add_corpus_to_group_from_elf(*ctxt,
2625 *group, status);
2626 t.stop();
2627 if (verbose)
2628 std::cerr << "module '"
2629 << *m
2630 << "' reading DONE: "
2631 << t << "\n";
2632 }
2633
2634 result = group;
2635 }
2636 } 2793 }
2637 2794
2638 return result; 2795 return group;
2639} 2796}
2640 2797
2641}//end namespace tools_utils 2798}//end namespace tools_utils
diff --git a/tests/data/test-read-common/test-PR26568-2.o b/tests/data/test-read-common/test-PR26568-2.o
index b192d521..a6706e8c 100644
--- a/tests/data/test-read-common/test-PR26568-2.o
+++ b/tests/data/test-read-common/test-PR26568-2.o
Binary files differ
diff --git a/tests/data/test-read-ctf/PR27700/test-PR27700.abi b/tests/data/test-read-ctf/PR27700/test-PR27700.abi
index 62df1017..fe3a897d 100644
--- a/tests/data/test-read-ctf/PR27700/test-PR27700.abi
+++ b/tests/data/test-read-ctf/PR27700/test-PR27700.abi
@@ -11,9 +11,8 @@
11 <enumerator name='foo_e2' value='2'/> 11 <enumerator name='foo_e2' value='2'/>
12 <enumerator name='foo_e3' value='3'/> 12 <enumerator name='foo_e3' value='3'/>
13 </enum-decl> 13 </enum-decl>
14 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/>
15 <pointer-type-def type-id='022218d8' size-in-bits='64' alignment-in-bits='64' id='8750e847'/> 14 <pointer-type-def type-id='022218d8' size-in-bits='64' alignment-in-bits='64' id='8750e847'/>
16 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 15 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'>
17 <parameter type-id='8750e847'/> 16 <parameter type-id='8750e847'/>
18 <return type-id='48b5725f'/> 17 <return type-id='48b5725f'/>
19 </function-decl> 18 </function-decl>
diff --git a/tests/data/test-read-ctf/test-PR26568-1.o.abi b/tests/data/test-read-ctf/test-PR26568-1.o.abi
index d62474ec..832dc1bd 100644
--- a/tests/data/test-read-ctf/test-PR26568-1.o.abi
+++ b/tests/data/test-read-ctf/test-PR26568-1.o.abi
@@ -7,47 +7,29 @@
7 <data-member access='public' layout-offset-in-bits='0'> 7 <data-member access='public' layout-offset-in-bits='0'>
8 <var-decl name='' type-id='type-id-2' visibility='default'/> 8 <var-decl name='' type-id='type-id-2' visibility='default'/>
9 </data-member> 9 </data-member>
10 <data-member access='public' layout-offset-in-bits='0'>
11 <var-decl name='' type-id='type-id-3' visibility='default'/>
12 </data-member>
13 <data-member access='public' layout-offset-in-bits='0'>
14 <var-decl name='x' type-id='type-id-4' visibility='default'/>
15 </data-member>
16 <data-member access='public' layout-offset-in-bits='0'>
17 <var-decl name='' type-id='type-id-5' visibility='default'/>
18 </data-member>
19 <data-member access='public' layout-offset-in-bits='0'>
20 <var-decl name='y' type-id='type-id-6' visibility='default'/>
21 </data-member>
22 </class-decl> 10 </class-decl>
23 <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'> 11 <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
24 <data-member access='public' layout-offset-in-bits='0'> 12 <data-member access='public' layout-offset-in-bits='0'>
25 <var-decl name='x' type-id='type-id-4' visibility='default'/> 13 <var-decl name='y' type-id='type-id-4' visibility='default'/>
26 </data-member> 14 </data-member>
27 </class-decl> 15 </class-decl>
28 <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-5'> 16 <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-5'>
29 <data-member access='public' layout-offset-in-bits='0'> 17 <data-member access='public' layout-offset-in-bits='0'>
30 <var-decl name='y' type-id='type-id-6' visibility='default'/> 18 <var-decl name='x' type-id='type-id-6' visibility='default'/>
31 </data-member> 19 </data-member>
32 </class-decl> 20 </class-decl>
33 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/> 21 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-6'/>
34 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/> 22 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
35 <union-decl name='' size-in-bits='64' is-anonymous='yes' visibility='default' id='type-id-2'> 23 <union-decl name='' size-in-bits='64' is-anonymous='yes' visibility='default' id='type-id-2'>
36 <data-member access='public'> 24 <data-member access='public'>
37 <var-decl name='' type-id='type-id-3' visibility='default'/>
38 </data-member>
39 <data-member access='public'>
40 <var-decl name='x' type-id='type-id-4' visibility='default'/>
41 </data-member>
42 <data-member access='public'>
43 <var-decl name='' type-id='type-id-5' visibility='default'/> 25 <var-decl name='' type-id='type-id-5' visibility='default'/>
44 </data-member> 26 </data-member>
45 <data-member access='public'> 27 <data-member access='public'>
46 <var-decl name='y' type-id='type-id-6' visibility='default'/> 28 <var-decl name='' type-id='type-id-3' visibility='default'/>
47 </data-member> 29 </data-member>
48 </union-decl> 30 </union-decl>
49 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/> 31 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
50 <function-decl name='fun' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 32 <function-decl name='fun' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='fun'>
51 <parameter type-id='type-id-7'/> 33 <parameter type-id='type-id-7'/>
52 <return type-id='type-id-8'/> 34 <return type-id='type-id-8'/>
53 </function-decl> 35 </function-decl>
diff --git a/tests/data/test-read-ctf/test-PR26568-2.o.abi b/tests/data/test-read-ctf/test-PR26568-2.o.abi
index a934d15b..70e0772f 100644
--- a/tests/data/test-read-ctf/test-PR26568-2.o.abi
+++ b/tests/data/test-read-ctf/test-PR26568-2.o.abi
@@ -3,34 +3,28 @@
3 <elf-symbol name='fun' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 3 <elf-symbol name='fun' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 </elf-function-symbols> 4 </elf-function-symbols>
5 <abi-instr address-size='64' language='LANG_C'> 5 <abi-instr address-size='64' language='LANG_C'>
6 <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-1'> 6 <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-1'>
7 <data-member access='public' layout-offset-in-bits='0'> 7 <data-member access='public' layout-offset-in-bits='0'>
8 <var-decl name='x' type-id='type-id-2' visibility='default'/> 8 <var-decl name='y' type-id='type-id-2' visibility='default'/>
9 </data-member> 9 </data-member>
10 </class-decl> 10 </class-decl>
11 <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'> 11 <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
12 <data-member access='public' layout-offset-in-bits='0'> 12 <data-member access='public' layout-offset-in-bits='0'>
13 <var-decl name='y' type-id='type-id-4' visibility='default'/> 13 <var-decl name='x' type-id='type-id-4' visibility='default'/>
14 </data-member> 14 </data-member>
15 </class-decl> 15 </class-decl>
16 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-2'/> 16 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
17 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/> 17 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
18 <union-decl name='A' size-in-bits='64' visibility='default' id='type-id-5'> 18 <union-decl name='A' size-in-bits='64' visibility='default' id='type-id-5'>
19 <data-member access='public'> 19 <data-member access='public'>
20 <var-decl name='' type-id='type-id-1' visibility='default'/>
21 </data-member>
22 <data-member access='public'>
23 <var-decl name='x' type-id='type-id-2' visibility='default'/>
24 </data-member>
25 <data-member access='public'>
26 <var-decl name='' type-id='type-id-3' visibility='default'/> 20 <var-decl name='' type-id='type-id-3' visibility='default'/>
27 </data-member> 21 </data-member>
28 <data-member access='public'> 22 <data-member access='public'>
29 <var-decl name='y' type-id='type-id-4' visibility='default'/> 23 <var-decl name='' type-id='type-id-1' visibility='default'/>
30 </data-member> 24 </data-member>
31 </union-decl> 25 </union-decl>
32 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/> 26 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
33 <function-decl name='fun' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 27 <function-decl name='fun' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='fun'>
34 <parameter type-id='type-id-6'/> 28 <parameter type-id='type-id-6'/>
35 <return type-id='type-id-7'/> 29 <return type-id='type-id-7'/>
36 </function-decl> 30 </function-decl>
diff --git a/tests/data/test-read-ctf/test-PR27700.abi b/tests/data/test-read-ctf/test-PR27700.abi
new file mode 100644
index 00000000..fe3a897d
--- /dev/null
+++ b/tests/data/test-read-ctf/test-PR27700.abi
@@ -0,0 +1,21 @@
1<abi-corpus version='2.1' path='data/test-read-common/PR27700/test-PR27700.o'>
2 <elf-function-symbols>
3 <elf-symbol name='foo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 </elf-function-symbols>
5 <abi-instr address-size='64' language='LANG_C'>
6 <type-decl name='' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='811c9dc5'/>
7 <enum-decl name='foo' linkage-name='foo' id='022218d8'>
8 <underlying-type type-id='811c9dc5'/>
9 <enumerator name='foo_e0' value='0'/>
10 <enumerator name='foo_e1' value='1'/>
11 <enumerator name='foo_e2' value='2'/>
12 <enumerator name='foo_e3' value='3'/>
13 </enum-decl>
14 <pointer-type-def type-id='022218d8' size-in-bits='64' alignment-in-bits='64' id='8750e847'/>
15 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'>
16 <parameter type-id='8750e847'/>
17 <return type-id='48b5725f'/>
18 </function-decl>
19 <type-decl name='void' id='48b5725f'/>
20 </abi-instr>
21</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi b/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi
index 922a1daf..12050a5b 100644
--- a/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi
+++ b/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi
@@ -30,7 +30,6 @@
30 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='7359adad'/> 30 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='7359adad'/>
31 <pointer-type-def type-id='3ed987a4' size-in-bits='64' alignment-in-bits='64' id='84d5ac12'/> 31 <pointer-type-def type-id='3ed987a4' size-in-bits='64' alignment-in-bits='64' id='84d5ac12'/>
32 <pointer-type-def type-id='1c12b755' size-in-bits='64' alignment-in-bits='64' id='55cd64e8'/> 32 <pointer-type-def type-id='1c12b755' size-in-bits='64' alignment-in-bits='64' id='55cd64e8'/>
33 <var-decl name='a' type-id='3ed987a4' mangled-name='a' visibility='default'/> 33 <var-decl name='foo' type-id='55cd64e8' mangled-name='foo' visibility='default' elf-symbol-id='foo'/>
34 <var-decl name='foo' type-id='55cd64e8' mangled-name='foo' visibility='default'/>
35 </abi-instr> 34 </abi-instr>
36</abi-corpus> 35</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-B.c b/tests/data/test-read-ctf/test-ambiguous-struct-B.c
index 95a93469..e592529b 100644
--- a/tests/data/test-read-ctf/test-ambiguous-struct-B.c
+++ b/tests/data/test-read-ctf/test-ambiguous-struct-B.c
@@ -2,4 +2,4 @@ struct A;
2struct B { struct A *a; }; 2struct B { struct A *a; };
3struct A { struct B b; int foo; struct B b2; }; 3struct A { struct B b; int foo; struct B b2; };
4 4
5static struct A a __attribute__((__used__)); 5struct A a __attribute__((__used__));
diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-B.o b/tests/data/test-read-ctf/test-ambiguous-struct-B.o
index 06bd0f50..40a11fcb 100644
--- a/tests/data/test-read-ctf/test-ambiguous-struct-B.o
+++ b/tests/data/test-read-ctf/test-ambiguous-struct-B.o
Binary files differ
diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi b/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi
index 28291eb5..83d21919 100644
--- a/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi
+++ b/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi
@@ -1,4 +1,7 @@
1<abi-corpus version='2.1' path='data/test-read-ctf/test-ambiguous-struct-B.o'> 1<abi-corpus version='2.1' path='data/test-read-ctf/test-ambiguous-struct-B.o'>
2 <elf-variable-symbols>
3 <elf-symbol name='a' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 </elf-variable-symbols>
2 <abi-instr address-size='64' language='LANG_C'> 5 <abi-instr address-size='64' language='LANG_C'>
3 <class-decl name='A' size-in-bits='192' alignment-in-bits='64' is-struct='yes' visibility='default' id='3ed987a4'> 6 <class-decl name='A' size-in-bits='192' alignment-in-bits='64' is-struct='yes' visibility='default' id='3ed987a4'>
4 <data-member access='public' layout-offset-in-bits='0'> 7 <data-member access='public' layout-offset-in-bits='0'>
@@ -18,6 +21,6 @@
18 </class-decl> 21 </class-decl>
19 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='95e97e5e'/> 22 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='95e97e5e'/>
20 <pointer-type-def type-id='3ed987a4' size-in-bits='64' alignment-in-bits='64' id='84d5ac12'/> 23 <pointer-type-def type-id='3ed987a4' size-in-bits='64' alignment-in-bits='64' id='84d5ac12'/>
21 <var-decl name='a' type-id='3ed987a4' mangled-name='a' visibility='default'/> 24 <var-decl name='a' type-id='3ed987a4' mangled-name='a' visibility='default' elf-symbol-id='a'/>
22 </abi-instr> 25 </abi-instr>
23</abi-corpus> 26</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-anonymous-fields.o.abi b/tests/data/test-read-ctf/test-anonymous-fields.o.abi
index 0419c29c..2134a86d 100644
--- a/tests/data/test-read-ctf/test-anonymous-fields.o.abi
+++ b/tests/data/test-read-ctf/test-anonymous-fields.o.abi
@@ -3,14 +3,14 @@
3 <elf-symbol name='t' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 3 <elf-symbol name='t' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 </elf-variable-symbols> 4 </elf-variable-symbols>
5 <abi-instr address-size='64' language='LANG_C'> 5 <abi-instr address-size='64' language='LANG_C'>
6 <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-1'> 6 <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-1'>
7 <data-member access='public' layout-offset-in-bits='0'> 7 <data-member access='public' layout-offset-in-bits='0'>
8 <var-decl name='vaddr' type-id='type-id-2' visibility='default'/> 8 <var-decl name='dup_xol_work' type-id='type-id-2' visibility='default'/>
9 </data-member> 9 </data-member>
10 </class-decl> 10 </class-decl>
11 <class-decl name='' size-in-bits='32' alignment-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'> 11 <class-decl name='' size-in-bits='64' alignment-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='type-id-3'>
12 <data-member access='public' layout-offset-in-bits='0'> 12 <data-member access='public' layout-offset-in-bits='0'>
13 <var-decl name='dup_xol_work' type-id='type-id-4' visibility='default'/> 13 <var-decl name='vaddr' type-id='type-id-4' visibility='default'/>
14 </data-member> 14 </data-member>
15 </class-decl> 15 </class-decl>
16 <class-decl name='uprobe_task' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-5'> 16 <class-decl name='uprobe_task' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-5'>
@@ -18,16 +18,16 @@
18 <var-decl name='' type-id='type-id-6' visibility='default'/> 18 <var-decl name='' type-id='type-id-6' visibility='default'/>
19 </data-member> 19 </data-member>
20 </class-decl> 20 </class-decl>
21 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/> 21 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-2'/>
22 <union-decl name='' size-in-bits='64' is-anonymous='yes' visibility='default' id='type-id-6'> 22 <union-decl name='' size-in-bits='64' is-anonymous='yes' visibility='default' id='type-id-6'>
23 <data-member access='public'> 23 <data-member access='public'>
24 <var-decl name='' type-id='type-id-1' visibility='default'/> 24 <var-decl name='' type-id='type-id-3' visibility='default'/>
25 </data-member> 25 </data-member>
26 <data-member access='public'> 26 <data-member access='public'>
27 <var-decl name='' type-id='type-id-3' visibility='default'/> 27 <var-decl name='' type-id='type-id-1' visibility='default'/>
28 </data-member> 28 </data-member>
29 </union-decl> 29 </union-decl>
30 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 30 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
31 <var-decl name='t' type-id='type-id-5' mangled-name='t' visibility='default'/> 31 <var-decl name='t' type-id='type-id-5' mangled-name='t' visibility='default' elf-symbol-id='t'/>
32 </abi-instr> 32 </abi-instr>
33</abi-corpus> 33</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-array-of-pointers.abi b/tests/data/test-read-ctf/test-array-of-pointers.abi
index 920da28b..195361df 100644
--- a/tests/data/test-read-ctf/test-array-of-pointers.abi
+++ b/tests/data/test-read-ctf/test-array-of-pointers.abi
@@ -31,6 +31,6 @@
31 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/> 31 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
32 <pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/> 32 <pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/>
33 <pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-11'/> 33 <pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-11'/>
34 <var-decl name='t' type-id='type-id-11' mangled-name='t' visibility='default'/> 34 <var-decl name='t' type-id='type-id-11' mangled-name='t' visibility='default' elf-symbol-id='t'/>
35 </abi-instr> 35 </abi-instr>
36</abi-corpus> 36</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-callback.abi b/tests/data/test-read-ctf/test-callback.abi
index 704c4971..7f9b6c5f 100644
--- a/tests/data/test-read-ctf/test-callback.abi
+++ b/tests/data/test-read-ctf/test-callback.abi
@@ -4,28 +4,16 @@
4 <elf-symbol name='f2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 4 <elf-symbol name='f2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
5 </elf-function-symbols> 5 </elf-function-symbols>
6 <abi-instr address-size='64' language='LANG_C'> 6 <abi-instr address-size='64' language='LANG_C'>
7 <class-decl name='test' size-in-bits='64' alignment-in-bits='64' is-struct='yes' visibility='default' id='type-id-1'> 7 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
8 <data-member access='public' layout-offset-in-bits='0'> 8 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
9 <var-decl name='fn1' type-id='type-id-2' visibility='default'/> 9 <function-decl name='assign' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='assign'>
10 </data-member> 10 <return type-id='type-id-3'/>
11 </class-decl>
12 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
13 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
14 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
15 <pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
16 <function-decl name='assign' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'>
17 <return type-id='type-id-7'/>
18 </function-decl> 11 </function-decl>
19 <function-decl name='f2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 12 <function-decl name='f2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='f2'>
20 <parameter type-id='type-id-3'/> 13 <parameter type-id='type-id-1'/>
21 <parameter type-id='type-id-4'/> 14 <parameter type-id='type-id-2'/>
22 <return type-id='type-id-7'/> 15 <return type-id='type-id-3'/>
23 </function-decl> 16 </function-decl>
24 <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-6'> 17 <type-decl name='void' id='type-id-3'/>
25 <parameter type-id='type-id-3'/>
26 <parameter type-id='type-id-4'/>
27 <return type-id='type-id-7'/>
28 </function-type>
29 <type-decl name='void' id='type-id-7'/>
30 </abi-instr> 18 </abi-instr>
31</abi-corpus> 19</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-callback2.abi b/tests/data/test-read-ctf/test-callback2.abi
index bdd4ad33..ddc3e493 100644
--- a/tests/data/test-read-ctf/test-callback2.abi
+++ b/tests/data/test-read-ctf/test-callback2.abi
@@ -11,7 +11,7 @@
11 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/> 11 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
12 <pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 12 <pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
13 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/> 13 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
14 <var-decl name='s0' type-id='type-id-5' mangled-name='s0' visibility='default'/> 14 <var-decl name='s0' type-id='type-id-5' mangled-name='s0' visibility='default' elf-symbol-id='s0'/>
15 <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-4'> 15 <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-4'>
16 <parameter type-id='type-id-5'/> 16 <parameter type-id='type-id-5'/>
17 <return type-id='type-id-3'/> 17 <return type-id='type-id-3'/>
diff --git a/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi b/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi
index 03dd56b3..8d5c3e36 100644
--- a/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi
+++ b/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi
@@ -8,7 +8,7 @@
8 <typedef-decl name='a_t' type-id='bd54fe1a' id='40acc204'/> 8 <typedef-decl name='a_t' type-id='bd54fe1a' id='40acc204'/>
9 <typedef-decl name='b_t' type-id='bd54fe1a' id='b3d2db81'/> 9 <typedef-decl name='b_t' type-id='bd54fe1a' id='b3d2db81'/>
10 <pointer-type-def type-id='40acc204' size-in-bits='64' alignment-in-bits='64' id='c6fd4117'/> 10 <pointer-type-def type-id='40acc204' size-in-bits='64' alignment-in-bits='64' id='c6fd4117'/>
11 <var-decl name='a' type-id='c6fd4117' mangled-name='a' visibility='default'/> 11 <var-decl name='a' type-id='c6fd4117' mangled-name='a' visibility='default' elf-symbol-id='a'/>
12 <var-decl name='ignore2' type-id='b3d2db81' mangled-name='ignore2' visibility='default'/> 12 <var-decl name='ignore2' type-id='b3d2db81' mangled-name='ignore2' visibility='default' elf-symbol-id='ignore2'/>
13 </abi-instr> 13 </abi-instr>
14</abi-corpus> 14</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi b/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi
index 35bcac7a..992b669d 100644
--- a/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi
+++ b/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi
@@ -7,7 +7,7 @@
7 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='bd54fe1a'/> 7 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='bd54fe1a'/>
8 <typedef-decl name='a_t' type-id='bd54fe1a' id='40acc204'/> 8 <typedef-decl name='a_t' type-id='bd54fe1a' id='40acc204'/>
9 <typedef-decl name='b_t' type-id='bd54fe1a' id='b3d2db81'/> 9 <typedef-decl name='b_t' type-id='bd54fe1a' id='b3d2db81'/>
10 <var-decl name='b' type-id='40acc204' mangled-name='b' visibility='default'/> 10 <var-decl name='b' type-id='40acc204' mangled-name='b' visibility='default' elf-symbol-id='b'/>
11 <var-decl name='ignore1' type-id='b3d2db81' mangled-name='ignore1' visibility='default'/> 11 <var-decl name='ignore1' type-id='b3d2db81' mangled-name='ignore1' visibility='default' elf-symbol-id='ignore1'/>
12 </abi-instr> 12 </abi-instr>
13</abi-corpus> 13</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-dynamic-array.o.abi b/tests/data/test-read-ctf/test-dynamic-array.o.abi
index 02b22811..a9849d49 100644
--- a/tests/data/test-read-ctf/test-dynamic-array.o.abi
+++ b/tests/data/test-read-ctf/test-dynamic-array.o.abi
@@ -21,7 +21,7 @@
21 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/> 21 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>
22 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/> 22 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
23 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/> 23 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
24 <function-decl name='use_struct_s' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 24 <function-decl name='use_struct_s' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='use_struct_s'>
25 <parameter type-id='type-id-7'/> 25 <parameter type-id='type-id-7'/>
26 <return type-id='type-id-8'/> 26 <return type-id='type-id-8'/>
27 </function-decl> 27 </function-decl>
diff --git a/tests/data/test-read-ctf/test-enum-ctf.o.abi b/tests/data/test-read-ctf/test-enum-ctf.o.abi
new file mode 100644
index 00000000..f36f3fad
--- /dev/null
+++ b/tests/data/test-read-ctf/test-enum-ctf.o.abi
@@ -0,0 +1,24 @@
1<abi-corpus version='2.1' path='data/test-read-ctf/test-enum-ctf.o'>
2 <elf-variable-symbols>
3 <elf-symbol name='bar' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 <elf-symbol name='foo' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
5 </elf-variable-symbols>
6 <abi-instr address-size='64' language='LANG_C'>
7 <type-decl name='' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
8 <enum-decl name='e' linkage-name='e' id='type-id-2'>
9 <underlying-type type-id='type-id-1'/>
10 <enumerator name='ENUMSAMPLE_1' value='0'/>
11 <enumerator name='ENUMSAMPLE_2' value='1'/>
12 </enum-decl>
13 <enum-decl name='ie' linkage-name='ie' id='type-id-3'>
14 <underlying-type type-id='type-id-1'/>
15 <enumerator name='IENUMSAMPLE_1' value='-10'/>
16 <enumerator name='IENUMSAMPLE_2' value='-9'/>
17 <enumerator name='IENUMSAMPLE_3' value='-8'/>
18 </enum-decl>
19 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
20 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-5'/>
21 <var-decl name='foo' type-id='type-id-2' mangled-name='foo' visibility='default'/>
22 <var-decl name='bar' type-id='type-id-3' mangled-name='bar' visibility='default'/>
23 </abi-instr>
24</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi b/tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi
new file mode 100644
index 00000000..67a958a7
--- /dev/null
+++ b/tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi
@@ -0,0 +1,69 @@
1<abi-corpus version='2.1' path='data/test-read-ctf/test-enum-many-ctf.o'>
2 <elf-variable-symbols>
3 <elf-symbol name='bar' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 <elf-symbol name='foo' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
5 </elf-variable-symbols>
6 <abi-instr address-size='64' language='LANG_C'>
7 <type-decl name='' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='811c9dc5'/>
8 <enum-decl name='e' linkage-name='e' id='a6c2eddf'>
9 <underlying-type type-id='811c9dc5'/>
10 <enumerator name='ENUMSAMPLE_1' value='0'/>
11 <enumerator name='ENUMSAMPLE_2' value='1'/>
12 </enum-decl>
13 <enum-decl name='ie' linkage-name='ie' id='1ee696ca'>
14 <underlying-type type-id='811c9dc5'/>
15 <enumerator name='IE_0' value='-10'/>
16 <enumerator name='IE_1' value='-9'/>
17 <enumerator name='IE_2' value='-8'/>
18 <enumerator name='IE_3' value='-7'/>
19 <enumerator name='IE_4' value='-6'/>
20 <enumerator name='IE_5' value='-5'/>
21 <enumerator name='IE_6' value='-4'/>
22 <enumerator name='IE_7' value='-3'/>
23 <enumerator name='IE_8' value='-2'/>
24 <enumerator name='IE_9' value='-1'/>
25 <enumerator name='IE_A' value='0'/>
26 <enumerator name='IE_B' value='1'/>
27 <enumerator name='IE_C' value='2'/>
28 <enumerator name='IE_D' value='3'/>
29 <enumerator name='IE_E' value='4'/>
30 <enumerator name='IE_F' value='5'/>
31 <enumerator name='IE_10' value='6'/>
32 <enumerator name='IE_11' value='7'/>
33 <enumerator name='IE_12' value='8'/>
34 <enumerator name='IE_13' value='9'/>
35 <enumerator name='IE_14' value='10'/>
36 <enumerator name='IE_15' value='11'/>
37 <enumerator name='IE_16' value='12'/>
38 <enumerator name='IE_17' value='13'/>
39 <enumerator name='IE_18' value='14'/>
40 <enumerator name='IE_19' value='15'/>
41 <enumerator name='IE_1A' value='16'/>
42 <enumerator name='IE_1B' value='17'/>
43 <enumerator name='IE_1C' value='18'/>
44 <enumerator name='IE_1D' value='19'/>
45 <enumerator name='IE_1E' value='20'/>
46 <enumerator name='IE_1F' value='21'/>
47 <enumerator name='IE_20' value='22'/>
48 <enumerator name='IE_21' value='23'/>
49 <enumerator name='IE_22' value='24'/>
50 <enumerator name='IE_23' value='25'/>
51 <enumerator name='IE_24' value='26'/>
52 <enumerator name='IE_25' value='27'/>
53 <enumerator name='IE_26' value='28'/>
54 <enumerator name='IE_27' value='29'/>
55 <enumerator name='IE_28' value='30'/>
56 <enumerator name='IE_29' value='31'/>
57 <enumerator name='IE_2A' value='32'/>
58 <enumerator name='IE_2B' value='33'/>
59 <enumerator name='IE_2C' value='34'/>
60 <enumerator name='IE_2D' value='35'/>
61 <enumerator name='IE_2E' value='36'/>
62 <enumerator name='IE_2F' value='37'/>
63 </enum-decl>
64 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='95e97e5e'/>
65 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/>
66 <var-decl name='foo' type-id='a6c2eddf' mangled-name='foo' visibility='default'/>
67 <var-decl name='bar' type-id='1ee696ca' mangled-name='bar' visibility='default'/>
68 </abi-instr>
69</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-enum-many.o.hash.abi b/tests/data/test-read-ctf/test-enum-many.o.hash.abi
index 26bc048c..116325f9 100644
--- a/tests/data/test-read-ctf/test-enum-many.o.hash.abi
+++ b/tests/data/test-read-ctf/test-enum-many.o.hash.abi
@@ -61,9 +61,7 @@
61 <enumerator name='IE_2E' value='36'/> 61 <enumerator name='IE_2E' value='36'/>
62 <enumerator name='IE_2F' value='37'/> 62 <enumerator name='IE_2F' value='37'/>
63 </enum-decl> 63 </enum-decl>
64 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='95e97e5e'/> 64 <var-decl name='foo' type-id='a6c2eddf' mangled-name='foo' visibility='default' elf-symbol-id='foo'/>
65 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/> 65 <var-decl name='bar' type-id='1ee696ca' mangled-name='bar' visibility='default' elf-symbol-id='bar'/>
66 <var-decl name='foo' type-id='a6c2eddf' mangled-name='foo' visibility='default'/>
67 <var-decl name='bar' type-id='1ee696ca' mangled-name='bar' visibility='default'/>
68 </abi-instr> 66 </abi-instr>
69</abi-corpus> 67</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi b/tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi
new file mode 100644
index 00000000..fea6eb8b
--- /dev/null
+++ b/tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi
@@ -0,0 +1,16 @@
1<abi-corpus version='2.1' path='data/test-read-ctf/test-enum-symbol-ctf.o'>
2 <elf-variable-symbols>
3 <elf-symbol name='primary1' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 </elf-variable-symbols>
5 <abi-instr address-size='64' language='LANG_C'>
6 <type-decl name='' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='811c9dc5'/>
7 <enum-decl name='' is-anonymous='yes' id='08f5ca17'>
8 <underlying-type type-id='811c9dc5'/>
9 <enumerator name='red1' value='0'/>
10 <enumerator name='green1' value='1'/>
11 <enumerator name='blue1' value='2'/>
12 </enum-decl>
13 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/>
14 <var-decl name='primary1' type-id='08f5ca17' mangled-name='primary1' visibility='default'/>
15 </abi-instr>
16</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi b/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi
index d128b5b1..f4911bc4 100644
--- a/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi
+++ b/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi
@@ -10,7 +10,6 @@
10 <enumerator name='green1' value='1'/> 10 <enumerator name='green1' value='1'/>
11 <enumerator name='blue1' value='2'/> 11 <enumerator name='blue1' value='2'/>
12 </enum-decl> 12 </enum-decl>
13 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/> 13 <var-decl name='primary1' type-id='08f5ca17' mangled-name='primary1' visibility='default' elf-symbol-id='primary1'/>
14 <var-decl name='primary1' type-id='08f5ca17' mangled-name='primary1' visibility='default'/>
15 </abi-instr> 14 </abi-instr>
16</abi-corpus> 15</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-enum.o.abi b/tests/data/test-read-ctf/test-enum.o.abi
index 88e6ad61..bd3a55be 100644
--- a/tests/data/test-read-ctf/test-enum.o.abi
+++ b/tests/data/test-read-ctf/test-enum.o.abi
@@ -16,9 +16,7 @@
16 <enumerator name='IENUMSAMPLE_2' value='-9'/> 16 <enumerator name='IENUMSAMPLE_2' value='-9'/>
17 <enumerator name='IENUMSAMPLE_3' value='-8'/> 17 <enumerator name='IENUMSAMPLE_3' value='-8'/>
18 </enum-decl> 18 </enum-decl>
19 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/> 19 <var-decl name='foo' type-id='type-id-2' mangled-name='foo' visibility='default' elf-symbol-id='foo'/>
20 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-5'/> 20 <var-decl name='bar' type-id='type-id-3' mangled-name='bar' visibility='default' elf-symbol-id='bar'/>
21 <var-decl name='foo' type-id='type-id-2' mangled-name='foo' visibility='default'/>
22 <var-decl name='bar' type-id='type-id-3' mangled-name='bar' visibility='default'/>
23 </abi-instr> 21 </abi-instr>
24</abi-corpus> 22</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-forward-type-decl.abi b/tests/data/test-read-ctf/test-forward-type-decl.abi
index 21bb45c8..026e7d32 100644
--- a/tests/data/test-read-ctf/test-forward-type-decl.abi
+++ b/tests/data/test-read-ctf/test-forward-type-decl.abi
@@ -24,6 +24,6 @@
24 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/> 24 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
25 <pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/> 25 <pointer-type-def type-id='type-id-4' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>
26 <pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 26 <pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
27 <var-decl name='addr' type-id='type-id-5' mangled-name='addr' visibility='default'/> 27 <var-decl name='addr' type-id='type-id-5' mangled-name='addr' visibility='default' elf-symbol-id='addr'/>
28 </abi-instr> 28 </abi-instr>
29</abi-corpus> 29</abi-corpus>
diff --git a/tests/data/test-read-ctf/test-functions-declaration.abi b/tests/data/test-read-ctf/test-functions-declaration.abi
index 9ef05e44..7eb57d26 100644
--- a/tests/data/test-read-ctf/test-functions-declaration.abi
+++ b/tests/data/test-read-ctf/test-functions-declaration.abi
@@ -7,11 +7,11 @@
7 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/> 7 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
8 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 8 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
9 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/> 9 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-4'/>
10 <function-decl name='attribute_container_add_device' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 10 <function-decl name='attribute_container_add_device' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='attribute_container_add_device'>
11 <parameter type-id='type-id-4'/> 11 <parameter type-id='type-id-4'/>
12 <return type-id='type-id-5'/> 12 <return type-id='type-id-5'/>
13 </function-decl> 13 </function-decl>
14 <function-decl name='attribute_container_device_trigger' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 14 <function-decl name='attribute_container_device_trigger' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='attribute_container_device_trigger'>
15 <parameter type-id='type-id-4'/> 15 <parameter type-id='type-id-4'/>
16 <return type-id='type-id-5'/> 16 <return type-id='type-id-5'/>
17 </function-decl> 17 </function-decl>
diff --git a/tests/data/test-read-ctf/test-list-struct.abi b/tests/data/test-read-ctf/test-list-struct.abi
index 196a79a1..deb6a4a1 100644
--- a/tests/data/test-read-ctf/test-list-struct.abi
+++ b/tests/data/test-read-ctf/test-list-struct.abi
@@ -14,7 +14,7 @@
14 </class-decl> 14 </class-decl>
15 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/> 15 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>
16 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 16 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
17 <var-decl name='n1' type-id='type-id-1' mangled-name='n1' visibility='default'/> 17 <var-decl name='n1' type-id='type-id-1' mangled-name='n1' visibility='default' elf-symbol-id='n1'/>
18 <var-decl name='n2' type-id='type-id-1' mangled-name='n2' visibility='default'/> 18 <var-decl name='n2' type-id='type-id-1' mangled-name='n2' visibility='default' elf-symbol-id='n2'/>
19 </abi-instr> 19 </abi-instr>
20</abi-corpus> 20</abi-corpus>
diff --git a/tests/data/test-read-ctf/test0 b/tests/data/test-read-ctf/test0
index aca7fbac..90aa8a39 100755
--- a/tests/data/test-read-ctf/test0
+++ b/tests/data/test-read-ctf/test0
Binary files differ
diff --git a/tests/data/test-read-ctf/test0.abi b/tests/data/test-read-ctf/test0.abi
index 50ca26f4..fc61f2ac 100644
--- a/tests/data/test-read-ctf/test0.abi
+++ b/tests/data/test-read-ctf/test0.abi
@@ -39,16 +39,26 @@
39 </array-type-def> 39 </array-type-def>
40 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-10'/> 40 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-10'/>
41 <type-decl name='short int' size-in-bits='16' alignment-in-bits='16' id='type-id-11'/> 41 <type-decl name='short int' size-in-bits='16' alignment-in-bits='16' id='type-id-11'/>
42 <type-decl name='signed char' size-in-bits='8' alignment-in-bits='8' id='type-id-12'/>
43 <type-decl name='unsigned char' size-in-bits='8' alignment-in-bits='8' id='type-id-13'/>
44 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-14'/>
45 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/> 42 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/>
46 <type-decl name='unsigned short int' size-in-bits='16' alignment-in-bits='16' id='type-id-15'/> 43 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-12'/>
47 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-16'/> 44 <pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-13'/>
48 <pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-17'/> 45 <qualified-type-def type-id='type-id-3' const='yes' id='type-id-14'/>
49 <qualified-type-def type-id='type-id-3' const='yes' id='type-id-18'/> 46 <pointer-type-def type-id='type-id-10' size-in-bits='64' alignment-in-bits='64' id='type-id-15'/>
50 <pointer-type-def type-id='type-id-10' size-in-bits='64' alignment-in-bits='64' id='type-id-19'/> 47 <qualified-type-def type-id='type-id-15' restrict='yes' id='type-id-16'/>
51 <qualified-type-def type-id='type-id-19' restrict='yes' id='type-id-20'/> 48 <qualified-type-def type-id='type-id-11' volatile='yes' id='type-id-17'/>
52 <qualified-type-def type-id='type-id-11' volatile='yes' id='type-id-21'/> 49 <var-decl name='status' type-id='type-id-5' mangled-name='status' visibility='default' elf-symbol-id='status'/>
50 <var-decl name='test_pointer' type-id='type-id-13' mangled-name='test_pointer' visibility='default' elf-symbol-id='test_pointer'/>
51 <var-decl name='test_const' type-id='type-id-14' mangled-name='test_const' visibility='default' elf-symbol-id='test_const'/>
52 <var-decl name='test_float' type-id='type-id-6' mangled-name='test_float' visibility='default' elf-symbol-id='test_float'/>
53 <function-decl name='foo_1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo_1'>
54 <parameter type-id='type-id-12'/>
55 <return type-id='type-id-4'/>
56 </function-decl>
57 <function-decl name='main' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='main'>
58 <return type-id='type-id-4'/>
59 </function-decl>
60 <var-decl name='test_array' type-id='type-id-7' mangled-name='test_array' visibility='default' elf-symbol-id='test_array'/>
61 <var-decl name='test_restrict' type-id='type-id-16' mangled-name='test_restrict' visibility='default' elf-symbol-id='test_restrict'/>
62 <var-decl name='test_volatile' type-id='type-id-17' mangled-name='test_volatile' visibility='default' elf-symbol-id='test_volatile'/>
53 </abi-instr> 63 </abi-instr>
54</abi-corpus> 64</abi-corpus>
diff --git a/tests/data/test-read-ctf/test0.c b/tests/data/test-read-ctf/test0.c
index eb702312..fdefd57c 100644
--- a/tests/data/test-read-ctf/test0.c
+++ b/tests/data/test-read-ctf/test0.c
@@ -1,3 +1,9 @@
1/*
2 * ELF EXEC files must use -Wl,--ctf-variables -Bdynimic options
3 * to export an ABI and store CTF symbols information.
4 *
5 * ctf-gcc -gctf -Wl,--ctf-variables -Bdynamic test0.c -o test0
6 */
1 7
2#include <stdio.h> 8#include <stdio.h>
3 9
diff --git a/tests/data/test-read-ctf/test0.hash.abi b/tests/data/test-read-ctf/test0.hash.abi
index b58520ab..eff32228 100644
--- a/tests/data/test-read-ctf/test0.hash.abi
+++ b/tests/data/test-read-ctf/test0.hash.abi
@@ -39,16 +39,26 @@
39 </array-type-def> 39 </array-type-def>
40 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='bd54fe1a'/> 40 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='bd54fe1a'/>
41 <type-decl name='short int' size-in-bits='16' alignment-in-bits='16' id='a2185560'/> 41 <type-decl name='short int' size-in-bits='16' alignment-in-bits='16' id='a2185560'/>
42 <type-decl name='signed char' size-in-bits='8' alignment-in-bits='8' id='28577a57'/>
43 <type-decl name='unsigned char' size-in-bits='8' alignment-in-bits='8' id='002ac4a6'/>
44 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/>
45 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='7359adad'/> 42 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='7359adad'/>
46 <type-decl name='unsigned short int' size-in-bits='16' alignment-in-bits='16' id='8efea9e5'/>
47 <pointer-type-def type-id='50d9a3fa' size-in-bits='64' alignment-in-bits='64' id='fd01f598'/> 43 <pointer-type-def type-id='50d9a3fa' size-in-bits='64' alignment-in-bits='64' id='fd01f598'/>
48 <pointer-type-def type-id='a84c031d' size-in-bits='64' alignment-in-bits='64' id='26a90f95'/> 44 <pointer-type-def type-id='a84c031d' size-in-bits='64' alignment-in-bits='64' id='26a90f95'/>
49 <qualified-type-def type-id='50d9a3fa' const='yes' id='0fb3b55d'/> 45 <qualified-type-def type-id='50d9a3fa' const='yes' id='0fb3b55d'/>
50 <pointer-type-def type-id='bd54fe1a' size-in-bits='64' alignment-in-bits='64' id='3ccc2590'/> 46 <pointer-type-def type-id='bd54fe1a' size-in-bits='64' alignment-in-bits='64' id='3ccc2590'/>
51 <qualified-type-def type-id='3ccc2590' restrict='yes' id='af4b1b38'/> 47 <qualified-type-def type-id='3ccc2590' restrict='yes' id='af4b1b38'/>
52 <qualified-type-def type-id='a2185560' volatile='yes' id='ec67e496'/> 48 <qualified-type-def type-id='a2185560' volatile='yes' id='ec67e496'/>
49 <var-decl name='status' type-id='e7f43f72' mangled-name='status' visibility='default' elf-symbol-id='status'/>
50 <var-decl name='test_pointer' type-id='26a90f95' mangled-name='test_pointer' visibility='default' elf-symbol-id='test_pointer'/>
51 <var-decl name='test_const' type-id='0fb3b55d' mangled-name='test_const' visibility='default' elf-symbol-id='test_const'/>
52 <var-decl name='test_float' type-id='a6c45d85' mangled-name='test_float' visibility='default' elf-symbol-id='test_float'/>
53 <function-decl name='foo_1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo_1'>
54 <parameter type-id='fd01f598'/>
55 <return type-id='95e97e5e'/>
56 </function-decl>
57 <function-decl name='main' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='main'>
58 <return type-id='95e97e5e'/>
59 </function-decl>
60 <var-decl name='test_array' type-id='b7bd1749' mangled-name='test_array' visibility='default' elf-symbol-id='test_array'/>
61 <var-decl name='test_restrict' type-id='af4b1b38' mangled-name='test_restrict' visibility='default' elf-symbol-id='test_restrict'/>
62 <var-decl name='test_volatile' type-id='ec67e496' mangled-name='test_volatile' visibility='default' elf-symbol-id='test_volatile'/>
53 </abi-instr> 63 </abi-instr>
54</abi-corpus> 64</abi-corpus>
diff --git a/tests/data/test-read-ctf/test1.so.abi b/tests/data/test-read-ctf/test1.so.abi
index 5b3caf63..416bd39d 100644
--- a/tests/data/test-read-ctf/test1.so.abi
+++ b/tests/data/test-read-ctf/test1.so.abi
@@ -16,8 +16,13 @@
16 </enum-decl> 16 </enum-decl>
17 <typedef-decl name='opaque_enum' type-id='type-id-4' id='type-id-3'/> 17 <typedef-decl name='opaque_enum' type-id='type-id-4' id='type-id-3'/>
18 <typedef-decl name='opaque_struct' type-id='type-id-2' id='type-id-5'/> 18 <typedef-decl name='opaque_struct' type-id='type-id-2' id='type-id-5'/>
19 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-6'/> 19 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
20 <pointer-type-def type-id='type-id-3' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/> 20 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
21 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/> 21 <function-decl name='fn' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='fn'>
22 <parameter type-id='type-id-7'/>
23 <parameter type-id='type-id-6'/>
24 <return type-id='type-id-8'/>
25 </function-decl>
26 <type-decl name='void' id='type-id-8'/>
22 </abi-instr> 27 </abi-instr>
23</abi-corpus> 28</abi-corpus>
diff --git a/tests/data/test-read-ctf/test1.so.hash.abi b/tests/data/test-read-ctf/test1.so.hash.abi
index 8019cb54..b3620e75 100644
--- a/tests/data/test-read-ctf/test1.so.hash.abi
+++ b/tests/data/test-read-ctf/test1.so.hash.abi
@@ -16,8 +16,13 @@
16 </enum-decl> 16 </enum-decl>
17 <typedef-decl name='opaque_enum' type-id='55763a91' id='99fcd3a5'/> 17 <typedef-decl name='opaque_enum' type-id='55763a91' id='99fcd3a5'/>
18 <typedef-decl name='opaque_struct' type-id='6cde5052' id='dae69ca1'/> 18 <typedef-decl name='opaque_struct' type-id='6cde5052' id='dae69ca1'/>
19 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='f0981eeb'/>
20 <pointer-type-def type-id='99fcd3a5' size-in-bits='64' alignment-in-bits='64' id='0e0526e0'/> 19 <pointer-type-def type-id='99fcd3a5' size-in-bits='64' alignment-in-bits='64' id='0e0526e0'/>
21 <pointer-type-def type-id='dae69ca1' size-in-bits='64' alignment-in-bits='64' id='3f6e71d0'/> 20 <pointer-type-def type-id='dae69ca1' size-in-bits='64' alignment-in-bits='64' id='3f6e71d0'/>
21 <function-decl name='fn' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='fn'>
22 <parameter type-id='3f6e71d0'/>
23 <parameter type-id='0e0526e0'/>
24 <return type-id='48b5725f'/>
25 </function-decl>
26 <type-decl name='void' id='48b5725f'/>
22 </abi-instr> 27 </abi-instr>
23</abi-corpus> 28</abi-corpus>
diff --git a/tests/data/test-read-ctf/test2.so.abi b/tests/data/test-read-ctf/test2.so.abi
index eb6aff3e..67f802f9 100644
--- a/tests/data/test-read-ctf/test2.so.abi
+++ b/tests/data/test-read-ctf/test2.so.abi
@@ -20,6 +20,14 @@
20 <qualified-type-def type-id='type-id-8' const='yes' id='type-id-9'/> 20 <qualified-type-def type-id='type-id-8' const='yes' id='type-id-9'/>
21 <pointer-type-def type-id='type-id-9' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/> 21 <pointer-type-def type-id='type-id-9' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
22 <pointer-type-def type-id='type-id-8' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 22 <pointer-type-def type-id='type-id-8' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
23 <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='bar'>
24 <parameter type-id='type-id-7'/>
25 <return type-id='type-id-8'/>
26 </function-decl>
27 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'>
28 <parameter type-id='type-id-6'/>
29 <return type-id='type-id-8'/>
30 </function-decl>
23 <type-decl name='void' id='type-id-8'/> 31 <type-decl name='void' id='type-id-8'/>
24 </abi-instr> 32 </abi-instr>
25</abi-corpus> 33</abi-corpus>
diff --git a/tests/data/test-read-ctf/test2.so.hash.abi b/tests/data/test-read-ctf/test2.so.hash.abi
index 6e57333b..6bbf347e 100644
--- a/tests/data/test-read-ctf/test2.so.hash.abi
+++ b/tests/data/test-read-ctf/test2.so.hash.abi
@@ -20,6 +20,14 @@
20 <qualified-type-def type-id='48b5725f' const='yes' id='8581546e'/> 20 <qualified-type-def type-id='48b5725f' const='yes' id='8581546e'/>
21 <pointer-type-def type-id='8581546e' size-in-bits='64' alignment-in-bits='64' id='6e97a70c'/> 21 <pointer-type-def type-id='8581546e' size-in-bits='64' alignment-in-bits='64' id='6e97a70c'/>
22 <pointer-type-def type-id='48b5725f' size-in-bits='64' alignment-in-bits='64' id='eaa32e2f'/> 22 <pointer-type-def type-id='48b5725f' size-in-bits='64' alignment-in-bits='64' id='eaa32e2f'/>
23 <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='bar'>
24 <parameter type-id='5e30a4f9'/>
25 <return type-id='48b5725f'/>
26 </function-decl>
27 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'>
28 <parameter type-id='842ea234'/>
29 <return type-id='48b5725f'/>
30 </function-decl>
23 <type-decl name='void' id='48b5725f'/> 31 <type-decl name='void' id='48b5725f'/>
24 </abi-instr> 32 </abi-instr>
25</abi-corpus> 33</abi-corpus>
diff --git a/tests/data/test-read-ctf/test3.so.abi b/tests/data/test-read-ctf/test3.so.abi
index 9d55fec5..3d2f6326 100644
--- a/tests/data/test-read-ctf/test3.so.abi
+++ b/tests/data/test-read-ctf/test3.so.abi
@@ -8,5 +8,9 @@
8 <elf-symbol name='foo__' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/> 8 <elf-symbol name='foo__' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
9 </elf-function-symbols> 9 </elf-function-symbols>
10 <abi-instr address-size='64' language='LANG_C'> 10 <abi-instr address-size='64' language='LANG_C'>
11 <function-decl name='__foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='__foo'>
12 <return type-id='type-id-1'/>
13 </function-decl>
14 <type-decl name='void' id='type-id-1'/>
11 </abi-instr> 15 </abi-instr>
12</abi-corpus> 16</abi-corpus>
diff --git a/tests/data/test-read-ctf/test3.so.hash.abi b/tests/data/test-read-ctf/test3.so.hash.abi
index 9d55fec5..1c69e2e1 100644
--- a/tests/data/test-read-ctf/test3.so.hash.abi
+++ b/tests/data/test-read-ctf/test3.so.hash.abi
@@ -8,5 +8,9 @@
8 <elf-symbol name='foo__' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/> 8 <elf-symbol name='foo__' type='func-type' binding='weak-binding' visibility='default-visibility' is-defined='yes'/>
9 </elf-function-symbols> 9 </elf-function-symbols>
10 <abi-instr address-size='64' language='LANG_C'> 10 <abi-instr address-size='64' language='LANG_C'>
11 <function-decl name='__foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='__foo'>
12 <return type-id='48b5725f'/>
13 </function-decl>
14 <type-decl name='void' id='48b5725f'/>
11 </abi-instr> 15 </abi-instr>
12</abi-corpus> 16</abi-corpus>
diff --git a/tests/data/test-read-ctf/test4.so.abi b/tests/data/test-read-ctf/test4.so.abi
index b8e0ead3..dc18e191 100644
--- a/tests/data/test-read-ctf/test4.so.abi
+++ b/tests/data/test-read-ctf/test4.so.abi
@@ -10,5 +10,11 @@
10 <qualified-type-def type-id='type-id-1' const='yes' id='type-id-5'/> 10 <qualified-type-def type-id='type-id-1' const='yes' id='type-id-5'/>
11 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/> 11 <pointer-type-def type-id='type-id-5' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
12 <qualified-type-def type-id='type-id-6' restrict='yes' id='type-id-7'/> 12 <qualified-type-def type-id='type-id-6' restrict='yes' id='type-id-7'/>
13 <function-decl name='cpy' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='cpy'>
14 <parameter type-id='type-id-4'/>
15 <parameter type-id='type-id-7'/>
16 <parameter type-id='type-id-2'/>
17 <return type-id='type-id-3'/>
18 </function-decl>
13 </abi-instr> 19 </abi-instr>
14</abi-corpus> 20</abi-corpus>
diff --git a/tests/data/test-read-ctf/test4.so.hash.abi b/tests/data/test-read-ctf/test4.so.hash.abi
index dbe34d9c..dc428592 100644
--- a/tests/data/test-read-ctf/test4.so.hash.abi
+++ b/tests/data/test-read-ctf/test4.so.hash.abi
@@ -10,5 +10,11 @@
10 <qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/> 10 <qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
11 <pointer-type-def type-id='9b45d938' size-in-bits='64' alignment-in-bits='64' id='80f4b756'/> 11 <pointer-type-def type-id='9b45d938' size-in-bits='64' alignment-in-bits='64' id='80f4b756'/>
12 <qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/> 12 <qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
13 <function-decl name='cpy' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='cpy'>
14 <parameter type-id='266fe297'/>
15 <parameter type-id='9d26089a'/>
16 <parameter type-id='f0981eeb'/>
17 <return type-id='26a90f95'/>
18 </function-decl>
13 </abi-instr> 19 </abi-instr>
14</abi-corpus> 20</abi-corpus>
diff --git a/tests/data/test-read-ctf/test5.o.abi b/tests/data/test-read-ctf/test5.o.abi
index eb30cf6a..f7bcdeb1 100644
--- a/tests/data/test-read-ctf/test5.o.abi
+++ b/tests/data/test-read-ctf/test5.o.abi
@@ -17,34 +17,32 @@
17 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/> 17 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
18 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/> 18 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-5'/>
19 <type-decl name='long long int' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/> 19 <type-decl name='long long int' size-in-bits='64' alignment-in-bits='64' id='type-id-6'/>
20 <type-decl name='long long unsigned int' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/> 20 <typedef-decl name='long_long' type-id='type-id-6' id='type-id-7'/>
21 <typedef-decl name='long_long' type-id='type-id-6' id='type-id-8'/> 21 <pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/>
22 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-9'/> 22 <qualified-type-def type-id='type-id-4' const='yes' id='type-id-9'/>
23 <pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-10'/> 23 <qualified-type-def type-id='type-id-5' const='yes' id='type-id-10'/>
24 <qualified-type-def type-id='type-id-4' const='yes' id='type-id-11'/> 24 <qualified-type-def type-id='type-id-10' volatile='yes' id='type-id-11'/>
25 <qualified-type-def type-id='type-id-5' const='yes' id='type-id-12'/> 25 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'>
26 <qualified-type-def type-id='type-id-12' volatile='yes' id='type-id-13'/> 26 <parameter type-id='type-id-8'/>
27 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 27 <parameter type-id='type-id-11'/>
28 <parameter type-id='type-id-10'/>
29 <parameter type-id='type-id-13'/>
30 <return type-id='type-id-5'/> 28 <return type-id='type-id-5'/>
31 </function-decl> 29 </function-decl>
32 <function-decl name='baz2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 30 <function-decl name='baz2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='baz2'>
33 <parameter type-id='type-id-4'/> 31 <parameter type-id='type-id-4'/>
34 <return type-id='type-id-8'/> 32 <return type-id='type-id-7'/>
35 </function-decl> 33 </function-decl>
36 <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 34 <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='bar'>
37 <parameter is-variadic='yes'/> 35 <parameter is-variadic='yes'/>
38 <return type-id='type-id-14'/> 36 <return type-id='type-id-12'/>
39 </function-decl> 37 </function-decl>
40 <function-decl name='bar2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 38 <function-decl name='bar2' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='bar2'>
41 <parameter type-id='type-id-3'/> 39 <parameter type-id='type-id-3'/>
42 <return type-id='type-id-14'/> 40 <return type-id='type-id-12'/>
43 </function-decl> 41 </function-decl>
44 <function-decl name='baz' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 42 <function-decl name='baz' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='baz'>
45 <parameter type-id='type-id-4'/> 43 <parameter type-id='type-id-4'/>
46 <return type-id='type-id-14'/> 44 <return type-id='type-id-12'/>
47 </function-decl> 45 </function-decl>
48 <type-decl name='void' id='type-id-14'/> 46 <type-decl name='void' id='type-id-12'/>
49 </abi-instr> 47 </abi-instr>
50</abi-corpus> 48</abi-corpus>
diff --git a/tests/data/test-read-ctf/test7.o.abi b/tests/data/test-read-ctf/test7.o.abi
index b744fac5..a13af174 100644
--- a/tests/data/test-read-ctf/test7.o.abi
+++ b/tests/data/test-read-ctf/test7.o.abi
@@ -3,40 +3,31 @@
3 <elf-symbol name='first_type_constructor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> 3 <elf-symbol name='first_type_constructor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
4 </elf-function-symbols> 4 </elf-function-symbols>
5 <abi-instr address-size='64' language='LANG_C'> 5 <abi-instr address-size='64' language='LANG_C'>
6 <type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/> 6 <class-decl name='first_type' size-in-bits='128' alignment-in-bits='32' is-struct='yes' visibility='default' id='type-id-1'>
7 <class-decl name='first_type' size-in-bits='128' alignment-in-bits='32' is-struct='yes' visibility='default' id='type-id-2'>
8 <data-member access='public' layout-offset-in-bits='0'> 7 <data-member access='public' layout-offset-in-bits='0'>
9 <var-decl name='member0' type-id='type-id-3' visibility='default'/> 8 <var-decl name='member0' type-id='type-id-2' visibility='default'/>
10 </data-member> 9 </data-member>
11 <data-member access='public' layout-offset-in-bits='32'> 10 <data-member access='public' layout-offset-in-bits='32'>
12 <var-decl name='member1' type-id='type-id-4' visibility='default'/> 11 <var-decl name='member1' type-id='type-id-3' visibility='default'/>
13 </data-member> 12 </data-member>
14 <data-member access='public' layout-offset-in-bits='64'> 13 <data-member access='public' layout-offset-in-bits='64'>
15 <var-decl name='ctor' type-id='type-id-5' visibility='default'/> 14 <var-decl name='ctor' type-id='type-id-4' visibility='default'/>
16 </data-member> 15 </data-member>
17 </class-decl> 16 </class-decl>
18 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-6'/> 17 <type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-5'/>
19 <type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/> 18 <typedef-decl name='character' type-id='type-id-6' id='type-id-3'/>
20 <type-decl name='long long int' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/> 19 <typedef-decl name='constructor' type-id='type-id-7' id='type-id-4'/>
21 <type-decl name='long long unsigned int' size-in-bits='64' alignment-in-bits='64' id='type-id-9'/> 20 <typedef-decl name='integer' type-id='type-id-5' id='type-id-2'/>
22 <type-decl name='short int' size-in-bits='16' alignment-in-bits='16' id='type-id-10'/> 21 <type-decl name='unsigned char' size-in-bits='8' alignment-in-bits='8' id='type-id-6'/>
23 <type-decl name='signed char' size-in-bits='8' alignment-in-bits='8' id='type-id-11'/> 22 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-8'/>
24 <typedef-decl name='character' type-id='type-id-12' id='type-id-4'/> 23 <pointer-type-def type-id='type-id-9' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
25 <typedef-decl name='constructor' type-id='type-id-13' id='type-id-5'/> 24 <function-decl name='first_type_constructor' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='first_type_constructor'>
26 <typedef-decl name='integer' type-id='type-id-6' id='type-id-3'/> 25 <parameter type-id='type-id-8'/>
27 <type-decl name='unsigned char' size-in-bits='8' alignment-in-bits='8' id='type-id-12'/> 26 <return type-id='type-id-10'/>
28 <type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-14'/>
29 <type-decl name='unsigned long int' size-in-bits='64' alignment-in-bits='64' id='type-id-15'/>
30 <type-decl name='unsigned short int' size-in-bits='16' alignment-in-bits='16' id='type-id-16'/>
31 <pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-17'/>
32 <pointer-type-def type-id='type-id-18' size-in-bits='64' alignment-in-bits='64' id='type-id-13'/>
33 <function-decl name='first_type_constructor' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'>
34 <parameter type-id='type-id-17'/>
35 <return type-id='type-id-19'/>
36 </function-decl> 27 </function-decl>
37 <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-18'> 28 <function-type size-in-bits='64' alignment-in-bits='8' id='type-id-9'>
38 <return type-id='type-id-19'/> 29 <return type-id='type-id-10'/>
39 </function-type> 30 </function-type>
40 <type-decl name='void' id='type-id-19'/> 31 <type-decl name='void' id='type-id-10'/>
41 </abi-instr> 32 </abi-instr>
42</abi-corpus> 33</abi-corpus>
diff --git a/tests/data/test-read-ctf/test8.o.abi b/tests/data/test-read-ctf/test8.o.abi
index 68b3af06..b6996c29 100644
--- a/tests/data/test-read-ctf/test8.o.abi
+++ b/tests/data/test-read-ctf/test8.o.abi
@@ -4,7 +4,7 @@
4 </elf-function-symbols> 4 </elf-function-symbols>
5 <abi-instr address-size='64' language='LANG_C'> 5 <abi-instr address-size='64' language='LANG_C'>
6 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 6 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
7 <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 7 <function-decl name='bar' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='bar'>
8 <parameter type-id='type-id-2'/> 8 <parameter type-id='type-id-2'/>
9 <return type-id='type-id-1'/> 9 <return type-id='type-id-1'/>
10 </function-decl> 10 </function-decl>
diff --git a/tests/data/test-read-ctf/test9.o.abi b/tests/data/test-read-ctf/test9.o.abi
index 746dd77b..08704d79 100644
--- a/tests/data/test-read-ctf/test9.o.abi
+++ b/tests/data/test-read-ctf/test9.o.abi
@@ -49,7 +49,7 @@
49 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/> 49 <pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
50 <pointer-type-def type-id='type-id-16' size-in-bits='64' alignment-in-bits='64' id='type-id-17'/> 50 <pointer-type-def type-id='type-id-16' size-in-bits='64' alignment-in-bits='64' id='type-id-17'/>
51 <pointer-type-def type-id='type-id-18' size-in-bits='64' alignment-in-bits='64' id='type-id-20'/> 51 <pointer-type-def type-id='type-id-18' size-in-bits='64' alignment-in-bits='64' id='type-id-20'/>
52 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8'> 52 <function-decl name='foo' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='8' elf-symbol-id='foo'>
53 <parameter type-id='type-id-22'/> 53 <parameter type-id='type-id-22'/>
54 <return type-id='type-id-16'/> 54 <return type-id='type-id-16'/>
55 </function-decl> 55 </function-decl>
diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc
index fdf49e90..215ed8d6 100644
--- a/tests/test-read-ctf.cc
+++ b/tests/test-read-ctf.cc
@@ -269,20 +269,28 @@ static InOutSpec in_out_specs[] =
269 "output/test-read-ctf/test-list-struct.abi", 269 "output/test-read-ctf/test-list-struct.abi",
270 }, 270 },
271 { 271 {
272 "data/test-read-ctf/test-callback2.o", 272 "data/test-read-common/test-PR26568-1.o",
273 "", 273 "",
274 "", 274 "",
275 SEQUENCE_TYPE_ID_STYLE, 275 SEQUENCE_TYPE_ID_STYLE,
276 "data/test-read-ctf/test-callback2.abi", 276 "data/test-read-ctf/test-PR26568-1.o.abi",
277 "output/test-read-ctf/test-callback2.abi", 277 "output/test-read-ctf/test-PR26568-1.o.abi",
278 }, 278 },
279 { 279 {
280 "data/test-read-ctf/test-forward-undefine-type-decl.o", 280 "data/test-read-common/test-PR26568-2.o",
281 "", 281 "",
282 "", 282 "",
283 SEQUENCE_TYPE_ID_STYLE, 283 SEQUENCE_TYPE_ID_STYLE,
284 "data/test-read-ctf/test-forward-undefine-type-decl.abi", 284 "data/test-read-ctf/test-PR26568-2.o.abi",
285 "output/test-read-ctf/test-forward-undefine-type-decl.abi", 285 "output/test-read-ctf/test-PR26568-2.o.abi",
286 },
287 {
288 "data/test-read-ctf/test-callback2.o",
289 "",
290 "",
291 SEQUENCE_TYPE_ID_STYLE,
292 "data/test-read-ctf/test-callback2.abi",
293 "output/test-read-ctf/test-callback2.abi",
286 }, 294 },
287 // This should be the last entry. 295 // This should be the last entry.
288 {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} 296 {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL}
diff --git a/tools/abidw.cc b/tools/abidw.cc
index f7a8937d..32d055f5 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -811,13 +811,18 @@ load_kernel_corpus_group_and_write_abixml(char* argv[],
811 811
812 global_timer.start(); 812 global_timer.start();
813 t.start(); 813 t.start();
814corpus::origin origin =
815#ifdef WITH_CTF
816 opts.use_ctf ? corpus::CTF_ORIGIN :
817#endif
818 corpus::DWARF_ORIGIN;
814 corpus_group_sptr group = 819 corpus_group_sptr group =
815 build_corpus_group_from_kernel_dist_under(opts.in_file_path, 820 build_corpus_group_from_kernel_dist_under(opts.in_file_path,
816 /*debug_info_root=*/"", 821 /*debug_info_root=*/"",
817 opts.vmlinux, 822 opts.vmlinux,
818 opts.suppression_paths, 823 opts.suppression_paths,
819 opts.kabi_whitelist_paths, 824 opts.kabi_whitelist_paths,
820 supprs, opts.do_log, env); 825 supprs, opts.do_log, env, origin);
821 t.stop(); 826 t.stop();
822 827
823 if (opts.do_log) 828 if (opts.do_log)