From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by sourceware.org (Postfix) with ESMTPS id 55A253858C62 for ; Mon, 28 Nov 2022 15:57:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 55A253858C62 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=seketeli.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=seketeli.org Received: (Authenticated sender: dodji@seketeli.org) by mail.gandi.net (Postfix) with ESMTPSA id C070CFF803; Mon, 28 Nov 2022 15:56:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=seketeli.org; s=gm1; t=1669651019; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6CxLDdp3xd7eyHrfjtwzpTYyl6nGcLPkgMxwi6m9mDo=; b=e+cHX6gURDefPopD5ZP3gKXSmpS8CVuyGsB3+7iUYAqnZ56hOyIp0CcKOUXnlNtmCH5/kv HXM3ehuB8esrauFdtys/qcZDFje6zlA5zenHnq0+TK07OlSAD6FAlv4JDgrGgSYVnF90CN d2LqUvNyExmYaboXDfkHgoLBukh5UoC+7aUnytjfX1JaHHOeMJz54yN/Byg9UtYz+cbOLh VpQ8k0B3Xsg+JOEVyV4vRrKzdKZmSLzgxZiEzGQbb+LjqIkaA+QSDBPfYwyBYpf7DGq3i4 /O37kvxAUWPWq6mjLlGcItoXYEOIefXevKX781AmJhtE5lnxhttaI8oYcvx93w== Received: by localhost (Postfix, from userid 1000) id D9605581C59; Mon, 28 Nov 2022 16:56:57 +0100 (CET) From: Dodji Seketeli To: "Guillermo E. Martinez via Libabigail" Cc: "Guillermo E. Martinez" Subject: Re: [PATCH v4] ELF based front-end readers fallback feature Organization: Me, myself and I References: <20221121185102.1163007-1-guillermo.e.martinez@oracle.com> <20221122160050.2031623-1-guillermo.e.martinez@oracle.com> X-Operating-System: Fedora 38 X-URL: http://www.seketeli.net/~dodji Date: Mon, 28 Nov 2022 16:56:57 +0100 In-Reply-To: <20221122160050.2031623-1-guillermo.e.martinez@oracle.com> (Guillermo E. Martinez via Libabigail's message of "Tue, 22 Nov 2022 10:00:50 -0600") Message-ID: <87fse3oywm.fsf@seketeli.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,JMQ_SPF_NEUTRAL,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hello Guillermo, Many thanks for the update! The patch looks good to me. I have amended it somewhat and applied the result to the master branch. Please find below my comments. "Guillermo E. Martinez via Libabigail" a =C3=A9crit: > By default, `abidw', `abidiff', `abipkgdiff' and `kmidiff' tools use > debug information in `DWARF` format, if present, otherwise now > automatically the tools try to extract and build the IR using > debug information in `CTF` format without use of `--ctf' option, if > present, finally, if neither is found, they use only `ELF` symbols to > extract, build, compare and report the binary IR. To force the use of > CTF front-end the `--ctf' option should be pass to command line. > > It works for libraries and Linux kernel. The `--ctf' option is > preserved to explicitly indicate to those tools that we want to use > CTF support. By other hand, if tools use `--ctf' but binary doesn't > have CTF debug information it looks for DWARF automatically. I have slightly amended this part of the commit log. You'll see the resulting patch at the very end of this message. [...] > diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc > index 5fde94f3..fdefd3a6 100644 > --- a/src/abg-ctf-reader.cc > +++ b/src/abg-ctf-reader.cc [...] > /// Getter of the environment of the current CTF reader. > /// > /// @return the environment of the current CTF reader. > @@ -349,27 +355,24 @@ public: > // Read the ELF-specific parts of the corpus. > elf::reader::read_corpus(status); >=20=20 > - if ((status & STATUS_NO_SYMBOLS_FOUND) > - || !(status & STATUS_OK)) > - // Either we couldn't find ELF symbols or something went badly > - // wrong. There is nothing we can do with this ELF file. Bail > - // out. > - return; > - > corpus_sptr corp =3D corpus(); > if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN) > && corpus_group()) > { > - status |=3D fe_iface::STATUS_OK; > + // Is expected not find debug information when we're building > + // a kABI. I have slightly amended the comment here to make it read like this: + // Not finding any debug info so far is expected if we are + // building a kABI. > + status &=3D static_cast > + (~STATUS_DEBUG_INFO_NOT_FOUND); > return; > } >=20=20 > - /* Get the raw ELF section contents for libctf. */ > - if (!find_ctf_section()) > - { > - status |=3D fe_iface::STATUS_DEBUG_INFO_NOT_FOUND; > - return; > - } > + if ((status & (STATUS_NO_SYMBOLS_FOUND | > + STATUS_DEBUG_INFO_NOT_FOUND)) > + || !(status & STATUS_OK)) the STATUS_DEBUG_INFO_NOT_FOUND bit cannot be set here because you have unset it above by doing: > + status &=3D static_cast > + (~STATUS_DEBUG_INFO_NOT_FOUND); So I have changed that condition to make it read: + if ((status & STATUS_NO_SYMBOLS_FOUND) + || !(status & STATUS_OK)) [...] > diff --git a/src/abg-elf-reader.cc b/src/abg-elf-reader.cc > index eedeaf8e..3f191bda 100644 > --- a/src/abg-elf-reader.cc > +++ b/src/abg-elf-reader.cc [...] >=20=20 > +bool > +reader::has_dwarf_debug_info() const I have added a doxygen comment to this function. > +{return ((priv_->dwarf_handle !=3D nullptr) > + || (priv_->alt_dwarf_handle !=3D nullptr));} > + > +bool > +reader::has_ctf_debug_info() const Likewise. > +{return (priv_->ctf_section !=3D nullptr);} > + [...] > diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc > index 8898ef97..0a523b87 100644 [...] > diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h > index 9dc9b8d3..13d6ad75 100644 > --- a/include/abg-tools-utils.h > +++ b/include/abg-tools-utils.h > @@ -322,7 +322,10 @@ build_corpus_group_from_kernel_dist_under(const stri= ng& root, > elf_based_reader_sptr > create_best_elf_based_reader(const string& elf_file_path, > const vector& debug_info_root_paths, > - environment& env); > + environment& env, > + bool use_ctf, Rather than adding a boolean here, I have added a parameter 'corpus::origin requested_fe_kind'. This is basically the kind of front-end requested by the user when invoking the tool. For instance, if --ctf is provided on the command line, requested_fe_kind should be set to corpus::CTF_ORIGIN. If nothing is provided on the command line, either requested_fe_kind could be set to either corpus::ARTIFICIAL_ORIGIN or corpus::DWARF_ORIGIN. When we have another kind of front-end tomorrow, requested_fe_kind will still be able to be used because that new front-end is likely to be for a new kind corpus::origin. So, I think that doing this is a more generic solution. > + bool show_all_types, > + bool linux_kernel_mode =3D false); >=20=20 > }// end namespace tools_utils >=20=20 > --- a/src/abg-tools-utils.cc > +++ b/src/abg-tools-utils.cc > @@ -405,6 +405,23 @@ is_regular_file(const string& path) > return false; > } [...] > @@ -2853,13 +2807,16 @@ build_corpus_group_from_kernel_dist_under(const s= tring& root, > /// Create the best elf based reader (or front-end), given an ELF file. > /// > /// This function looks into the ELF file. If it contains DWARF debug > -/// info, then a DWARF Reader front-end is created and returned. > -/// Otherwise, if it contains CTF debug info, then a CTF Reader > -/// front-end is created and returned. > +/// info, then a DWARF Reader front-end is created and returned, unless > +/// that @ref use_ctf be true. Otherwise, if it contains CTF debug info, > +/// then a CTF Reader front-end is created and returned. > +/// > +/// By other hand, it selects the DWARF front-end when @ref use_ctf is > +/// true but ELF file doesn't have CTF debug information. > /// > /// Otherwise, if the file contains no debug info or if the king of > -/// debug info is not yet recognized, a DWARF Reader front-end is > -/// created and returned. > +/// debug info is not yet recognized, a DWARF or CTF Reader front-end is > +/// created and returned depending of @ref use_ctf parameter. > /// > /// @param elf_file_path a path to the ELF file to consider > /// > @@ -2868,32 +2825,62 @@ build_corpus_group_from_kernel_dist_under(const s= tring& root, > /// > /// @param env the environment to use for the front-end. > /// > +/// @param use_ctf set to true if it's going to use CTF front-end. > +/// > +/// @param show_all_types option to be passed to elf based readers. > +/// > +/// @param linux_kernel_mode option to bed passed to elf based readers, > +/// > /// @return the ELF based Reader that is better adapted for the binary > /// designated by @p elf_file_path. > elf_based_reader_sptr > create_best_elf_based_reader(const string& elf_file_path, > const vector& debug_info_root_paths, > - environment& env) > + environment& env, > + bool use_ctf, > + bool show_all_types, > + bool linux_kernel_mode) Following my comment above about the declaration of this function, I have updated its definition here. Near the end of this message, I'll paste my changes against the tree containing your patch, so that you can see clearly the changes I've made to create_best_elf_based_reader and to all the other related parts of the patch. But right now, please find the hunk I have come up with about this specific location of the source code: -/// Create the best elf based reader (or front-end), given an ELF file. +/// Create the best elf based reader (or front-end), given an ELF +/// file. +/// +/// This function looks into the ELF file; depending on the kind of +/// debug info it contains and on the request of the user, the "best" +/// front-end is created. /// -/// This function looks into the ELF file. If it contains DWARF debug -/// info, then a DWARF Reader front-end is created and returned, unless -/// that @ref use_ctf be true. Otherwise, if it contains CTF debug in= fo, -/// then a CTF Reader front-end is created and returned. +/// If the user requested the use of the CTF front-end, then, if the +/// file contains CTF debug info, the CTF front-end is created, +/// assuming libabigail is built with CTF support. /// -/// By other hand, it selects the DWARF front-end when @ref use_ctf is -/// true but ELF file doesn't have CTF debug information. +/// If the binary ONLY has CTF debug info, then CTF front-end is +/// created, even if the user hasn't explicitly requested the creation +/// of the CTF front-end. /// -/// Otherwise, if the file contains no debug info or if the king of -/// debug info is not yet recognized, a DWARF or CTF Reader front-end= is -/// created and returned depending of @ref use_ctf parameter. +/// Otherwise, by default, the DWARF front-end is created. /// /// @param elf_file_path a path to the ELF file to consider /// @@ -2825,7 +2824,10 @@ build_corpus_group_from_kernel_dist_under(const = string& root, /// /// @param env the environment to use for the front-end. /// -/// @param use_ctf set to true if it's going to use CTF front-end. +/// @param requested_fe_kind the kind of front-end specifically +/// requested by the user. At the moment, only the CTF front-end can +/// be requested, using the "--ctf" command line option on some tools +/// using the library. /// /// @param show_all_types option to be passed to elf based readers. /// @@ -2837,7 +2839,7 @@ elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_path= s, environment& env, - bool use_ctf, + corpus::origin requested_fe_kind, bool show_all_types, bool linux_kernel_mode) { @@ -2845,41 +2847,36 @@ create_best_elf_based_reader(const string& elf_= file_path, if (guess_file_type(elf_file_path) !=3D FILE_TYPE_ELF) return result; + if (requested_fe_kind & corpus::CTF_ORIGIN) + { #ifdef WITH_CTF - if (!use_ctf) + if (file_has_ctf_debug_info(elf_file_path, debug_info_root_paths= )) + result =3D ctf::create_reader(elf_file_path, debug_info_root_paths, e= nv); +#endif + } + else { + // The user hasn't formally requested the use of the CTF front-e= nd. +#ifdef WITH_CTF + if (!file_has_dwarf_debug_info(elf_file_path, debug_info_root_pa= ths) + && file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) + // The file has CTF debug info and no DWARF, let's use the CTF + // front end even if it wasn't formally requested by the user. + result =3D ctf::create_reader(elf_file_path, debug_info_root_paths, e= nv); #endif + } + + if (!result) + { + // This is the default case. At worst, the DWARF reader knows + // how to handle just ELF data for the case where there is no + // DWARF debug info present. result =3D dwarf::create_reader(elf_file_path, debug_info_root_paths, env, show_all_types, linux_kernel_mode); -#ifdef WITH_CTF - if (!file_has_dwarf_debug_info(elf_file_path, - debug_info_root_paths) - && file_has_ctf_debug_info(elf_file_path, - debug_info_root_paths)) - result =3D ctf::create_reader(elf_file_path, - debug_info_root_paths, - env); } - else - { - result =3D ctf::create_reader(elf_file_path, - debug_info_root_paths, - env); - - if (!file_has_ctf_debug_info(elf_file_path, - debug_info_root_paths) - && file_has_dwarf_debug_info(elf_file_path, - debug_info_root_paths)) - result =3D dwarf::create_reader(elf_file_path, - debug_info_root_paths, - env, - show_all_types, - linux_kernel_mode); - } -#endif return result; } [...] I have adjusted the rest of the code accordingly. Please find below the diff of my changed related to create_best_elf_based_reader and to other related parts. --------------------------->8<------------------------------------------ diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h index 13d6ad75..3d7f0d23 100644 --- a/include/abg-tools-utils.h +++ b/include/abg-tools-utils.h @@ -317,13 +317,13 @@ build_corpus_group_from_kernel_dist_under(const strin= g& root, suppr::suppressions_type& supprs, bool verbose, environment& env, - corpus::origin origin =3D corpus::DWARF_ORIGIN); + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN); =20 elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_paths, environment& env, - bool use_ctf, + corpus::origin requested_debug_info_kind, bool show_all_types, bool linux_kernel_mode =3D false); =20 diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index 0a523b87..b089b69c 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -2755,7 +2755,7 @@ build_corpus_group_from_kernel_dist_under(const strin= g& root, suppressions_type& supprs, bool verbose, environment& env, - corpus::origin origin) + corpus::origin requested_fe_kind) { string vmlinux =3D vmlinux_path; corpus_group_sptr group; @@ -2787,11 +2787,7 @@ build_corpus_group_from_kernel_dist_under(const stri= ng& root, create_best_elf_based_reader(vmlinux, di_roots, env, -#ifdef WITH_CTF - origin & corpus::CTF_ORIGIN, -#else - false, -#endif + requested_fe_kind, /*read_all_types=3D*/false, /*linux_kernel_mode=3D*/true); ABG_ASSERT(reader); @@ -2804,19 +2800,22 @@ build_corpus_group_from_kernel_dist_under(const str= ing& root, return group; } =20 -/// Create the best elf based reader (or front-end), given an ELF file. +/// Create the best elf based reader (or front-end), given an ELF +/// file. +/// +/// This function looks into the ELF file; depending on the kind of +/// debug info it contains and on the request of the user, the "best" +/// front-end is created. /// -/// This function looks into the ELF file. If it contains DWARF debug -/// info, then a DWARF Reader front-end is created and returned, unless -/// that @ref use_ctf be true. Otherwise, if it contains CTF debug info, -/// then a CTF Reader front-end is created and returned. +/// If the user requested the use of the CTF front-end, then, if the +/// file contains CTF debug info, the CTF front-end is created, +/// assuming libabigail is built with CTF support. /// -/// By other hand, it selects the DWARF front-end when @ref use_ctf is -/// true but ELF file doesn't have CTF debug information. +/// If the binary ONLY has CTF debug info, then CTF front-end is +/// created, even if the user hasn't explicitly requested the creation +/// of the CTF front-end. /// -/// Otherwise, if the file contains no debug info or if the king of -/// debug info is not yet recognized, a DWARF or CTF Reader front-end is -/// created and returned depending of @ref use_ctf parameter. +/// Otherwise, by default, the DWARF front-end is created. /// /// @param elf_file_path a path to the ELF file to consider /// @@ -2825,7 +2824,10 @@ build_corpus_group_from_kernel_dist_under(const stri= ng& root, /// /// @param env the environment to use for the front-end. /// -/// @param use_ctf set to true if it's going to use CTF front-end. +/// @param requested_fe_kind the kind of front-end specifically +/// requested by the user. At the moment, only the CTF front-end can +/// be requested, using the "--ctf" command line option on some tools +/// using the library. /// /// @param show_all_types option to be passed to elf based readers. /// @@ -2837,7 +2839,7 @@ elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_paths, environment& env, - bool use_ctf, + corpus::origin requested_fe_kind, bool show_all_types, bool linux_kernel_mode) { @@ -2845,41 +2847,36 @@ create_best_elf_based_reader(const string& elf_file= _path, if (guess_file_type(elf_file_path) !=3D FILE_TYPE_ELF) return result; =20 + if (requested_fe_kind & corpus::CTF_ORIGIN) + { #ifdef WITH_CTF - if (!use_ctf) + if (file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) + result =3D ctf::create_reader(elf_file_path, debug_info_root_paths, env); +#endif + } + else { + // The user hasn't formally requested the use of the CTF front-end. +#ifdef WITH_CTF + if (!file_has_dwarf_debug_info(elf_file_path, debug_info_root_paths) + && file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) + // The file has CTF debug info and no DWARF, let's use the CTF + // front end even if it wasn't formally requested by the user. + result =3D ctf::create_reader(elf_file_path, debug_info_root_paths, env); #endif + } + + if (!result) + { + // This is the default case. At worst, the DWARF reader knows + // how to handle just ELF data for the case where there is no + // DWARF debug info present. result =3D dwarf::create_reader(elf_file_path, debug_info_root_paths, env, show_all_types, linux_kernel_mode); -#ifdef WITH_CTF - if (!file_has_dwarf_debug_info(elf_file_path, - debug_info_root_paths) - && file_has_ctf_debug_info(elf_file_path, - debug_info_root_paths)) - result =3D ctf::create_reader(elf_file_path, - debug_info_root_paths, - env); } - else - { - result =3D ctf::create_reader(elf_file_path, - debug_info_root_paths, - env); - - if (!file_has_ctf_debug_info(elf_file_path, - debug_info_root_paths) - && file_has_dwarf_debug_info(elf_file_path, - debug_info_root_paths)) - result =3D dwarf::create_reader(elf_file_path, - debug_info_root_paths, - env, - show_all_types, - linux_kernel_mode); - } -#endif =20 return result; } diff --git a/tools/abidiff.cc b/tools/abidiff.cc index 6cd948bf..5ffe47a3 100644 --- a/tools/abidiff.cc +++ b/tools/abidiff.cc @@ -1197,15 +1197,15 @@ main(int argc, char* argv[]) case abigail::tools_utils::FILE_TYPE_ELF: // fall through case abigail::tools_utils::FILE_TYPE_AR: { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; +#ifdef WITH_CTF + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; +#endif abigail::elf_based_reader_sptr rdr =3D create_best_elf_based_reader(opts.file1, opts.prepared_di_root_paths1, - env, -#ifdef WITH_CTF - opts.use_ctf, -#else - false, -#endif + env, requested_fe_kind, opts.show_all_types); ABG_ASSERT(rdr); =20 @@ -1271,15 +1271,15 @@ main(int argc, char* argv[]) case abigail::tools_utils::FILE_TYPE_ELF: // Fall through case abigail::tools_utils::FILE_TYPE_AR: { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; +#ifdef WITH_CTF + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; +#endif abigail::elf_based_reader_sptr rdr =3D create_best_elf_based_reader(opts.file2, opts.prepared_di_root_paths2, - env, -#ifdef WITH_CTF - opts.use_ctf, -#else - false, -#endif + env, requested_fe_kind, opts.show_all_types); ABG_ASSERT(rdr); =20 diff --git a/tools/abidw.cc b/tools/abidw.cc index d711751f..3b1a1bd5 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -553,17 +553,18 @@ load_corpus_and_write_abixml(char* argv[], =20 corpus_sptr corp; fe_iface::status s =3D fe_iface::STATUS_UNKNOWN; + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; +#ifdef WITH_CTF + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; +#endif + // First of all, create a reader to read the ABI from the file // specfied in opts ... abigail::elf_based_reader_sptr reader =3D create_best_elf_based_reader(opts.in_file_path, opts.prepared_di_root_paths, - env, -#ifdef WITH_CTF - opts.use_ctf, -#else - false, -#endif + env, requested_fe_kind, opts.load_all_types, opts.linux_kernel_mode); ABG_ASSERT(reader); @@ -819,7 +820,7 @@ load_kernel_corpus_group_and_write_abixml(char* argv[], =20 global_timer.start(); t.start(); - corpus::origin origin =3D + corpus::origin requested_fe_kind =3D #ifdef WITH_CTF opts.use_ctf ? corpus::CTF_ORIGIN : #endif @@ -830,7 +831,8 @@ load_kernel_corpus_group_and_write_abixml(char* argv[], opts.vmlinux, opts.suppression_paths, opts.kabi_whitelist_paths, - supprs, opts.do_log, env, origin); + supprs, opts.do_log, env, + requested_fe_kind); t.stop(); =20 if (opts.do_log) diff --git a/tools/abipkgdiff.cc b/tools/abipkgdiff.cc index ecdfb45f..1feb3d9e 100644 --- a/tools/abipkgdiff.cc +++ b/tools/abipkgdiff.cc @@ -1323,15 +1323,15 @@ compare(const elf_file& elf1, abigail::elf_based_reader_sptr reader; corpus_sptr corpus1; { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; +#ifdef WITH_CTF + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; +#endif abigail::elf_based_reader_sptr reader =3D create_best_elf_based_reader(elf1.path, di_dirs1, - env, -#ifdef WITH_CTF - opts.use_ctf, -#else - false, -#endif + env, requested_fe_kind, opts.show_all_types); ABG_ASSERT(reader); =20 @@ -1423,15 +1423,15 @@ compare(const elf_file& elf1, =20 corpus_sptr corpus2; { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; +#ifdef WITH_CTF + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; +#endif abigail::elf_based_reader_sptr reader =3D create_best_elf_based_reader(elf2.path, di_dirs2, - env, -#ifdef WITH_CTF - opts.use_ctf, -#else - false, -#endif + env, requested_fe_kind, opts.show_all_types); ABG_ASSERT(reader); =20 @@ -1589,15 +1589,15 @@ compare_to_self(const elf_file& elf, corpus_sptr corp; abigail::elf_based_reader_sptr reader; { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; +#ifdef WITH_CTF + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; +#endif abigail::elf_based_reader_sptr reader =3D create_best_elf_based_reader(elf.path, di_dirs, - env, -#ifdef WITH_CTF - opts.use_ctf, -#else - false, -#endif + env, requested_fe_kind, opts.show_all_types); ABG_ASSERT(reader); =20 diff --git a/tools/kmidiff.cc b/tools/kmidiff.cc index 391677ca..728392e3 100644 --- a/tools/kmidiff.cc +++ b/tools/kmidiff.cc @@ -421,7 +421,7 @@ main(int argc, char* argv[]) =20 corpus_group_sptr group1, group2; string debug_info_root_dir; - corpus::origin origin =3D + corpus::origin requested_fe_kind =3D #ifdef WITH_CTF opts.use_ctf ? corpus::CTF_ORIGIN : #endif @@ -443,8 +443,8 @@ main(int argc, char* argv[]) opts.suppression_paths, opts.kabi_whitelist_paths, opts.read_time_supprs, - opts.verbose, - env, origin); + opts.verbose, env, + requested_fe_kind); print_kernel_dist_binary_paths_under(opts.kernel_dist_root1, opts); } else if (ftype =3D=3D FILE_TYPE_XML_CORPUS_GROUP) @@ -469,8 +469,8 @@ main(int argc, char* argv[]) opts.suppression_paths, opts.kabi_whitelist_paths, opts.read_time_supprs, - opts.verbose, - env, origin); + opts.verbose, env, + requested_fe_kind); print_kernel_dist_binary_paths_under(opts.kernel_dist_root2, opts); } else if (ftype =3D=3D FILE_TYPE_XML_CORPUS_GROUP) --------------------------->8<------------------------------------------ So, in the end, please find below the whole final patch that I have applied= to the master branch. Many thanks! Cheers, >From 060b2efff7b79ef6010001289974be8fe313024d Mon Sep 17 00:00:00 2001 From: "Guillermo E. Martinez" Date: Tue, 22 Nov 2022 10:00:50 -0600 Subject: [PATCH] Use the CTF reader by default when applicable At the moment, the tools abidw, abidiff, abipkgdiff and kmidiff all use the DWARF front-end by default. When the "--ctf" option is added to the command line, they use the CTF front-end. This patch changes that behaviour in the way described below. If the "--ctf" command line option is passed to the tool and if the binary to analyze contains CTF debug info, then the CTF front-end is used. If the binary contains ONLY CTF debug info, then the CTF front-end is used, even if no "--ctf" option was provided. In all the other cases, the DWARF front-end is used. Of course, the CTF front-end is not used at all if the CTF functionality hasn't been enabled at configure time. This new behaviour is effective for user space and Linux kernel binaries. * doc/manuals/abidiff.rst: Adjust. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * doc/manuals/kmidiff.rst: Likewise. * include/abg-elf-based-reader.h (initialize): Add member function. * include/abg-elf-reader.h (has_{dwarf,ctf}_debug_info): Add predicate functions. * include/abg-tools-utils.h (create_best_elf_based_reader): Add arguments. * src/abg-ctf-reader.cc (process_ctf_typedef, process_ctf_base_type) (process_ctf_function_type, process_ctf_sou_members, process_ctf_forward_t= ype) (process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type) (process_ctf_qualified_type, process_ctf_pointer_type, process_ctf_enum_ty= pe): Remove arguments. Using getters to access required information instead. (reader::cur_tu_): Add data member. (initialize): Add arguments. (cur_transl_unit): Add {get,set)ter. (slurp_elf_info): Clear `STATUS_DEBUG_INFO_NOT_FOUND' if corpus is `LINUX_KERNEL_BINARY_ORIGIN'. (reader::lookup_type): Remove. (reader::build_type): New member function. * src/abg-elf-reader.cc (reader::reader): Locate ctf debug info from binary file. (reader::reader): Reset base `fe_iface' constructor. (reader::has_{dwarf,ctf}_debug_info): New definitions. (reader::read_corpus): Set `STATUS_DEBUG_INFO_NOT_FOUND' according to corpus::origin. * src/abg-tools-utils.cc (dir_contains_ctf_archive): Define new member. (file_has_ctf_debug_info): Looks for kernel ctf debug information archive. (maybe_load_vmlinux_{dwarf,ctf}_corpus): Remove. (load_vmlinux_corpus): Define function to load IR from kernel regardless of the corpus::origin. (build_corpus_group_from_kernel_dist_under): Use create_best_elf_based_reader to select the front-end. (create_best_elf_based_reader): Adjust to allow fallback behaviour for different front-ends. * tests/data/Makefile.am: Add tests. * tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt: Adjust. * tests/data/test-read-ctf/test-fallback.abi: New test case. * tests/data/test-read-ctf/test-fallback.c: Likewise. * tests/data/test-read-ctf/test-fallback.o: Likewise. * tests/data/test-read-dwarf/test-fallback.abi: Likewise. * tests/data/test-read-dwarf/test-fallback.c: Likewise. * tests/data/test-read-dwarf/test-fallback.o: Likewise. * tests/test-diff-pkg.cc: Adjust. * tests/test-read-common.cc (test_task::run_abidw): Use the `options:option' field. * tests/test-read-common.h (InOutSpec): Add new member. * tests/test-read-ctf.cc (in_out_specs): Add option field to test suite. Add new test case. * tests/test-read-dwarf.cc: Likewise. * tools/abidiff.cc (main): Use create_best_elf_based_reader. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Guillermo E. Martinez Signed-off-by: Dodji Seketeli --- doc/manuals/abidiff.rst | 15 +- doc/manuals/abidw.rst | 15 +- doc/manuals/abipkgdiff.rst | 13 +- doc/manuals/kmidiff.rst | 9 +- include/abg-elf-based-reader.h | 5 + include/abg-elf-reader.h | 6 + include/abg-tools-utils.h | 7 +- src/abg-ctf-reader.cc | 266 +++++++-------- src/abg-elf-reader.cc | 35 +- src/abg-tools-utils.cc | 302 ++++++++---------- tests/data/Makefile.am | 6 + .../test-diff-pkg-ctf/dirpkg-3-report-2.txt | 16 + tests/data/test-read-ctf/test-fallback.abi | 9 + tests/data/test-read-ctf/test-fallback.c | 8 + tests/data/test-read-ctf/test-fallback.o | Bin 0 -> 1216 bytes tests/data/test-read-dwarf/test-fallback.abi | 9 + tests/data/test-read-dwarf/test-fallback.c | 8 + tests/data/test-read-dwarf/test-fallback.o | Bin 0 -> 2424 bytes tests/test-diff-pkg.cc | 2 +- tests/test-read-common.cc | 5 +- tests/test-read-common.h | 1 + tests/test-read-ctf.cc | 93 ++++-- tests/test-read-dwarf.cc | 121 +++++-- tools/abidiff.cc | 44 ++- tools/abidw.cc | 32 +- tools/abipkgdiff.cc | 37 ++- tools/kmidiff.cc | 10 +- 27 files changed, 626 insertions(+), 448 deletions(-) create mode 100644 tests/data/test-read-ctf/test-fallback.abi create mode 100644 tests/data/test-read-ctf/test-fallback.c create mode 100644 tests/data/test-read-ctf/test-fallback.o create mode 100644 tests/data/test-read-dwarf/test-fallback.abi create mode 100644 tests/data/test-read-dwarf/test-fallback.c create mode 100644 tests/data/test-read-dwarf/test-fallback.o diff --git a/doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst index c728b373..a8878d2c 100644 --- a/doc/manuals/abidiff.rst +++ b/doc/manuals/abidiff.rst @@ -12,11 +12,12 @@ This tool can also compare the textual representations = of the ABI of two ELF binaries (as emitted by ``abidw``) or an ELF binary against a textual representation of another ELF binary. =20 -For a comprehensive ABI change report that includes changes about -function and variable sub-types, the two input shared libraries must -be accompanied with their debug information in `DWARF`_ format. -Otherwise, only `ELF`_ symbols that were added or removed are -reported. +For a comprehensive ABI change report between two input shared +libraries that includes changes about function and variable sub-types, +``abidiff`` uses by default, debug information in `DWARF`_ format, if +present, otherwise it compares interfaces using debug information in +`CTF`_ format, if present, finally, if neither is found, it uses only +`ELF`_ symbols to report which of them were added or removed. =20 .. include:: tools-use-libabigail.txt =20 @@ -581,7 +582,7 @@ Options =20 * ``--ctf`` =20 - When comparing binaries, extract ABI information from CTF debug + When comparing binaries, extract ABI information from `CTF`_ debug information, if present. =20 * ``--stats`` @@ -808,4 +809,4 @@ Usage examples =20 .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format .. _DWARF: http://www.dwarfstd.org - +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/= ctf-spec.pdf diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst index a3055c7e..20948805 100644 --- a/doc/manuals/abidw.rst +++ b/doc/manuals/abidw.rst @@ -8,8 +8,7 @@ representation of its ABI to standard output. The emitted representation format, named ``ABIXML``, includes all the globally defined functions and variables, along with a complete representation of their types. It also includes a representation of the globally -defined ELF symbols of the file. The input shared library must -contain associated debug information in `DWARF`_ format. +defined ELF symbols of the file. =20 When given the ``--linux-tree`` option, this program can also handle a `Linux kernel`_ tree. That is, a directory tree that contains both @@ -19,8 +18,13 @@ interface between the kernel and its module, to standard= output. In this case, we don't call it an ABI, but a KMI (Kernel Module Interface). The emitted KMI includes all the globally defined functions and variables, along with a complete representation of their -types. The input binaries must contain associated debug information -in `DWARF`_ format. +types. + +To generate either ABI or KMI representation, by default ``abidw`` +uses debug information in `DWARF`_ format, if present, otherwise it +looks for debug information in `CTF`_ format, if present, finally, if +neither is found, it uses only `ELF`_ symbols to report which of them +were added or removed. =20 .. include:: tools-use-libabigail.txt =20 @@ -326,7 +330,7 @@ Options =20 * ``--ctf`` =20 - Extract ABI information from CTF debug information, if present in + Extract ABI information from `CTF`_ debug information, if present in the given object. =20 * ``--annotate`` @@ -365,3 +369,4 @@ standard `here .. _DWARF: http://www.dwarfstd.org .. _GNU: http://www.gnu.org .. _Linux Kernel: https://kernel.org/ +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/= ctf-spec.pdf diff --git a/doc/manuals/abipkgdiff.rst b/doc/manuals/abipkgdiff.rst index 9114775a..771bb034 100644 --- a/doc/manuals/abipkgdiff.rst +++ b/doc/manuals/abipkgdiff.rst @@ -13,12 +13,18 @@ binaries. For a comprehensive ABI change report that includes changes about function and variable sub-types, the two input packages must be accompanied with their debug information packages that contain debug -information either in `DWARF`_ or in `CTF` formats. Please note +information either in `DWARF`_ or in `CTF`_ formats. Please note however that some packages contain binaries that embed the debug information directly in a section of said binaries. In those cases, obviously, no separate debug information package is needed as the tool will find the debug information inside the binaries. =20 +By default, ``abipkgdiff`` uses debug information in `DWARF`_ format, +if present, otherwise it compares binaries interfaces using debug +information in `CTF`_ format, if present, finally, if neither is +found, it uses only `ELF`_ symbols to report which of them were added +or removed. + .. include:: tools-use-libabigail.txt =20 .. _abipkgdiff_invocation_label: @@ -525,8 +531,8 @@ Options =20 * ``--ctf`` =20 - This is used to compare packages with CTF debug information, if - present. + This is used to compare packages with `CTF`_ debug information, + if present. =20 .. _abipkgdiff_return_value_label: =20 @@ -546,4 +552,5 @@ In the later case, the value of the exit code is the sa= me as for the .. _Deb: https://en.wikipedia.org/wiki/Deb_%28file_format%29 .. _tar: https://en.wikipedia.org/wiki/Tar_%28computing%29 .. _DWARF: http://www.dwarfstd.org +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/= ctf-spec.pdf .. _Development Package: https://fedoraproject.org/wiki/Packaging:Guidelin= es?rd=3DPackaging/Guidelines#Devel_Packages diff --git a/doc/manuals/kmidiff.rst b/doc/manuals/kmidiff.rst index 53010189..a27d2456 100644 --- a/doc/manuals/kmidiff.rst +++ b/doc/manuals/kmidiff.rst @@ -74,6 +74,11 @@ functions and variables) between the Kernel and its modu= les. In practice, though, some users might want to compare a subset of the those interfaces. =20 +By default, ``kmidiff`` uses debug information in `DWARF`_ format, +if present, otherwise it compares interfaces using debug information +in `CTF`_ format, if present, finally, if neither is found, it uses +only `ELF`_ symbols to report which were added or removed. + Users can then define a "white list" of the interfaces to compare. Such a white list is a just a file in the "INI" format that looks like: :: @@ -174,7 +179,7 @@ Options =20 * ``--ctf`` =20 - Extract ABI information from CTF debug information, if present in + Extract ABI information from `CTF`_ debug information, if present in the Kernel and Modules. =20 * ``--impacted-interfaces | -i`` @@ -242,3 +247,5 @@ Options .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format .. _ksymtab: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format .. _Linux Kernel: https://kernel.org +.. _DWARF: http://www.dwarfstd.org +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/= ctf-spec.pdf diff --git a/include/abg-elf-based-reader.h b/include/abg-elf-based-reader.h index cf0c719e..4fae055e 100644 --- a/include/abg-elf-based-reader.h +++ b/include/abg-elf-based-reader.h @@ -56,6 +56,11 @@ public: virtual ir::corpus_sptr read_and_add_corpus_to_group(ir::corpus_group& group, fe_iface::status& status); + virtual void + initialize(const string& elf_path, + const vector& debug_info_root_paths, + bool load_all_types, + bool linux_kernel_mode) =3D 0; };//end class elf_based_reader =20 typedef std::shared_ptr elf_based_reader_sptr; diff --git a/include/abg-elf-reader.h b/include/abg-elf-reader.h index 86999ac1..42897a92 100644 --- a/include/abg-elf-reader.h +++ b/include/abg-elf-reader.h @@ -91,6 +91,12 @@ class reader : public fe_iface const Dwarf* dwarf_debug_info() const; =20 + bool + has_dwarf_debug_info() const; + + bool + has_ctf_debug_info() const; + const Dwarf* alternate_dwarf_debug_info() const; =20 diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h index 9dc9b8d3..3d7f0d23 100644 --- a/include/abg-tools-utils.h +++ b/include/abg-tools-utils.h @@ -317,12 +317,15 @@ build_corpus_group_from_kernel_dist_under(const strin= g& root, suppr::suppressions_type& supprs, bool verbose, environment& env, - corpus::origin origin =3D corpus::DWARF_ORIGIN); + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN); =20 elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_paths, - environment& env); + environment& env, + corpus::origin requested_debug_info_kind, + bool show_all_types, + bool linux_kernel_mode =3D false); =20 }// end namespace tools_utils =20 diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index 5fde94f3..9bcb9424 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc @@ -51,15 +51,11 @@ class reader; =20 static typedef_decl_sptr process_ctf_typedef(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static type_decl_sptr process_ctf_base_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 @@ -69,63 +65,47 @@ build_ir_node_for_variadic_parameter_type(reader &rdr, =20 static function_type_sptr process_ctf_function_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static void process_ctf_sou_members(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type, class_or_union_sptr sou); =20 static type_base_sptr process_ctf_forward_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static class_decl_sptr process_ctf_struct_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static union_decl_sptr process_ctf_union_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static array_type_def_sptr process_ctf_array_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static type_base_sptr process_ctf_qualified_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static pointer_type_def_sptr process_ctf_pointer_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 static enum_type_decl_sptr process_ctf_enum_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); =20 @@ -161,6 +141,7 @@ class reader : public elf_based_reader ctf_sect_t ctf_sect; ctf_sect_t symtab_sect; ctf_sect_t strtab_sect; + translation_unit_sptr cur_tu_; =20 public: =20 @@ -263,17 +244,21 @@ public: { ctfa =3D nullptr; types_map.clear(); + cur_tu_.reset(); corpus_group().reset(); } =20 /// Initializer of the reader. /// - /// /// @param elf_path the new path to the new ELF file to use. /// /// @param debug_info_root_paths a vector of paths to use to look /// for debug info that is split out into a separate file. /// + /// @param load_all_types currently not used. + /// + /// @param linux_kernel_mode currently not used. + /// /// This is useful to clear out the data used by the reader and get /// it ready to be used again. /// @@ -286,11 +271,32 @@ public: /// the environment. void initialize(const string& elf_path, - const vector& debug_info_root_paths) + const vector& debug_info_root_paths, + bool load_all_types =3D false, + bool linux_kernel_mode =3D false) { + load_all_types =3D load_all_types; + linux_kernel_mode =3D linux_kernel_mode; reset(elf_path, debug_info_root_paths); } =20 + /// Setter of the current translation unit. + /// + /// @param tu the current translation unit being constructed. + void + cur_transl_unit(translation_unit_sptr tu) + { + if (tu) + cur_tu_ =3D tu; + } + + /// Getter of the current translation unit. + /// + /// @return the current translation unit being constructed. + const translation_unit_sptr& + cur_transl_unit() const + {return cur_tu_;} + /// Getter of the environment of the current CTF reader. /// /// @return the environment of the current CTF reader. @@ -349,27 +355,23 @@ public: // Read the ELF-specific parts of the corpus. elf::reader::read_corpus(status); =20 - if ((status & STATUS_NO_SYMBOLS_FOUND) - || !(status & STATUS_OK)) - // Either we couldn't find ELF symbols or something went badly - // wrong. There is nothing we can do with this ELF file. Bail - // out. - return; - corpus_sptr corp =3D corpus(); if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN) && corpus_group()) { - status |=3D fe_iface::STATUS_OK; + // Not finding any debug info so far is expected if we are + // building a kABI. + status &=3D static_cast + (~STATUS_DEBUG_INFO_NOT_FOUND); return; } =20 - /* Get the raw ELF section contents for libctf. */ - if (!find_ctf_section()) - { - status |=3D fe_iface::STATUS_DEBUG_INFO_NOT_FOUND; - return; - } + if ((status & STATUS_NO_SYMBOLS_FOUND) + || !(status & STATUS_OK)) + // Either we couldn't find ELF symbols or something went badly + // wrong. There is nothing we can do with this ELF file. Bail + // out. + return; =20 GElf_Ehdr *ehdr, eh_mem; if (!(ehdr =3D gelf_getehdr(elf_handle(), &eh_mem))) @@ -402,16 +404,16 @@ public: /// Process a CTF archive and create libabigail IR for the types, /// variables and function declarations found in the archive, iterating /// over public symbols. The IR is added to the given corpus. - /// - /// @param corp the IR corpus to which add the new contents. void - process_ctf_archive(corpus_sptr corp) + process_ctf_archive() { + corpus_sptr corp =3D corpus(); /* We only have a translation unit. */ translation_unit_sptr ir_translation_unit =3D std::make_shared(env(), "", 64); ir_translation_unit->set_language(translation_unit::LANG_C); corp->add(ir_translation_unit); + cur_transl_unit(ir_translation_unit); =20 int ctf_err; ctf_dict_t *ctf_dict, *dict_tmp; @@ -455,8 +457,7 @@ public: if (ctf_type_kind(ctf_dict, ctf_sym_type) !=3D CTF_K_FUNCTION) { const char *var_name =3D sym_name.c_str(); - type_base_sptr var_type =3D lookup_type(corp, ir_translation_unit, - ctf_dict, ctf_sym_type); + type_base_sptr var_type =3D build_type(ctf_dict, ctf_sym_type); if (!var_type) /* Ignore variable if its type can't be sorted out. */ continue; @@ -477,8 +478,7 @@ public: { const char *func_name =3D sym_name.c_str(); ctf_id_t ctf_sym =3D ctf_sym_type; - type_base_sptr func_type =3D lookup_type(corp, ir_translation_unit, - ctf_dict, ctf_sym); + type_base_sptr func_type =3D build_type(ctf_dict, ctf_sym); if (!func_type) /* Ignore function if its type can't be sorted out. */ continue; @@ -508,8 +508,6 @@ public: =20 /// Add a new type declaration to the given libabigail IR corpus CORP. /// - /// @param corp the libabigail IR corpus being constructed. - /// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -518,11 +516,11 @@ public: /// /// @return a shared pointer to the IR node for the type. type_base_sptr - process_ctf_type(corpus_sptr corp, - translation_unit_sptr tunit, - ctf_dict_t *ctf_dictionary, + process_ctf_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D corpus(); + translation_unit_sptr tunit =3D cur_transl_unit(); int type_kind =3D ctf_type_kind(ctf_dictionary, ctf_type); type_base_sptr result; =20 @@ -538,21 +536,21 @@ public: case CTF_K_FLOAT: { type_decl_sptr type_decl - =3D process_ctf_base_type(this, corp, tunit, ctf_dictionary, ctf_type= ); + =3D process_ctf_base_type(this, ctf_dictionary, ctf_type); result =3D is_type(type_decl); break; } case CTF_K_TYPEDEF: { typedef_decl_sptr typedef_decl - =3D process_ctf_typedef(this, corp, tunit, ctf_dictionary, ctf_type); + =3D process_ctf_typedef(this, ctf_dictionary, ctf_type); result =3D is_type(typedef_decl); break; } case CTF_K_POINTER: { pointer_type_def_sptr pointer_type - =3D process_ctf_pointer_type(this, corp, tunit, ctf_dictionary, ctf_t= ype); + =3D process_ctf_pointer_type(this, ctf_dictionary, ctf_type); result =3D pointer_type; break; } @@ -561,49 +559,45 @@ public: case CTF_K_RESTRICT: { type_base_sptr qualified_type - =3D process_ctf_qualified_type(this, corp, tunit, ctf_dictionary, ctf= _type); + =3D process_ctf_qualified_type(this, ctf_dictionary, ctf_type); result =3D qualified_type; break; } case CTF_K_ARRAY: { array_type_def_sptr array_type - =3D process_ctf_array_type(this, corp, tunit, ctf_dictionary, ctf_typ= e); + =3D process_ctf_array_type(this, ctf_dictionary, ctf_type); result =3D array_type; break; } case CTF_K_ENUM: { enum_type_decl_sptr enum_type - =3D process_ctf_enum_type(this, tunit, ctf_dictionary, ctf_type); + =3D process_ctf_enum_type(this, ctf_dictionary, ctf_type); result =3D enum_type; break; } case CTF_K_FUNCTION: { function_type_sptr function_type - =3D process_ctf_function_type(this, corp, tunit, ctf_dictionary, ctf_= type); + =3D process_ctf_function_type(this, ctf_dictionary, ctf_type); result =3D function_type; break; } case CTF_K_STRUCT: { class_decl_sptr struct_decl - =3D process_ctf_struct_type(this, corp, tunit, ctf_dictionary, ctf_ty= pe); + =3D process_ctf_struct_type(this, ctf_dictionary, ctf_type); result =3D is_type(struct_decl); break; } case CTF_K_FORWARD: - { - result =3D process_ctf_forward_type(this, tunit, - ctf_dictionary, - ctf_type); - } + result =3D process_ctf_forward_type(this, ctf_dictionary, ctf_type); break; case CTF_K_UNION: { union_decl_sptr union_decl - =3D process_ctf_union_type(this, corp, tunit, ctf_dictionary, ctf_typ= e); + =3D process_ctf_union_type(this, ctf_dictionary, ctf_type); result =3D is_type(union_decl); break; } @@ -622,11 +616,10 @@ public: return result; } =20 - /// Given a CTF type id, lookup the corresponding libabigail IR type. - /// If the IR type hasn't been generated yet, generate it. + /// Given a CTF type id, build the corresponding libabigail IR type. + /// If the IR type has been generated it returns the corresponding + /// type. /// - /// @param corp the libabigail IR corpus being constructed. - /// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the looked type. /// @@ -635,14 +628,12 @@ public: /// /// @return a shared pointer to the IR node for the type. type_base_sptr - lookup_type(corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, - ctf_id_t ctf_type) + build_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { type_base_sptr result =3D lookup_type(ctf_dictionary, ctf_type); =20 if (!result) - result =3D process_ctf_type(corp, tunit, ctf_dictionary, ctf_type); + result =3D process_ctf_type(ctf_dictionary, ctf_type); return result; } =20 @@ -664,13 +655,12 @@ public: origin |=3D corpus::CTF_ORIGIN; corp->set_origin(origin); =20 - if (corpus_group()) - corpus_group()->add_corpus(corpus()); - slurp_elf_info(status); - if (!elf_helpers::is_linux_kernel(elf_handle()) - && ((status & fe_iface::STATUS_DEBUG_INFO_NOT_FOUND) | - (status & fe_iface::STATUS_NO_SYMBOLS_FOUND))) + if (status & fe_iface::STATUS_NO_SYMBOLS_FOUND) + return corpus_sptr(); + + if (!(origin & corpus::LINUX_KERNEL_BINARY_ORIGIN) + && (status & fe_iface::STATUS_DEBUG_INFO_NOT_FOUND)) return corp; =20 int errp; @@ -697,7 +687,7 @@ public: status |=3D fe_iface::STATUS_DEBUG_INFO_NOT_FOUND; else { - process_ctf_archive(corp); + process_ctf_archive(); corpus()->sort_functions(); corpus()->sort_variables(); } @@ -719,8 +709,6 @@ typedef shared_ptr reader_sptr; /// Build and return a typedef libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -728,11 +716,11 @@ typedef shared_ptr reader_sptr; =20 static typedef_decl_sptr process_ctf_typedef(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); typedef_decl_sptr result; =20 ctf_id_t ctf_utype =3D ctf_type_reference(ctf_dictionary, ctf_type); @@ -744,14 +732,13 @@ process_ctf_typedef(reader *rdr, if (result =3D lookup_typedef_type(typedef_name, *corp)) return result; =20 - type_base_sptr utype =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_utype); + type_base_sptr utype =3D rdr->build_type(ctf_dictionary, ctf_utype); =20 if (!utype) return result; =20 - result =3D dynamic_pointer_cast(rdr->lookup_type(ctf_dicti= onary, - ctf_type)); + result =3D dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; =20 @@ -782,7 +769,6 @@ process_ctf_typedef(reader *rdr, /// IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -790,11 +776,11 @@ process_ctf_typedef(reader *rdr, =20 static type_decl_sptr process_ctf_base_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); type_decl_sptr result; =20 ssize_t type_alignment =3D ctf_type_align(ctf_dictionary, ctf_type); @@ -873,8 +859,6 @@ build_ir_node_for_variadic_parameter_type(reader &rdr, /// Build and return a function type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -882,11 +866,11 @@ build_ir_node_for_variadic_parameter_type(reader &rdr, =20 static function_type_sptr process_ctf_function_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); function_type_sptr result; =20 /* Fetch the function type info from the CTF type. */ @@ -896,8 +880,7 @@ process_ctf_function_type(reader *rdr, =20 /* Take care first of the result type. */ ctf_id_t ctf_ret_type =3D funcinfo.ctc_return; - type_base_sptr ret_type =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_ret_type); + type_base_sptr ret_type =3D rdr->build_type(ctf_dictionary, ctf_ret_type= ); if (!ret_type) return result; =20 @@ -912,8 +895,7 @@ process_ctf_function_type(reader *rdr, for (int i =3D 0; i < argc; i++) { ctf_id_t ctf_arg_type =3D argv[i]; - type_base_sptr arg_type =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_arg_type); + type_base_sptr arg_type =3D rdr->build_type(ctf_dictionary, ctf_arg_= type); if (!arg_type) return result; =20 @@ -938,8 +920,8 @@ process_ctf_function_type(reader *rdr, function_parms.push_back(parm); } =20 - result =3D dynamic_pointer_cast(rdr->lookup_type(ctf_dict= ionary, - ctf_type)= ); + result =3D dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; =20 @@ -964,20 +946,18 @@ process_ctf_function_type(reader *rdr, /// Add member information to a IR struct or union type. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @param sou the IR struct or union type to which add the members. =20 static void process_ctf_sou_members(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type, class_or_union_sptr sou) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); ssize_t member_size; ctf_next_t *member_next =3D NULL; const char *member_name =3D NULL; @@ -997,9 +977,8 @@ process_ctf_sou_members(reader *rdr, return; =20 /* Build the IR for the member's type. */ - type_base_sptr member_type =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, - member_ctf_type); + type_base_sptr member_type =3D rdr->build_type(ctf_dictionary, + member_ctf_type); if (!member_type) /* Ignore this member. */ continue; @@ -1024,17 +1003,16 @@ process_ctf_sou_members(reader *rdr, /// IR. /// /// @param rdr the read context. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @return the resulting IR node created. =20 static type_base_sptr process_ctf_forward_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); decl_base_sptr result; std::string type_name =3D ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1083,8 +1061,6 @@ process_ctf_forward_type(reader *rdr, /// Build and return a struct type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1092,11 +1068,11 @@ process_ctf_forward_type(reader *rdr, =20 static class_decl_sptr process_ctf_struct_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); class_decl_sptr result; std::string struct_type_name =3D ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1130,8 +1106,7 @@ process_ctf_struct_type(reader *rdr, /* Now add the struct members as specified in the CTF type description. This is C, so named types can only be defined in the global scope. */ - process_ctf_sou_members(rdr, corp, tunit, ctf_dictionary, ctf_type, - result); + process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result); =20 return result; } @@ -1139,8 +1114,6 @@ process_ctf_struct_type(reader *rdr, /// Build and return an union type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1148,11 +1121,11 @@ process_ctf_struct_type(reader *rdr, =20 static union_decl_sptr process_ctf_union_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); union_decl_sptr result; std::string union_type_name =3D ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1184,8 +1157,7 @@ process_ctf_union_type(reader *rdr, /* Now add the union members as specified in the CTF type description. This is C, so named types can only be defined in the global scope. */ - process_ctf_sou_members(rdr, corp, tunit, ctf_dictionary, ctf_type, - result); + process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result); =20 return result; } @@ -1193,20 +1165,19 @@ process_ctf_union_type(reader *rdr, /// Build and return an array type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. +/// /// @param ctf_dictionary the CTF dictionary being read. +/// /// @param ctf_type the CTF type ID of the source type. /// /// @return a shared pointer to the IR node for the array type. - static array_type_def_sptr process_ctf_array_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); array_type_def_sptr result; ctf_arinfo_t ctf_ainfo; bool is_infinite =3D false; @@ -1222,21 +1193,19 @@ process_ctf_array_type(reader *rdr, uint64_t nelems =3D ctf_ainfo.ctr_nelems; =20 /* Make sure the element type is generated. */ - type_base_sptr element_type =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, - ctf_element_type); + type_base_sptr element_type =3D rdr->build_type(ctf_dictionary, + ctf_element_type); if (!element_type) return result; =20 /* Ditto for the index type. */ - type_base_sptr index_type =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, - ctf_index_type); + type_base_sptr index_type =3D rdr->build_type(ctf_dictionary, + ctf_index_type); if (!index_type) return result; =20 - result =3D dynamic_pointer_cast(rdr->lookup_type(ctf_dic= tionary, - ctf_type= )); + result =3D dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; =20 @@ -1284,28 +1253,25 @@ process_ctf_array_type(reader *rdr, /// Build and return a qualified type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. =20 static type_base_sptr process_ctf_qualified_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); type_base_sptr result; int type_kind =3D ctf_type_kind(ctf_dictionary, ctf_type); ctf_id_t ctf_utype =3D ctf_type_reference(ctf_dictionary, ctf_type); - type_base_sptr utype =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_utype); + type_base_sptr utype =3D rdr->build_type(ctf_dictionary, ctf_utype); if (!utype) return result; =20 - result =3D dynamic_pointer_cast(rdr->lookup_type(ctf_dictiona= ry, - ctf_type)); + result =3D dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; =20 @@ -1337,8 +1303,6 @@ process_ctf_qualified_type(reader *rdr, /// Build and return a pointer type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1346,24 +1310,23 @@ process_ctf_qualified_type(reader *rdr, =20 static pointer_type_def_sptr process_ctf_pointer_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp =3D rdr->corpus(); + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); pointer_type_def_sptr result; ctf_id_t ctf_target_type =3D ctf_type_reference(ctf_dictionary, ctf_type= ); if (ctf_target_type =3D=3D CTF_ERR) return result; =20 - type_base_sptr target_type =3D rdr->lookup_type(corp, tunit, - ctf_dictionary, - ctf_target_type); + type_base_sptr target_type =3D rdr->build_type(ctf_dictionary, + ctf_target_type); if (!target_type) return result; =20 - result =3D dynamic_pointer_cast(rdr->lookup_type(ctf_d= ictionary, - ctf_ty= pe)); + result =3D dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; =20 @@ -1383,8 +1346,6 @@ process_ctf_pointer_type(reader *rdr, /// Build and return an enum type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1392,10 +1353,10 @@ process_ctf_pointer_type(reader *rdr, =20 static enum_type_decl_sptr process_ctf_enum_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + translation_unit_sptr tunit =3D rdr->cur_transl_unit(); enum_type_decl_sptr result; std::string enum_name =3D ctf_type_name_raw(ctf_dictionary, ctf_type); =20 @@ -1430,6 +1391,7 @@ process_ctf_enum_type(reader *rdr, =20 while ((ename =3D ctf_enum_next(ctf_dictionary, ctf_type, &enum_next, &e= value))) enms.push_back(enum_type_decl::enumerator(ename, evalue)); + if (ctf_errno(ctf_dictionary) !=3D ECTF_NEXT_END) { fprintf(stderr, "ERROR from ctf_enum_next\n"); diff --git a/src/abg-elf-reader.cc b/src/abg-elf-reader.cc index eedeaf8e..3b1b5803 100644 --- a/src/abg-elf-reader.cc +++ b/src/abg-elf-reader.cc @@ -459,6 +459,7 @@ reader::reader(const string& elf_path, { priv_->crack_open_elf_file(); priv_->locate_dwarf_debug_info(); + priv_->locate_ctf_debug_info(); } =20 /// The destructor of the @ref elf::reader type. @@ -479,10 +480,13 @@ void reader::reset(const std::string& elf_path, const vector& debug_info_roots) { + fe_iface::options_type opts =3D options(); + fe_iface::reset(elf_path, opts.env); corpus_path(elf_path); priv_->initialize(debug_info_roots); priv_->crack_open_elf_file(); priv_->locate_dwarf_debug_info(); + priv_->locate_ctf_debug_info(); } =20 /// Getter of the vector of directory paths to look into for split @@ -528,6 +532,21 @@ const Dwarf* reader::dwarf_debug_info() const {return priv_->dwarf_handle;} =20 +/// Test if the binary has DWARF debug info. +/// +/// @return true iff the binary has DWARF debug info. +bool +reader::has_dwarf_debug_info() const +{return ((priv_->dwarf_handle !=3D nullptr) + || (priv_->alt_dwarf_handle !=3D nullptr));} + +/// Test if the binary has CTF debug info. +/// +/// @return true iff the binary has CTF debug info. +bool +reader::has_ctf_debug_info() const +{return (priv_->ctf_section !=3D nullptr);} + /// Getter of the handle use to access DWARF information from the /// alternate split DWARF information. /// @@ -873,13 +892,15 @@ reader::read_corpus(status& status) corpus()->set_symtab(symtab()); =20 // If we couldn't load debug info from the elf path, then say it. - if (dwarf_debug_info() =3D=3D nullptr - && find_ctf_section() =3D=3D nullptr) - status |=3D STATUS_DEBUG_INFO_NOT_FOUND; - - status |=3D STATUS_OK; - - return corpus(); + if ((origin & abigail::ir::corpus::DWARF_ORIGIN) + && !has_dwarf_debug_info()) + status |=3D STATUS_DEBUG_INFO_NOT_FOUND; + else if ((origin & abigail::ir::corpus::CTF_ORIGIN) + && !has_ctf_debug_info()) + status |=3D STATUS_DEBUG_INFO_NOT_FOUND; + + status |=3D STATUS_OK; + return corpus(); } =20 /// Get the SONAME property of a designated ELF file. diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index 8898ef97..7894219b 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -405,6 +405,23 @@ is_regular_file(const string& path) return false; } =20 +/// Test if a directory contains a CTF archive. +/// +/// @param directory the directory to consider. +/// +/// @param archive_prefix the prefix of the archive file. +/// +/// @return true iff @p directory contains a CTF archive file. +bool +dir_contains_ctf_archive(const string& directory, + const string& archive_prefix) +{ + string ctf_archive =3D directory + "/" + archive_prefix + ".ctfa"; + if (file_exists(ctf_archive)) + return true; + return false; +} + /// Test if an ELF file has DWARF debug info. /// /// This function supports split debug info files as well. @@ -437,11 +454,29 @@ file_has_dwarf_debug_info(const string& elf_file_path, return false; } =20 +/// Test if an ELF file has CTF debug info. +/// +/// This function supports split debug info files as well. +/// Linux Kernel with CTF debug information generates a CTF archive: +/// a special file containing debug information for vmlinux and its +/// modules (*.ko) files it is located by default in the Kernel build +/// directory as "vmlinux.ctfa". +/// +/// @param elf_file_path the path to the ELF file to consider. +/// +/// @param debug_info_root a vector of pointer to directory to look +/// for debug info, in case the file is associated to split debug +/// info. If there is no split debug info then this vector can be +/// empty. Note that convert_char_stars_to_char_star_stars() can be +/// used to ease the construction of this vector. +/// +/// @return true iff the ELF file at @elf_file_path is an ELF file +/// that contains debug info. bool file_has_ctf_debug_info(const string& elf_file_path, const vector& debug_info_root_paths) { - if (guess_file_type(elf_file_path) !=3D FILE_TYPE_ELF) + if (guess_file_type(elf_file_path) !=3D FILE_TYPE_ELF) return false; =20 environment env; @@ -452,6 +487,20 @@ file_has_ctf_debug_info(const string& elf_file_path, if (r.find_ctf_section()) return true; =20 + string vmlinux; + if (base_name(elf_file_path, vmlinux)) + { + string dirname; + if (dir_name(elf_file_path, dirname) + && dir_contains_ctf_archive(dirname, vmlinux)) + return true; + } + + // vmlinux.ctfa could be provided with --debug-info-dir + for (const auto& path : debug_info_root_paths) + if (dir_contains_ctf_archive(*path, vmlinux)) + return true; + return false; } =20 @@ -2539,12 +2588,13 @@ get_binary_paths_from_kernel_dist(const string& dis= t_root, module_paths); } =20 -/// If the @ref origin is DWARF_ORIGIN it build a @ref corpus_group -/// made of vmlinux kernel file and the linux kernel modules found -/// under @p root directory and under its sub-directories, recursively. +/// It builds a @ref corpus_group made of vmlinux kernel file and +/// the kernel modules found under @p root directory and under its +/// sub-directories, recursively. /// -/// @param origin the debug type information in vmlinux kernel and -/// the linux kernel modules to be used to build the corpora @p group. +/// @param rdr the raeder that should be used to extract the debug +/// infomation from the linux kernel and its modules used to build +/// the corpora @p group. /// /// @param the group @ref corpus_group to be built. /// @@ -2576,28 +2626,20 @@ get_binary_paths_from_kernel_dist(const string& dis= t_root, /// /// @param env the environment to create the corpus_group in. static void -maybe_load_vmlinux_dwarf_corpus(corpus::origin origin, - corpus_group_sptr& group, - const string& vmlinux, - vector& modules, - const string& root, - vector& di_roots, - vector& suppr_paths, - vector& kabi_wl_paths, - suppressions_type& supprs, - bool verbose, - timer& t, - environment& env) -{ - if (!(origin & corpus::DWARF_ORIGIN)) - return; - +load_vmlinux_corpus(elf_based_reader_sptr rdr, + corpus_group_sptr& group, + const string& vmlinux, + vector& modules, + const string& root, + vector& di_roots, + vector& suppr_paths, + vector& kabi_wl_paths, + suppressions_type& supprs, + bool verbose, + timer& t, + environment& env) +{ abigail::fe_iface::status status =3D abigail::fe_iface::STATUS_OK; - elf_based_reader_sptr rdr =3D - dwarf::create_reader(vmlinux, di_roots, env, - /*read_all_types=3D*/false, - /*linux_kernel_mode=3D*/true); - ABG_ASSERT(rdr); rdr->options().do_log =3D verbose; =20 t.start(); @@ -2645,9 +2687,9 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin o= rigin, << "/" << total_nb_modules << ") ... " << std::flush; =20 - dwarf::reset_reader(*rdr, *m, di_roots, - /*read_all_types=3D*/false, - /*linux_kernel_mode=3D*/true); + rdr->initialize(*m, di_roots, + /*read_all_types=3D*/false, + /*linux_kernel_mode=3D*/true); =20 load_generate_apply_suppressions(*rdr, suppr_paths, kabi_wl_paths, supprs); @@ -2665,101 +2707,6 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin = origin, } } =20 -/// If the @ref origin is CTF_ORIGIN it build a @ref corpus_group -/// made of vmlinux kernel file and the linux kernel modules found -/// under @p root directory and under its sub-directories, recursively. -/// -/// @param origin the debug type information in vmlinux kernel and -/// the linux kernel modules to be used to build the corpora @p group. -/// -/// @param group the @ref corpus_group to be built. -/// -/// @param vmlinux the path to the vmlinux binary. -/// -/// @param modules a vector with the paths to the linux kernel -/// modules. -/// -/// @param root the path of the directory under which the kernel -/// kernel modules were found. -/// -/// @param di_root the directory in aboslute path which debug -/// info is to be found for binaries under director @p root -/// -/// @param verbose true if the function has to emit some verbose -/// messages. -/// -/// @param t time to trace time spent in each step. -/// -/// @param env the environment to create the corpus_group in. -#ifdef WITH_CTF -static void -maybe_load_vmlinux_ctf_corpus(corpus::origin origin, - corpus_group_sptr& group, - const string& vmlinux, - vector& modules, - const string& root, - vector& di_roots, - bool verbose, - timer& t, - environment& env) -{ - if (!(origin & corpus::CTF_ORIGIN)) - return; - - abigail::fe_iface::status status =3D abigail::fe_iface::STATUS_OK; - elf_based_reader_sptr rdr =3D - ctf::create_reader(vmlinux, di_roots, env); - ABG_ASSERT(rdr); - - group.reset(new corpus_group(env, root)); - rdr->corpus_group(group); - - if (verbose) - std::cerr << "reading kernel binary '" - << vmlinux << "' ...\n" << std::flush; - - // Read the vmlinux corpus and add it to the group. - t.start(); - rdr->read_and_add_corpus_to_group(*group, status); - t.stop(); - - if (verbose) - std::cerr << vmlinux - << " reading DONE:" - << t << "\n"; - - if (group->is_empty()) - return; - - // Now add the corpora of the modules to the corpus group. - int total_nb_modules =3D modules.size(); - int cur_module_index =3D 1; - for (vector::const_iterator m =3D modules.begin(); - m !=3D modules.end(); - ++m, ++cur_module_index) - { - if (verbose) - std::cerr << "reading module '" - << *m << "' (" - << cur_module_index - << "/" << total_nb_modules - << ") ... " << std::flush; - - ctf::reset_reader(*rdr, *m, di_roots); - rdr->corpus_group(group); - - t.start(); - rdr->read_and_add_corpus_to_group(*group, status); - t.stop(); - if (verbose) - std::cerr << "module '" - << *m - << "' reading DONE: " - << t << "\n"; - } -} -#endif - /// Walk a given directory and build an instance of @ref corpus_group /// from the vmlinux kernel binary and the linux kernel modules found /// under that directory and under its sub-directories, recursively. @@ -2767,11 +2714,6 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin origi= n, /// The main corpus of the @ref corpus_group is made of the vmlinux /// binary. The other corpora are made of the linux kernel binaries. /// -/// Depending of the @ref origin it delegates the corpus build @p group -/// to: -/// @ref maybe_load_vmlinux_dwarf_corpus -/// @ref maybe_load_vmlinux_ctf_corpus -/// /// @param root the path of the directory under which the kernel /// kernel modules are to be found. The vmlinux can also be found /// somewhere under that directory, but if it's not in there, its path @@ -2799,6 +2741,9 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin origin, /// messages. /// /// @param env the environment to create the corpus_group in. +/// +/// @param requested_fe_kind the kind of front-end requested by the +/// user. corpus_group_sptr build_corpus_group_from_kernel_dist_under(const string& root, const string debug_info_root, @@ -2808,7 +2753,7 @@ build_corpus_group_from_kernel_dist_under(const strin= g& root, suppressions_type& supprs, bool verbose, environment& env, - corpus::origin origin) + corpus::origin requested_fe_kind) { string vmlinux =3D vmlinux_path; corpus_group_sptr group; @@ -2836,30 +2781,39 @@ build_corpus_group_from_kernel_dist_under(const str= ing& root, vector di_roots; di_roots.push_back(&di_root_ptr); =20 - maybe_load_vmlinux_dwarf_corpus(origin, group, vmlinux, - modules, root, di_roots, - suppr_paths, kabi_wl_paths, - supprs, verbose, t, env); -#ifdef WITH_CTF - maybe_load_vmlinux_ctf_corpus(origin, group, vmlinux, - modules, root, di_roots, - verbose, t, env); -#endif + abigail::elf_based_reader_sptr reader =3D + create_best_elf_based_reader(vmlinux, + di_roots, + env, + requested_fe_kind, + /*read_all_types=3D*/false, + /*linux_kernel_mode=3D*/true); + ABG_ASSERT(reader); + load_vmlinux_corpus(reader, group, vmlinux, + modules, root, di_roots, + suppr_paths, kabi_wl_paths, + supprs, verbose, t, env); } =20 return group; } =20 -/// Create the best elf based reader (or front-end), given an ELF file. +/// Create the best elf based reader (or front-end), given an ELF +/// file. +/// +/// This function looks into the ELF file; depending on the kind of +/// debug info it contains and on the request of the user, the "best" +/// front-end is created. /// -/// This function looks into the ELF file. If it contains DWARF debug -/// info, then a DWARF Reader front-end is created and returned. -/// Otherwise, if it contains CTF debug info, then a CTF Reader -/// front-end is created and returned. +/// If the user requested the use of the CTF front-end, then, if the +/// file contains CTF debug info, the CTF front-end is created, +/// assuming libabigail is built with CTF support. /// -/// Otherwise, if the file contains no debug info or if the king of -/// debug info is not yet recognized, a DWARF Reader front-end is -/// created and returned. +/// If the binary ONLY has CTF debug info, then CTF front-end is +/// created, even if the user hasn't explicitly requested the creation +/// of the CTF front-end. +/// +/// Otherwise, by default, the DWARF front-end is created. /// /// @param elf_file_path a path to the ELF file to consider /// @@ -2868,31 +2822,59 @@ build_corpus_group_from_kernel_dist_under(const str= ing& root, /// /// @param env the environment to use for the front-end. /// +/// @param requested_fe_kind the kind of front-end specifically +/// requested by the user. At the moment, only the CTF front-end can +/// be requested, using the "--ctf" command line option on some tools +/// using the library. +/// +/// @param show_all_types option to be passed to elf based readers. +/// +/// @param linux_kernel_mode option to bed passed to elf based readers, +/// /// @return the ELF based Reader that is better adapted for the binary /// designated by @p elf_file_path. elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_paths, - environment& env) + environment& env, + corpus::origin requested_fe_kind, + bool show_all_types, + bool linux_kernel_mode) { elf_based_reader_sptr result; if (guess_file_type(elf_file_path) !=3D FILE_TYPE_ELF) return result; =20 - if (file_has_dwarf_debug_info(elf_file_path, debug_info_root_paths)) - result =3D dwarf::create_reader(elf_file_path, - debug_info_root_paths, - env); + if (requested_fe_kind & corpus::CTF_ORIGIN) + { #ifdef WITH_CTF - else if (file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) - result =3D ctf::create_reader(elf_file_path, - debug_info_root_paths, - env); + if (file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) + result =3D ctf::create_reader(elf_file_path, debug_info_root_paths, env); #endif + } else - result =3D dwarf::create_reader(elf_file_path, - debug_info_root_paths, - env); + { + // The user hasn't formally requested the use of the CTF front-end. +#ifdef WITH_CTF + if (!file_has_dwarf_debug_info(elf_file_path, debug_info_root_paths) + && file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) + // The file has CTF debug info and no DWARF, let's use the CTF + // front end even if it wasn't formally requested by the user. + result =3D ctf::create_reader(elf_file_path, debug_info_root_paths, env); +#endif + } + + if (!result) + { + // This is the default case. At worst, the DWARF reader knows + // how to handle just ELF data for the case where there is no + // DWARF debug info present. + result =3D dwarf::create_reader(elf_file_path, + debug_info_root_paths, + env, + show_all_types, + linux_kernel_mode); + } =20 return result; } diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 5ec33924..4b6e9305 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -607,6 +607,9 @@ test-read-dwarf/PR28584/PR28584-smv.clang.o.abi \ test-read-dwarf/PR29443-missing-xx.cc \ test-read-dwarf/PR29443-missing-xx.o \ test-read-dwarf/PR29443-missing-xx.o.abi \ +test-read-dwarf/test-fallback.abi \ +test-read-dwarf/test-fallback.c \ +test-read-dwarf/test-fallback.o \ \ test-read-ctf/test0 \ test-read-ctf/test0.abi \ @@ -698,6 +701,9 @@ test-read-ctf/test-anonymous-fields.o.abi \ test-read-ctf/test-linux-module.abi \ test-read-ctf/test-linux-module.c \ test-read-ctf/test-linux-module.ko \ +test-read-ctf/test-fallback.abi \ +test-read-ctf/test-fallback.c \ +test-read-ctf/test-fallback.o \ \ test-annotate/test0.abi \ test-annotate/test1.abi \ diff --git a/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt b/tests/dat= a/test-diff-pkg-ctf/dirpkg-3-report-2.txt index e69de29b..4938d221 100644 --- a/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt +++ b/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt @@ -0,0 +1,16 @@ +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D changes of 'libobj-v0.so'= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Adde= d functions + Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + + 1 function with some indirect sub-type change: + + [C] 'function void foo(S1*)' has some indirect sub-type changes: + parameter 1 of type 'S1*' has sub-type changes: + in pointed to type 'struct S1': + type size changed from 0 to 32 (in bits) + type alignment changed from 0 to 32 + 1 data member insertion: + 'int mem2', at offset 0 (in bits) + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D end of changes of 'libobj= -v0.so'=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + diff --git a/tests/data/test-read-ctf/test-fallback.abi b/tests/data/test-r= ead-ctf/test-fallback.abi new file mode 100644 index 00000000..e7d30594 --- /dev/null +++ b/tests/data/test-read-ctf/test-fallback.abi @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-fallback.c b/tests/data/test-rea= d-ctf/test-fallback.c new file mode 100644 index 00000000..e5019857 --- /dev/null +++ b/tests/data/test-read-ctf/test-fallback.c @@ -0,0 +1,8 @@ +/* gcc -gctf -c test-fallback.c -o test-fallback.o + + This test case is meant to test the fallback feature in + libabigail tools, so when those tools are executed without + the explicit use of `--ctf' option it should be use CTF + frond-end to build the IR. + */ +int a; diff --git a/tests/data/test-read-ctf/test-fallback.o b/tests/data/test-rea= d-ctf/test-fallback.o new file mode 100644 index 0000000000000000000000000000000000000000..874368b667443493724183c51dc= 49e3c5c4bf104 GIT binary patch literal 1216 zcmbVLy-veG40fRWFCZ9@Si%Gda!Jbs1B!(B5khQ?43}^~M4F)F5Om@dcn2olf;VAi zgckt2@m;GcES%)C{rR(FyS=3DA_)59^(19LpsgMnvI)MEoX?wc{p!7O~ew`^o;K!Fz8 zB-1SOsC|@k6skYLLN;L7^T( zt!iC|mr~2V8B|JM2C2SkyepaKiA--r3UIW)zw56bot$nQj*PP-lL`0MKN zPE}b~65)a#EEs!e*eG5 z3MSHwlTLxy@r~>5YZU{84K~p*<3^3#ZvGlF=3Ds)&XzTGQVa{VpD-I_#=3D>B95cD0{oy zHbw}GETb_#*xz(;lW+7c#*IBpUHT3Dg?oY+y*v8|xyUl-yM58Fh7Zx)T#6ra{xOqh lm}l~rhj4fI6nf_TMdlgBuyOGXjQ(~Md|~2+Wj2PJ{{yZRUq=3D7{ literal 0 HcmV?d00001 diff --git a/tests/data/test-read-dwarf/test-fallback.abi b/tests/data/test= -read-dwarf/test-fallback.abi new file mode 100644 index 00000000..ebbae7ef --- /dev/null +++ b/tests/data/test-read-dwarf/test-fallback.abi @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/data/test-read-dwarf/test-fallback.c b/tests/data/test-r= ead-dwarf/test-fallback.c new file mode 100644 index 00000000..e5019857 --- /dev/null +++ b/tests/data/test-read-dwarf/test-fallback.c @@ -0,0 +1,8 @@ +/* gcc -gctf -c test-fallback.c -o test-fallback.o + + This test case is meant to test the fallback feature in + libabigail tools, so when those tools are executed without + the explicit use of `--ctf' option it should be use CTF + frond-end to build the IR. + */ +int a; diff --git a/tests/data/test-read-dwarf/test-fallback.o b/tests/data/test-r= ead-dwarf/test-fallback.o new file mode 100644 index 0000000000000000000000000000000000000000..ab76098f2fff275b73cca9f627b= 95ff55de374ee GIT binary patch literal 2424 zcmbVNU2F_d6h1T4(so<=3DlTb=3DJ1Z}ZncTrkeD-DhRic~zQ+3i@Z-D&MkW${oUK}Zu1 z9!UCtc&I1dNc^=3DDi8mtgDkNT-c<}Qgk(6_0?%9rOnkG(i?>Xl?-#Pc}{h1x!v3IAc zD8QmXJ4}0w0z597w&SiDhZ?AcX0(ezDIv(sTj~bIq?#Bij-gkoF|HLA_t_4ztCW@V zYC>9lU47+30CfXsC9Rf((YfzI!_DaDBi5Z~qr11}yY5#W>hFFX zyZGZ$`qR6qb>H7i#tx)jDE)Wi%b~NQqg8LjpU^Z*|J)xPqmH8(2d3ekD&xMR#oh9J z?i*=3D=3DLh&N__B$x3VI)X2m=3Dgqp2BkCLp&9V9fO#ve3Hz0@Z;7s}c zJ45AUKZ=3D-KlX!8OP+C1zm}Tx-j8M&Zf#DfHRZsK1sYI7}{9f?0>`EKXa!m@Hb)(>Z zhlS}XncIb^j1h6nWdrC!vy!=3DcFc8%L6|te*C-qP7OzyuIF}Wr}@R}x++4ipoIYH~+ z7V96QA}F*zecj~s2N9$7BRKq`il#dKAllq3>vIB&aACpk5(HbyXBy{U<9vztToCv> z#$nE5eM97Pob@CV7!X>9?;%d-BCcD3{Z$aY* literal 0 HcmV?d00001 diff --git a/tests/test-diff-pkg.cc b/tests/test-diff-pkg.cc index e128ff63..8e510ca2 100644 --- a/tests/test-diff-pkg.cc +++ b/tests/test-diff-pkg.cc @@ -855,7 +855,7 @@ static InOutSpec in_out_specs[] =3D { // Just like the previous tests, but loc info is emitted. "data/test-diff-pkg-ctf/dirpkg-3-dir1", "data/test-diff-pkg-ctf/dirpkg-3-dir2", - "--no-default-suppression --no-abignore", + "--ctf --no-default-suppression --no-abignore", "data/test-diff-pkg-ctf/dirpkg-3.suppr", "", "", diff --git a/tests/test-read-common.cc b/tests/test-read-common.cc index b794a311..1d70b3d0 100644 --- a/tests/test-read-common.cc +++ b/tests/test-read-common.cc @@ -95,13 +95,14 @@ test_task::run_abidw(const string& extargs) { string abidw =3D string(get_build_dir()) + "/tools/abidw"; string drop_private_types; + string spec_options =3D spec.options ? spec.options : ""; set_in_abi_path(); =20 if (!in_public_headers_path.empty()) drop_private_types +=3D "--headers-dir " + in_public_headers_path + " --drop-private-types"; - string cmd =3D abidw + " " + drop_private_types + " --abidiff " + extarg= s + - in_elf_path; + string cmd =3D abidw + " " + spec_options + drop_private_types + + " --abidiff " + extargs + in_elf_path; if (system(cmd.c_str())) { error_message =3D string("ABIs differ:\n") diff --git a/tests/test-read-common.h b/tests/test-read-common.h index 4277896a..f00205b9 100644 --- a/tests/test-read-common.h +++ b/tests/test-read-common.h @@ -40,6 +40,7 @@ struct InOutSpec type_id_style_kind type_id_style; const char* in_abi_path; const char* out_abi_path; + const char* options; };// end struct InOutSpec =20 /// The task that performs the tests. diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index 6dc2d53f..043032ff 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc @@ -43,7 +43,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test0.abi", - "output/test-read-ctf/test0.abi" + "output/test-read-ctf/test0.abi", + "--ctf" }, { "data/test-read-ctf/test0", @@ -51,7 +52,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test0.hash.abi", - "output/test-read-ctf/test0.hash.abi" + "output/test-read-ctf/test0.hash.abi", + "--ctf" }, { "data/test-read-ctf/test1.so", @@ -59,7 +61,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test1.so.abi", - "output/test-read-ctf/test1.so.abi" + "output/test-read-ctf/test1.so.abi", + "--ctf" }, { "data/test-read-ctf/test1.so", @@ -67,7 +70,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test1.so.hash.abi", - "output/test-read-ctf/test1.so.hash.abi" + "output/test-read-ctf/test1.so.hash.abi", + "--ctf" }, { "data/test-read-ctf/test2.so", @@ -75,7 +79,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test2.so.abi", - "output/test-read-ctf/test2.so.abi" + "output/test-read-ctf/test2.so.abi", + "--ctf" }, { "data/test-read-ctf/test2.so", @@ -83,7 +88,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test2.so.hash.abi", - "output/test-read-ctf/test2.so.hash.abi" + "output/test-read-ctf/test2.so.hash.abi", + "--ctf" }, { "data/test-read-common/test3.so", @@ -91,7 +97,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test3.so.abi", - "output/test-read-ctf/test3.so.abi" + "output/test-read-ctf/test3.so.abi", + "--ctf" }, { "data/test-read-common/test3.so", @@ -99,7 +106,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test3.so.hash.abi", - "output/test-read-ctf/test3.so.hash.abi" + "output/test-read-ctf/test3.so.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-enum-many.o", @@ -107,7 +115,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-enum-many.o.hash.abi", - "output/test-read-ctf/test-enum-many.o.hash.abi" + "output/test-read-ctf/test-enum-many.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-ambiguous-struct-A.o", @@ -115,7 +124,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi", - "output/test-read-ctf/test-ambiguous-struct-A.o.hash.abi" + "output/test-read-ctf/test-ambiguous-struct-A.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-ambiguous-struct-B.o", @@ -123,7 +133,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi", - "output/test-read-ctf/test-ambiguous-struct-B.o.hash.abi" + "output/test-read-ctf/test-ambiguous-struct-B.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-conflicting-type-syms-a.o", @@ -131,7 +142,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi", - "output/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi" + "output/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-conflicting-type-syms-b.o", @@ -139,7 +151,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi", - "output/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi" + "output/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi", + "--ctf" }, { "data/test-read-common/test4.so", @@ -147,7 +160,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test4.so.abi", - "output/test-read-ctf/test4.so.abi" + "output/test-read-ctf/test4.so.abi", + "--ctf" }, { "data/test-read-common/test4.so", @@ -155,7 +169,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test4.so.hash.abi", - "output/test-read-ctf/test4.so.hash.abi" + "output/test-read-ctf/test4.so.hash.abi", + "--ctf" }, { "data/test-read-ctf/test5.o", @@ -163,7 +178,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test5.o.abi", - "output/test-read-ctf/test5.o.abi" + "output/test-read-ctf/test5.o.abi", + "--ctf" }, { "data/test-read-ctf/test7.o", @@ -171,7 +187,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test7.o.abi", - "output/test-read-ctf/test7.o.abi" + "output/test-read-ctf/test7.o.abi", + "--ctf" }, { "data/test-read-ctf/test8.o", @@ -179,7 +196,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test8.o.abi", - "output/test-read-ctf/test8.o.abi" + "output/test-read-ctf/test8.o.abi", + "--ctf" }, { "data/test-read-ctf/test9.o", @@ -187,7 +205,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test9.o.abi", - "output/test-read-ctf/test9.o.abi" + "output/test-read-ctf/test9.o.abi", + "--ctf" }, { "data/test-read-ctf/test-enum.o", @@ -195,7 +214,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-enum.o.abi", - "output/test-read-ctf/test-enum.o.abi" + "output/test-read-ctf/test-enum.o.abi", + "--ctf" }, { "data/test-read-ctf/test-enum-symbol.o", @@ -203,7 +223,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-enum-symbol.o.hash.abi", - "output/test-read-ctf/test-enum-symbol.o.hash.abi" + "output/test-read-ctf/test-enum-symbol.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-dynamic-array.o", @@ -211,7 +232,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-dynamic-array.o.abi", - "output/test-read-ctf/test-dynamic-array.o.abi" + "output/test-read-ctf/test-dynamic-array.o.abi", + "--ctf" }, { "data/test-read-ctf/test-anonymous-fields.o", @@ -219,7 +241,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-anonymous-fields.o.abi", - "output/test-read-ctf/test-anonymous-fields.o.abi" + "output/test-read-ctf/test-anonymous-fields.o.abi", + "--ctf" }, { "data/test-read-common/PR27700/test-PR27700.o", @@ -228,6 +251,7 @@ static InOutSpec in_out_specs[] =3D HASH_TYPE_ID_STYLE, "data/test-read-ctf/PR27700/test-PR27700.abi", "output/test-read-ctf/PR27700/test-PR27700.abi", + "--ctf" }, { "data/test-read-ctf/test-callback.o", @@ -236,6 +260,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-callback.abi", "output/test-read-ctf/test-callback.abi", + "--ctf" }, { "data/test-read-ctf/test-array-of-pointers.o", @@ -244,6 +269,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-array-of-pointers.abi", "output/test-read-ctf/test-array-of-pointers.abi", + "--ctf" }, { "data/test-read-ctf/test-functions-declaration.o", @@ -252,6 +278,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-functions-declaration.abi", "output/test-read-ctf/test-functions-declaration.abi", + "--ctf" }, { "data/test-read-ctf/test-forward-type-decl.o", @@ -260,6 +287,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-forward-type-decl.abi", "output/test-read-ctf/test-forward-type-decl.abi", + "--ctf" }, { "data/test-read-ctf/test-list-struct.o", @@ -268,6 +296,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-list-struct.abi", "output/test-read-ctf/test-list-struct.abi", + "--ctf" }, { "data/test-read-common/test-PR26568-1.o", @@ -276,6 +305,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-PR26568-1.o.abi", "output/test-read-ctf/test-PR26568-1.o.abi", + "--ctf" }, { "data/test-read-common/test-PR26568-2.o", @@ -284,6 +314,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-PR26568-2.o.abi", "output/test-read-ctf/test-PR26568-2.o.abi", + "--ctf" }, { "data/test-read-ctf/test-callback2.o", @@ -292,6 +323,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-callback2.abi", "output/test-read-ctf/test-callback2.abi", + "--ctf" }, // out-of-tree kernel module. { @@ -301,9 +333,20 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-linux-module.abi", "output/test-read-ctf/test-linux-module.abi", + "--ctf" + }, + // CTF fallback feature. + { + "data/test-read-ctf/test-fallback.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-ctf/test-fallback.abi", + "output/test-read-ctf/test-fallback.abi", + NULL, }, // This should be the last entry. - {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} + {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL} }; =20 /// Task specialization to perform CTF tests. @@ -389,7 +432,7 @@ test_task_ctf::perform() if (!(is_ok =3D serialize_corpus(out_abi_path, corp))) return; =20 - if (!(is_ok =3D run_abidw("--ctf "))) + if (!(is_ok =3D run_abidw())) return; =20 if (!(is_ok =3D run_diff())) diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc index 4b7bd14f..fbe3436b 100644 --- a/tests/test-read-dwarf.cc +++ b/tests/test-read-dwarf.cc @@ -43,7 +43,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test0.abi", - "output/test-read-dwarf/test0.abi" + "output/test-read-dwarf/test0.abi", + NULL, }, { "data/test-read-dwarf/test0", @@ -51,7 +52,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test0.hash.abi", - "output/test-read-dwarf/test0.hash.abi" + "output/test-read-dwarf/test0.hash.abi", + NULL, }, { "data/test-read-dwarf/test1", @@ -59,7 +61,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test1.abi", - "output/test-read-dwarf/test1.abi" + "output/test-read-dwarf/test1.abi", + NULL, }, { "data/test-read-dwarf/test1", @@ -67,7 +70,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test1.hash.abi", - "output/test-read-dwarf/test1.hash.abi" + "output/test-read-dwarf/test1.hash.abi", + NULL, }, { "data/test-read-dwarf/test2.so", @@ -75,7 +79,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test2.so.abi", - "output/test-read-dwarf/test2.so.abi" + "output/test-read-dwarf/test2.so.abi", + NULL, }, { "data/test-read-dwarf/test2.so", @@ -83,7 +88,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test2.so.hash.abi", - "output/test-read-dwarf/test2.so.hash.abi" + "output/test-read-dwarf/test2.so.hash.abi", + NULL, }, { "data/test-read-common/test3.so", @@ -91,7 +97,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test3.so.abi", - "output/test-read-dwarf/test3.so.abi" + "output/test-read-dwarf/test3.so.abi", + NULL, }, { "data/test-read-common/test3.so", @@ -99,7 +106,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3.so.hash.abi", - "output/test-read-dwarf/test3.so.hash.abi" + "output/test-read-dwarf/test3.so.hash.abi", + NULL, }, // suppress all except the main symbol of a group of aliases { @@ -108,7 +116,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-1.so.hash.abi", - "output/test-read-dwarf/test3-alias-1.so.hash.abi" + "output/test-read-dwarf/test3-alias-1.so.hash.abi", + NULL, }, // suppress the main symbol of a group of aliases { @@ -117,7 +126,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-2.so.hash.abi", - "output/test-read-dwarf/test3-alias-2.so.hash.abi" + "output/test-read-dwarf/test3-alias-2.so.hash.abi", + NULL, }, // suppress all except one non main symbol of a group of aliases { @@ -126,7 +136,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-3.so.hash.abi", - "output/test-read-dwarf/test3-alias-3.so.hash.abi" + "output/test-read-dwarf/test3-alias-3.so.hash.abi", + NULL, }, // suppress all symbols of a group of aliases { @@ -135,7 +146,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-4.so.hash.abi", - "output/test-read-dwarf/test3-alias-4.so.hash.abi" + "output/test-read-dwarf/test3-alias-4.so.hash.abi", + NULL, }, // suppress the main symbols with alias (function+variable) in .o file { @@ -145,6 +157,7 @@ static InOutSpec in_out_specs[] =3D HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test-suppressed-alias.o.abi", "output/test-read-dwarf/test-suppressed-alias.o.abi", + NULL, }, { "data/test-read-common/test4.so", @@ -152,7 +165,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test4.so.abi", - "output/test-read-dwarf/test4.so.abi" + "output/test-read-dwarf/test4.so.abi", + NULL, }, { "data/test-read-common/test4.so", @@ -160,7 +174,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test4.so.hash.abi", - "output/test-read-dwarf/test4.so.hash.abi" + "output/test-read-dwarf/test4.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test5.o", @@ -168,7 +183,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test5.o.abi", - "output/test-read-dwarf/test5.o.abi" + "output/test-read-dwarf/test5.o.abi", + NULL, }, { "data/test-read-dwarf/test5.o", @@ -176,7 +192,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test5.o.hash.abi", - "output/test-read-dwarf/test5.o.hash.abi" + "output/test-read-dwarf/test5.o.hash.abi", + NULL, }, { "data/test-read-dwarf/test6.so", @@ -184,7 +201,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test6.so.abi", - "output/test-read-dwarf/test6.so.abi" + "output/test-read-dwarf/test6.so.abi", + NULL, }, { "data/test-read-dwarf/test6.so", @@ -192,7 +210,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test6.so.hash.abi", - "output/test-read-dwarf/test6.so.hash.abi" + "output/test-read-dwarf/test6.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test7.so", @@ -200,7 +219,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test7.so.abi", - "output/test-read-dwarf/test7.so.abi" + "output/test-read-dwarf/test7.so.abi", + NULL, }, { "data/test-read-dwarf/test7.so", @@ -208,7 +228,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test7.so.hash.abi", - "output/test-read-dwarf/test7.so.hash.abi" + "output/test-read-dwarf/test7.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test8-qualified-this-pointer.so", @@ -216,7 +237,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test8-qualified-this-pointer.so.abi", - "output/test-read-dwarf/test8-qualified-this-pointer.so.abi" + "output/test-read-dwarf/test8-qualified-this-pointer.so.abi", + NULL, }, { "data/test-read-dwarf/test8-qualified-this-pointer.so", @@ -224,7 +246,8 @@ static InOutSpec in_out_specs[] =3D "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi", - "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi" + "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test9-pr18818-clang.so", @@ -232,7 +255,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test9-pr18818-clang.so.abi", - "output/test-read-dwarf/test9-pr18818-clang.so.abi" + "output/test-read-dwarf/test9-pr18818-clang.so.abi", + NULL, }, { "data/test-read-dwarf/test10-pr18818-gcc.so", @@ -240,7 +264,8 @@ static InOutSpec in_out_specs[] =3D "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test10-pr18818-gcc.so.abi", - "output/test-read-dwarf/test10-pr18818-gcc.so.abi" + "output/test-read-dwarf/test10-pr18818-gcc.so.abi", + NULL, }, { "data/test-read-dwarf/test11-pr18828.so", @@ -249,6 +274,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test11-pr18828.so.abi", "output/test-read-dwarf/test11-pr18828.so.abi", + NULL, }, { "data/test-read-dwarf/test12-pr18844.so", @@ -257,6 +283,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test12-pr18844.so.abi", "output/test-read-dwarf/test12-pr18844.so.abi", + NULL, }, { "data/test-read-dwarf/test13-pr18894.so", @@ -265,6 +292,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test13-pr18894.so.abi", "output/test-read-dwarf/test13-pr18894.so.abi", + NULL, }, { "data/test-read-dwarf/test14-pr18893.so", @@ -273,6 +301,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test14-pr18893.so.abi", "output/test-read-dwarf/test14-pr18893.so.abi", + NULL, }, { "data/test-read-dwarf/test15-pr18892.so", @@ -281,6 +310,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test15-pr18892.so.abi", "output/test-read-dwarf/test15-pr18892.so.abi", + NULL, }, { "data/test-read-dwarf/test16-pr18904.so", @@ -289,6 +319,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test16-pr18904.so.abi", "output/test-read-dwarf/test16-pr18904.so.abi", + NULL, }, { "data/test-read-dwarf/test17-pr19027.so", @@ -297,6 +328,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test17-pr19027.so.abi", "output/test-read-dwarf/test17-pr19027.so.abi", + NULL, }, { "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so", @@ -305,6 +337,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi", "output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi", + NULL, }, { "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so", @@ -313,6 +346,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi", "output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi= ", + NULL, }, { "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so", @@ -321,6 +355,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi", "output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi", + NULL, }, { "data/test-read-dwarf/test21-pr19092.so", @@ -329,6 +364,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test21-pr19092.so.abi", "output/test-read-dwarf/test21-pr19092.so.abi", + NULL, }, { "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so", @@ -337,6 +373,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi", "output/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi", + NULL, }, { "data/test-read-dwarf/libtest23.so", @@ -345,6 +382,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/libtest23.so.abi", "output/test-read-dwarf/libtest23.so.abi", + NULL, }, { "data/test-read-dwarf/libtest24-drop-fns.so", @@ -353,6 +391,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/libtest24-drop-fns.so.abi", "output/test-read-dwarf/libtest24-drop-fns.so.abi", + NULL, }, { "data/test-read-dwarf/libtest24-drop-fns.so", @@ -361,6 +400,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/libtest24-drop-fns-2.so.abi", "output/test-read-dwarf/libtest24-drop-fns-2.so.abi", + NULL, }, { "data/test-read-dwarf/PR22015-libboost_iostreams.so", @@ -369,6 +409,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR22015-libboost_iostreams.so.abi", "output/test-read-dwarf/PR22015-libboost_iostreams.so.abi", + NULL, }, { "data/test-read-dwarf/PR22122-libftdc.so", @@ -377,6 +418,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR22122-libftdc.so.abi", "output/test-read-dwarf/PR22122-libftdc.so.abi", + NULL, }, { "data/test-read-dwarf/PR24378-fn-is-not-scope.o", @@ -385,6 +427,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR24378-fn-is-not-scope.abi", "output/test-read-dwarf/PR24378-fn-is-not-scope.abi", + NULL, }, #if defined(HAVE_R_AARCH64_ABS64_MACRO) && defined(HAVE_R_AARCH64_PREL32_M= ACRO) { @@ -394,6 +437,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR25007-sdhci.ko.abi", "output/test-read-dwarf/PR25007-sdhci.ko.abi", + NULL, }, #endif #if defined HAVE_DW_FORM_strx @@ -404,6 +448,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi", "output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi", + NULL, }, #endif { @@ -413,6 +458,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, NULL, NULL, + NULL, }, { "data/test-read-dwarf/test26-bogus-binary.elf", @@ -421,6 +467,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, NULL, NULL, + NULL, }, { "data/test-read-dwarf/test27-bogus-binary.elf", @@ -429,6 +476,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, NULL, NULL, + NULL, }, { "data/test-read-common/PR26261/PR26261-exe", @@ -437,6 +485,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR26261/PR26261-exe.abi", "output/test-read-dwarf/PR26261/PR26261-exe.abi", + NULL, }, { "data/test-read-common/test-PR26568-1.o", @@ -445,6 +494,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test-PR26568-1.o.abi", "output/test-read-dwarf/test-PR26568-1.o.abi", + NULL, }, { "data/test-read-common/test-PR26568-2.o", @@ -453,6 +503,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test-PR26568-2.o.abi", "output/test-read-dwarf/test-PR26568-2.o.abi", + NULL, }, { "data/test-read-dwarf/test-libandroid.so", @@ -461,6 +512,7 @@ static InOutSpec in_out_specs[] =3D HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test-libandroid.so.abi", "output/test-read-dwarf/test-libandroid.so.abi", + NULL, }, { "data/test-read-common/PR27700/test-PR27700.o", @@ -469,6 +521,7 @@ static InOutSpec in_out_specs[] =3D HASH_TYPE_ID_STYLE, "data/test-read-dwarf/PR27700/test-PR27700.abi", "output/test-read-dwarf/PR27700/test-PR27700.abi", + NULL, }, { "data/test-read-dwarf/test-libaaudio.so", @@ -477,6 +530,7 @@ static InOutSpec in_out_specs[] =3D HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test-libaaudio.so.abi", "output/test-read-dwarf/test-libaaudio.so.abi", + NULL, }, { "data/test-read-dwarf/PR28584/PR28584-smv.clang.o", @@ -485,6 +539,7 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi", "output/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi", + NULL, }, { "data/test-read-dwarf/PR29443-missing-xx.o", @@ -493,9 +548,25 @@ static InOutSpec in_out_specs[] =3D SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR29443-missing-xx.o.abi", "output/test-read-dwarf/PR29443-missing-xx.o.abi", + NULL, }, + // DWARF fallback feature. + { + "data/test-read-dwarf/test-fallback.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-dwarf/test-fallback.abi", + "output/test-read-dwarf/test-fallback.abi", +#ifdef WITH_CTF + "--ctf", +#else + NULL, +#endif + }, + // This should be the last entry. - {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} + {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL} }; =20 using abigail::suppr::suppression_sptr; diff --git a/tools/abidiff.cc b/tools/abidiff.cc index 7413b291..5ffe47a3 100644 --- a/tools/abidiff.cc +++ b/tools/abidiff.cc @@ -55,6 +55,7 @@ using abigail::tools_utils::gen_suppr_spec_from_kernel_ab= i_whitelists; using abigail::tools_utils::load_default_system_suppressions; using abigail::tools_utils::load_default_user_suppressions; using abigail::tools_utils::abidiff_status; +using abigail::tools_utils::create_best_elf_based_reader; =20 using namespace abigail; =20 @@ -1196,21 +1197,17 @@ main(int argc, char* argv[]) case abigail::tools_utils::FILE_TYPE_ELF: // fall through case abigail::tools_utils::FILE_TYPE_AR: { - abigail::elf_based_reader_sptr rdr; + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; #ifdef WITH_CTF - if (opts.use_ctf) - rdr =3D ctf::create_reader(opts.file1, - opts.prepared_di_root_paths1, - env); - else + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; #endif - rdr =3D dwarf::create_reader(opts.file1, - opts.prepared_di_root_paths1, - env, - /*read_all_types=3D*/opts.show_all_types, - opts.linux_kernel_mode); - - assert(rdr); + abigail::elf_based_reader_sptr rdr =3D + create_best_elf_based_reader(opts.file1, + opts.prepared_di_root_paths1, + env, requested_fe_kind, + opts.show_all_types); + ABG_ASSERT(rdr); =20 rdr->options().show_stats =3D opts.show_stats; rdr->options().do_log =3D opts.do_log; @@ -1274,21 +1271,18 @@ main(int argc, char* argv[]) case abigail::tools_utils::FILE_TYPE_ELF: // Fall through case abigail::tools_utils::FILE_TYPE_AR: { - abigail::elf_based_reader_sptr rdr; + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; #ifdef WITH_CTF - if (opts.use_ctf) - rdr =3D ctf::create_reader(opts.file2, - opts.prepared_di_root_paths2, - env); - else + if (opts.use_ctf) + requested_fe_kind =3D corpus::CTF_ORIGIN; #endif - rdr =3D dwarf::create_reader (opts.file2, - opts.prepared_di_root_paths2, - env, - /*read_all_types=3D*/opts.show_all_types, - opts.linux_kernel_mode); + abigail::elf_based_reader_sptr rdr =3D + create_best_elf_based_reader(opts.file2, + opts.prepared_di_root_paths2, + env, requested_fe_kind, + opts.show_all_types); + ABG_ASSERT(rdr); =20 - assert(rdr); rdr->options().show_stats =3D opts.show_stats; rdr->options().do_log =3D opts.do_log; set_suppressions(*rdr, opts); diff --git a/tools/abidw.cc b/tools/abidw.cc index 7d520018..3b1a1bd5 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -48,6 +48,7 @@ using abigail::tools_utils::temp_file_sptr; using abigail::tools_utils::check_file; using abigail::tools_utils::build_corpus_group_from_kernel_dist_under; using abigail::tools_utils::timer; +using abigail::tools_utils::create_best_elf_based_reader; using abigail::ir::environment_sptr; using abigail::ir::environment; using abigail::corpus; @@ -101,7 +102,7 @@ struct options bool show_stats; bool noout; #ifdef WITH_CTF - bool use_ctf; + bool use_ctf; #endif bool show_locs; bool abidiff; @@ -552,21 +553,21 @@ load_corpus_and_write_abixml(char* argv[], =20 corpus_sptr corp; fe_iface::status s =3D fe_iface::STATUS_UNKNOWN; - // First of all, create a reader to read the ABI from the file - // specfied in opts ... - abigail::elf_based_reader_sptr reader; + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; #ifdef WITH_CTF if (opts.use_ctf) - reader =3D abigail::ctf::create_reader(opts.in_file_path, - opts.prepared_di_root_paths, - env); - else + requested_fe_kind =3D corpus::CTF_ORIGIN; #endif - reader =3D abigail::dwarf::create_reader(opts.in_file_path, - opts.prepared_di_root_paths, - env, - opts.load_all_types, - opts.linux_kernel_mode); + + // First of all, create a reader to read the ABI from the file + // specfied in opts ... + abigail::elf_based_reader_sptr reader =3D + create_best_elf_based_reader(opts.in_file_path, + opts.prepared_di_root_paths, + env, requested_fe_kind, + opts.load_all_types, + opts.linux_kernel_mode); + ABG_ASSERT(reader); =20 // ... then tune a bunch of "buttons" on the newly created reader ... reader->options().drop_undefined_syms =3D opts.drop_undefined_syms; @@ -819,7 +820,7 @@ load_kernel_corpus_group_and_write_abixml(char* argv[], =20 global_timer.start(); t.start(); -corpus::origin origin =3D + corpus::origin requested_fe_kind =3D #ifdef WITH_CTF opts.use_ctf ? corpus::CTF_ORIGIN : #endif @@ -830,7 +831,8 @@ corpus::origin origin =3D opts.vmlinux, opts.suppression_paths, opts.kabi_whitelist_paths, - supprs, opts.do_log, env, origin); + supprs, opts.do_log, env, + requested_fe_kind); t.stop(); =20 if (opts.do_log) diff --git a/tools/abipkgdiff.cc b/tools/abipkgdiff.cc index adfe8b8e..1feb3d9e 100644 --- a/tools/abipkgdiff.cc +++ b/tools/abipkgdiff.cc @@ -136,6 +136,7 @@ using abigail::tools_utils::build_corpus_group_from_ker= nel_dist_under; using abigail::tools_utils::load_default_system_suppressions; using abigail::tools_utils::load_default_user_suppressions; using abigail::tools_utils::abidiff_status; +using abigail::tools_utils::create_best_elf_based_reader; using abigail::ir::corpus_sptr; using abigail::ir::corpus_group_sptr; using abigail::comparison::diff_context; @@ -1322,14 +1323,16 @@ compare(const elf_file& elf1, abigail::elf_based_reader_sptr reader; corpus_sptr corpus1; { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; #ifdef WITH_CTF if (opts.use_ctf) - reader =3D ctf::create_reader(elf1.path, di_dirs1, env); - else + requested_fe_kind =3D corpus::CTF_ORIGIN; #endif - reader =3D dwarf::create_reader(elf1.path, di_dirs1, env, - /*load_all_types=3D*/opts.show_all_types); - + abigail::elf_based_reader_sptr reader =3D + create_best_elf_based_reader(elf1.path, + di_dirs1, + env, requested_fe_kind, + opts.show_all_types); ABG_ASSERT(reader); =20 reader->add_suppressions(priv_types_supprs1); @@ -1420,13 +1423,17 @@ compare(const elf_file& elf1, =20 corpus_sptr corpus2; { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; #ifdef WITH_CTF if (opts.use_ctf) - reader =3D ctf::create_reader(elf2.path, di_dirs2, env); - else + requested_fe_kind =3D corpus::CTF_ORIGIN; #endif - reader =3D dwarf::create_reader(elf2.path, di_dirs2, env, - /*load_all_types=3D*/opts.show_all_types); + abigail::elf_based_reader_sptr reader =3D + create_best_elf_based_reader(elf2.path, + di_dirs2, + env, requested_fe_kind, + opts.show_all_types); + ABG_ASSERT(reader); =20 reader->add_suppressions(priv_types_supprs2); if (!opts.kabi_suppressions.empty()) @@ -1582,13 +1589,17 @@ compare_to_self(const elf_file& elf, corpus_sptr corp; abigail::elf_based_reader_sptr reader; { + corpus::origin requested_fe_kind =3D corpus::DWARF_ORIGIN; #ifdef WITH_CTF if (opts.use_ctf) - reader =3D ctf::create_reader(elf.path, di_dirs, env); - else + requested_fe_kind =3D corpus::CTF_ORIGIN; #endif - reader =3D dwarf::create_reader(elf.path, di_dirs, env, - /*read_all_types=3D*/opts.show_all_types); + abigail::elf_based_reader_sptr reader =3D + create_best_elf_based_reader(elf.path, + di_dirs, + env, requested_fe_kind, + opts.show_all_types); + ABG_ASSERT(reader); =20 corp =3D reader->read_corpus(c_status); =20 diff --git a/tools/kmidiff.cc b/tools/kmidiff.cc index 391677ca..728392e3 100644 --- a/tools/kmidiff.cc +++ b/tools/kmidiff.cc @@ -421,7 +421,7 @@ main(int argc, char* argv[]) =20 corpus_group_sptr group1, group2; string debug_info_root_dir; - corpus::origin origin =3D + corpus::origin requested_fe_kind =3D #ifdef WITH_CTF opts.use_ctf ? corpus::CTF_ORIGIN : #endif @@ -443,8 +443,8 @@ main(int argc, char* argv[]) opts.suppression_paths, opts.kabi_whitelist_paths, opts.read_time_supprs, - opts.verbose, - env, origin); + opts.verbose, env, + requested_fe_kind); print_kernel_dist_binary_paths_under(opts.kernel_dist_root1, opts); } else if (ftype =3D=3D FILE_TYPE_XML_CORPUS_GROUP) @@ -469,8 +469,8 @@ main(int argc, char* argv[]) opts.suppression_paths, opts.kabi_whitelist_paths, opts.read_time_supprs, - opts.verbose, - env, origin); + opts.verbose, env, + requested_fe_kind); print_kernel_dist_binary_paths_under(opts.kernel_dist_root2, opts); } else if (ftype =3D=3D FILE_TYPE_XML_CORPUS_GROUP) --=20 2.38.1 --=20 Dodji