From patchwork Wed Jan 27 12:58:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Matthias_M=C3=A4nnich?= X-Patchwork-Id: 41853 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E3A153857C73; Wed, 27 Jan 2021 13:00:30 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E3A153857C73 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1611752431; bh=75wHZrMLBplb5BGKaQ0iIzxfY+ulXg80tEyWnfd9jCY=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ZhtzlMyAGUvl3xXngw0cHJdIlXByKwT0ktoXf5CSZqnsMRT7bUrAa8lBa0LOOizAa 4AoQnMOT9389bJ8LVPIaa4G6bEMGWYBd2xzkFfkR3ftgapo3ejX2U6mFCJzki/NKCh J5DPowMODa/wyd9qAoFs/GmFJpxSawrR7ZT0Z2wQ= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wr1-x449.google.com (mail-wr1-x449.google.com [IPv6:2a00:1450:4864:20::449]) by sourceware.org (Postfix) with ESMTPS id 7F6FE3971C3C for ; Wed, 27 Jan 2021 12:59:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 7F6FE3971C3C Received: by mail-wr1-x449.google.com with SMTP id o17so913390wrv.4 for ; Wed, 27 Jan 2021 04:59:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=75wHZrMLBplb5BGKaQ0iIzxfY+ulXg80tEyWnfd9jCY=; b=hQ8idoNSp33apPctYQRLabCuauC7Veg1GC3ur2K5VLOBT+C9qKyWVRpPRZoeWGsf32 kTOGTQOZ/IJnSD9EdBgMdID4WGGT6g1zU1W7GYSzng2A8r05PZzKggILeiTI6qwBpKnV BfplsjLEdZaLDJYEUP3kKfAw+9/7Ti28nPEjRQFY9+uOM5VrN5ZfaTVZjYq3xAI+gE2f SdJc2JccbJTL6w3VhaoHPZEKkAP6vThNmfVtbs3CBAa7KRFVFu/zDuJF2gvCEsidD/QW gu+qTrUVtnTkQE6hWwQfLU8n7/7JI5trrXToiKYGGrDRLPyHwyvV4FbKF2Hgwukk1YQQ n7Zg== X-Gm-Message-State: AOAM531OFVSruJfcxHugKA/myeXYIBKgKUg+t6069HAxjTuKZ7H8cVYG H9ev65RGtLlI1xrJao95/mLfchgmLwloifMDKXoY3H62TghKy+Lmln7WDsU8xpLf84Hi6kiL3ED pDVv3H05OMNebjKojOr2ir3gcjDH8ljREUdD+eqsVOWokjFp1TLioJUzKFx2x3g2pW9mCEig= X-Google-Smtp-Source: ABdhPJyEuU0TfD+HUHOar/id+wIjmzJhnghYiVjFf/VIKSqRkZwmNyFRgD2ztt/BpurXZbHl9tWygArNVjmUNA== X-Received: from lux.lon.corp.google.com ([2a00:79e0:d:210:7220:84ff:fe09:a3aa]) (user=maennich job=sendgmr) by 2002:a7b:c08f:: with SMTP id r15mr4203993wmh.22.1611752392522; Wed, 27 Jan 2021 04:59:52 -0800 (PST) Date: Wed, 27 Jan 2021 12:58:53 +0000 In-Reply-To: <20210127125853.886677-1-maennich@google.com> Message-Id: <20210127125853.886677-21-maennich@google.com> Mime-Version: 1.0 References: <20200619214305.562-1-maennich@google.com> <20210127125853.886677-1-maennich@google.com> X-Mailer: git-send-email 2.30.0.280.ga3ce27912f-goog Subject: [PATCH 20/20] symtab: Add support for MODVERSIONS (CRC checksums) To: libabigail@sourceware.org X-Spam-Status: No, score=-19.3 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LINEPADDING, LIKELY_SPAM_BODY, NORMAL_HTTP_TO_IP, NUMERIC_HTTP_ADDR, RCVD_IN_DNSWL_NONE, SCC_10_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Matthias Maennich via Libabigail From: =?utf-8?q?Matthias_M=C3=A4nnich?= Reply-To: Matthias Maennich Cc: maennich@google.com, kernel-team@android.com Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" The Linux Kernel has a mechanism (MODVERSIONS) to checksum symbols based on their type. In a way similar to what libabigail does, but different. The CRC values for symbols can be extracted from the symtab either by following the __kcrctab_ entry or by using the __crc_ value directly. This patch adds support for extracting those CRC values and storing them as a property of elf_symbol. Subsequently, 'crc' gets emitted as an attribute of 'elf-symbol' in the XML representation. CRC comparisons are also added to the abidiff machinery such that if both representations of a comparison contain a CRC value, they will be compared and if any of the values is unset (i.e. == 0), equality is assumed. Differences will be reported in the format that the Kernel presents them e.g. via Module.symvers. It is likely, but not necessary, that a CRC difference comes along with an ABI difference reported by libabigail. Not everything that leads to a change of the CRC value an ABI breakage in the libabigail sense. In case a function or variable symbol changes in a harmless way, we would previously also consider a CRC change harmless (or more precise: not harmful). Explicitly testing for CRC changes when analyzing whether diff nodes need to be considered harmful, allows to still classify them harmful. Also add some test cases to ensure reading CRC values from kernel binaries works as expected. The empty-report files have been consolidated to one file: empty-report.txt. That also clarifies the expected outcome for the affected tests. * include/abg-ir.h (elf_symbol::elf_symbol): Add CRC parameter. (elf_symbol::create): Likewise. (elf_symbol::get_crc): New member method. (elf_symbol::set_crc): New member method. * src/abg-comp-filter.cc (crc_changed): New function. (categorize_harmful_diff_node): Also test for CRC changes. * src/abg-ir.cc (elf_symbol::priv::crc_): New data member. * src/abg-ir.cc (elf_symbol::priv::priv): Add CRC parameter. (elf_symbol::elf_symbol): Likewise. (elf_symbol::create): Likewise. (elf_symbol::textually_equals): Add CRC support. (elf_symbol::get_crc): New member method. (elf_symbol::set_crc): New member method. * src/abg-reader.cc (build_elf_symbol): Add CRC support. * src/abg-reporter-priv.cc (maybe_report_diff_for_symbol): Likewise. * src/abg-symtab-reader.cc (symtab::load): Likewise. * src/abg-writer.cc (write_elf_symbol): Likewise. * tests/data/Makefile.am: Add new test data files. * tests/data/test-abidiff-exit/test-crc-report.txt: New test file. * tests/data/test-abidiff-exit/test-crc-v0.abi: Likewise. * tests/data/test-abidiff-exit/test-crc-v1.abi: Likewise. * tests/data/test-abidiff/empty-report.txt: New file. * tests/data/test-abidiff/test-PR18166-libtirpc.so.report.txt: Deleted. * tests/data/test-abidiff/test-PR24552-report0.txt: Deleted. * tests/data/test-abidiff/test-crc-0.xml: New test file. * tests/data/test-abidiff/test-crc-1.xml: Likewise. * tests/data/test-abidiff/test-crc-2.xml: Likewise. * tests/data/test-abidiff/test-crc-report.txt: Likewise. * tests/data/test-abidiff/test-empty-corpus-report.txt: Deleted. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Add CRC values. * tests/data/test-read-write/test-crc.xml: New test data file. * tests/data/test-symtab/kernel-modversions/Makefile: New test source. * tests/data/test-symtab/kernel-modversions/one_of_each.c: Likewise. * tests/data/test-symtab/kernel-modversions/one_of_each.ko: Likewise. * tests/test-abidiff-exit.cc: Add new test case. * tests/test-abidiff.cc: Add new test case. * tests/test-read-write.cc: Likewise. * tests/test-symtab.cc (Symtab::KernelSymtabsWithCRC): New test case. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-ir.h | 8 + src/abg-comp-filter.cc | 39 +- src/abg-ir.cc | 22 +- src/abg-reader.cc | 8 + src/abg-reporter-priv.cc | 18 +- src/abg-symtab-reader.cc | 19 + src/abg-writer.cc | 6 + tests/data/Makefile.am | 17 +- .../test-abidiff-exit/test-crc-report.txt | 15 + tests/data/test-abidiff-exit/test-crc-v0.abi | 29 + tests/data/test-abidiff-exit/test-crc-v1.abi | 30 + ...ibtirpc.so.report.txt => empty-report.txt} | 0 .../test-abidiff/test-PR24552-report0.txt | 3 - tests/data/test-abidiff/test-crc-0.xml | 1601 +++++++++++++++++ tests/data/test-abidiff/test-crc-1.xml | 1601 +++++++++++++++++ tests/data/test-abidiff/test-crc-2.xml | 1601 +++++++++++++++++ tests/data/test-abidiff/test-crc-report.txt | 9 + .../test-abidiff/test-empty-corpus-report.txt | 3 - .../data/test-read-dwarf/PR25007-sdhci.ko.abi | 72 +- tests/data/test-read-write/test-crc.xml | 10 + .../test-symtab/kernel-modversions/Makefile | 19 + .../kernel-modversions/one_of_each.c | 1 + .../kernel-modversions/one_of_each.ko | Bin 0 -> 131760 bytes tests/test-abidiff-exit.cc | 11 + tests/test-abidiff.cc | 34 +- tests/test-read-write.cc | 6 + tests/test-symtab.cc | 15 + 27 files changed, 5138 insertions(+), 59 deletions(-) create mode 100644 tests/data/test-abidiff-exit/test-crc-report.txt create mode 100644 tests/data/test-abidiff-exit/test-crc-v0.abi create mode 100644 tests/data/test-abidiff-exit/test-crc-v1.abi rename tests/data/test-abidiff/{test-PR18166-libtirpc.so.report.txt => empty-report.txt} (100%) delete mode 100644 tests/data/test-abidiff/test-PR24552-report0.txt create mode 100644 tests/data/test-abidiff/test-crc-0.xml create mode 100644 tests/data/test-abidiff/test-crc-1.xml create mode 100644 tests/data/test-abidiff/test-crc-2.xml create mode 100644 tests/data/test-abidiff/test-crc-report.txt delete mode 100644 tests/data/test-abidiff/test-empty-corpus-report.txt create mode 100644 tests/data/test-read-write/test-crc.xml create mode 100644 tests/data/test-symtab/kernel-modversions/Makefile create mode 120000 tests/data/test-symtab/kernel-modversions/one_of_each.c create mode 100644 tests/data/test-symtab/kernel-modversions/one_of_each.ko diff --git a/include/abg-ir.h b/include/abg-ir.h index a14ee1c23784..555bb769ba50 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -840,6 +840,7 @@ private: visibility vi, bool is_linux_string_cst = false, bool is_in_ksymtab = false, + uint64_t crc = 0, bool is_suppressed = false); elf_symbol(const elf_symbol&); @@ -865,6 +866,7 @@ public: visibility vi, bool is_linux_string_cst = false, bool is_in_ksymtab = false, + uint64_t crc = 0, bool is_suppressed = false); const environment* @@ -939,6 +941,12 @@ public: void set_is_in_ksymtab(bool is_in_ksymtab); + uint64_t + get_crc() const; + + void + set_crc(uint64_t crc); + bool is_suppressed() const; diff --git a/src/abg-comp-filter.cc b/src/abg-comp-filter.cc index a0280d8eddf1..0734b56ec2ee 100644 --- a/src/abg-comp-filter.cc +++ b/src/abg-comp-filter.cc @@ -218,6 +218,42 @@ access_changed(const decl_base_sptr& f, const decl_base_sptr& s) return false; } +/// Test if there was a function or variable CRC change. +/// +/// @param f the first function or variable to consider. +/// +/// @param s the second function or variable to consider. +/// +/// @return true if the test is positive, false otherwise. +template +static bool +crc_changed(const function_or_var_decl_sptr& f, + const function_or_var_decl_sptr& s) +{ + const auto symbol_f = f->get_symbol(), symbol_s = s->get_symbol(); + if (!symbol_f || !symbol_s) + return false; + const auto crc_f = symbol_f->get_crc(), crc_s = symbol_s->get_crc(); + return (crc_f != 0 && crc_s != 0 && crc_f != crc_s); +} + +/// Test if the current diff tree node carries a CRC change in either a +/// function or a variable. +/// +/// @param diff the diff tree node to consider. +/// +/// @return true if the test is positive, false otherwise. +static bool +crc_changed(const diff* diff) +{ + if (const function_decl_diff* d = + dynamic_cast(diff)) + return crc_changed(d->first_function_decl(), d->second_function_decl()); + if (const var_diff* d = dynamic_cast(diff)) + return crc_changed(d->first_var(), d->second_var()); + return false; +} + /// Test if there was a function name change, but there there was no /// change in name of the underlying symbol. IOW, if the name of a /// function changed, but the symbol of the new function is equal to @@ -1717,7 +1753,8 @@ categorize_harmful_diff_node(diff *d, bool pre) || non_static_data_member_type_size_changed(f, s) || non_static_data_member_added_or_removed(d) || base_classes_added_or_removed(d) - || has_harmful_enum_change(d))) + || has_harmful_enum_change(d) + || crc_changed(d))) category |= SIZE_OR_OFFSET_CHANGE_CATEGORY; if (has_virtual_mem_fn_change(d)) diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 0b31f2014189..64dfffbf4011 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -1311,6 +1312,7 @@ struct elf_symbol::priv bool is_common_; bool is_linux_string_cst_; bool is_in_ksymtab_; + uint64_t crc_; bool is_suppressed_; elf_symbol_wptr main_symbol_; elf_symbol_wptr next_alias_; @@ -1328,6 +1330,7 @@ struct elf_symbol::priv is_common_(false), is_linux_string_cst_(false), is_in_ksymtab_(false), + crc_(0), is_suppressed_(false) {} @@ -1343,6 +1346,7 @@ struct elf_symbol::priv elf_symbol::visibility vi, bool is_linux_string_cst, bool is_in_ksymtab, + uint64_t crc, bool is_suppressed) : env_(e), index_(i), @@ -1356,6 +1360,7 @@ struct elf_symbol::priv is_common_(c), is_linux_string_cst_(is_linux_string_cst), is_in_ksymtab_(is_in_ksymtab), + crc_(crc), is_suppressed_(is_suppressed) { if (!is_common_) @@ -1414,6 +1419,7 @@ elf_symbol::elf_symbol(const environment* e, visibility vi, bool is_linux_string_cst, bool is_in_ksymtab, + uint64_t crc, bool is_suppressed) : priv_(new priv(e, i, @@ -1427,6 +1433,7 @@ elf_symbol::elf_symbol(const environment* e, vi, is_linux_string_cst, is_in_ksymtab, + crc, is_suppressed)) {} @@ -1486,11 +1493,12 @@ elf_symbol::create(const environment* e, visibility vi, bool is_linux_string_cst, bool is_in_ksymtab, + uint64_t crc, bool is_suppressed) { elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi, is_linux_string_cst, - is_in_ksymtab, is_suppressed)); + is_in_ksymtab, crc, is_suppressed)); sym->priv_->main_symbol_ = sym; return sym; } @@ -1511,7 +1519,9 @@ textually_equals(const elf_symbol&l, && l.is_public() == r.is_public() && l.is_defined() == r.is_defined() && l.is_common_symbol() == r.is_common_symbol() - && l.get_version() == r.get_version()); + && l.get_version() == r.get_version() + && (l.get_crc() == 0 || r.get_crc() == 0 + || l.get_crc() == r.get_crc())); if (equals && l.is_variable()) // These are variable symbols. Let's compare their symbol size. @@ -1718,6 +1728,14 @@ void elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab) {priv_->is_in_ksymtab_ = is_in_ksymtab;} +uint64_t +elf_symbol::get_crc() const +{return priv_->crc_;} + +void +elf_symbol::set_crc(uint64_t crc) +{priv_->crc_ = crc;} + bool elf_symbol::is_suppressed() const {return priv_->is_suppressed_;} diff --git a/src/abg-reader.cc b/src/abg-reader.cc index e0269436ee89..42985e5a7496 100644 --- a/src/abg-reader.cc +++ b/src/abg-reader.cc @@ -2769,6 +2769,10 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node, is_default_version = true; } + uint64_t crc = 0; + if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "crc")) + crc = strtoull(CHAR_STR(s), NULL, 0); + elf_symbol::type type = elf_symbol::NOTYPE_TYPE; read_elf_symbol_type(node, type); @@ -2792,6 +2796,10 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node, /*is_linux_string_cst=*/false); e->set_is_suppressed(is_suppressed); + + if (crc != 0) + e->set_crc(crc); + return e; } diff --git a/src/abg-reporter-priv.cc b/src/abg-reporter-priv.cc index 1a7f09df63eb..c0b26d086c36 100644 --- a/src/abg-reporter-priv.cc +++ b/src/abg-reporter-priv.cc @@ -42,8 +42,7 @@ emit_num_value(uint64_t value, const diff_context& ctxt, ostream& out) out << std::hex << std::showbase ; else out << std::dec; - out << value; - out << std::dec << std::noshowbase; + out << value << std::dec << std::noshowbase; } /// Convert a bits value into a byte value if the current diff context @@ -1179,6 +1178,21 @@ maybe_report_diff_for_symbol(const elf_symbol_sptr& symbol1, reported = true; } + if (symbol1->get_crc() != 0 && symbol2->get_crc() != 0 + && symbol1->get_crc() != symbol2->get_crc()) + { + if (reported) + out << ",\n" << indent << "its CRC (modversions) changed from "; + else + out << "\n" << indent << "CRC value (modversions) changed from "; + + out << std::showbase << std::hex + << symbol1->get_crc() << " to " << symbol2->get_crc() + << std::noshowbase << std::dec; + + reported = true; + } + if (reported) out << "\n"; diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc index 512fbc20adc0..8ee90c590a94 100644 --- a/src/abg-symtab-reader.cc +++ b/src/abg-symtab-reader.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include "abg-elf-helpers.h" @@ -202,6 +203,7 @@ symtab::load_(Elf* elf_handle, const bool is_kernel = elf_helpers::is_linux_kernel(elf_handle); std::unordered_set exported_kernel_symbols; + std::unordered_map crc_values; const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle); @@ -249,6 +251,11 @@ symtab::load_(Elf* elf_handle, ABG_ASSERT(exported_kernel_symbols.insert(name.substr(10)).second); continue; } + if (is_kernel && name.rfind("__crc_", 0) == 0) + { + ABG_ASSERT(crc_values.emplace(name.substr(6), sym->st_value).second); + continue; + } // filter out uninteresting entries and only keep functions/variables for // now. The rest might be interesting in the future though. @@ -338,6 +345,18 @@ symtab::load_(Elf* elf_handle, has_ksymtab_entries_ = true; } + // Now add the CRC values + for (const auto& crc_entry : crc_values) + { + const auto r = name_symbol_map_.find(crc_entry.first); + if (r == name_symbol_map_.end()) + continue; + + for (const auto& symbol : r->second) { + symbol->set_crc(crc_entry.second); + } + } + // sort the symbols for deterministic output std::sort(symbols_.begin(), symbols_.end(), symbol_sort); diff --git a/src/abg-writer.cc b/src/abg-writer.cc index 4985174d3abd..8a1fc2495506 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -3068,6 +3069,11 @@ write_elf_symbol(const elf_symbol_sptr& sym, if (sym->is_common_symbol()) o << " is-common='yes'"; + if (sym->get_crc() != 0) + o << " crc='" + << std::hex << std::showbase << sym->get_crc() << "'" + << std::dec << std::noshowbase; + o << "/>\n"; return true; diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 83e48cb8ebac..eb1577c55527 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -35,6 +35,7 @@ test-read-write/test28-without-std-fns-ref.xml \ test-read-write/test28-drop-std-vars.abignore \ test-read-write/test28-without-std-vars-ref.xml \ test-read-write/test28-without-std-vars.xml \ +test-read-write/test-crc.xml \ \ test-write-read-archive/test0.xml \ test-write-read-archive/test1.xml \ @@ -57,6 +58,7 @@ test-core-diff/report11.txt \ test-core-diff/report12.txt \ test-core-diff/report13.txt \ \ +test-abidiff/empty-report.txt \ test-abidiff/test-enum0-v0.cc.bi \ test-abidiff/test-enum0-v1.cc.bi \ test-abidiff/test-enum0-report.txt \ @@ -77,17 +79,18 @@ test-abidiff/test-var0-v1.cc.bi \ test-abidiff/test-var0-report.txt \ test-abidiff/test-PR18166-libtirpc.so \ test-abidiff/test-PR18166-libtirpc.so.abi \ -test-abidiff/test-PR18166-libtirpc.so.report.txt \ test-abidiff/test-PR18791-report0.txt \ test-abidiff/test-PR18791-v0.so.abi \ test-abidiff/test-PR18791-v1.so.abi \ -test-abidiff/test-PR24552-report0.txt \ test-abidiff/test-PR24552-v0.abi \ test-abidiff/test-PR24552-v1.abi \ test-abidiff/test-empty-corpus-0.xml \ test-abidiff/test-empty-corpus-1.xml \ test-abidiff/test-empty-corpus-2.xml \ -test-abidiff/test-empty-corpus-report.txt \ +test-abidiff/test-crc-0.xml \ +test-abidiff/test-crc-1.xml \ +test-abidiff/test-crc-2.xml \ +test-abidiff/test-crc-report.txt \ \ test-abidiff-exit/test1-voffset-change-report0.txt \ test-abidiff-exit/test1-voffset-change-report1.txt \ @@ -197,6 +200,9 @@ test-abidiff-exit/test-non-leaf-array-v0.o \ test-abidiff-exit/test-non-leaf-array-v1.c \ test-abidiff-exit/test-non-leaf-array-v1.o \ test-abidiff-exit/test-non-leaf-array-report.txt \ +test-abidiff-exit/test-crc-report.txt \ +test-abidiff-exit/test-crc-v0.abi \ +test-abidiff-exit/test-crc-v1.abi \ test-abidiff-exit/test-missing-alias-report.txt \ test-abidiff-exit/test-missing-alias.abi \ test-abidiff-exit/test-missing-alias.suppr \ @@ -1951,4 +1957,7 @@ test-symtab/kernel-5.6/single_function_gpl.ko \ test-symtab/kernel-5.6/single_variable.c \ test-symtab/kernel-5.6/single_variable.ko \ test-symtab/kernel-5.6/single_variable_gpl.c \ -test-symtab/kernel-5.6/single_variable_gpl.ko +test-symtab/kernel-5.6/single_variable_gpl.ko \ +test-symtab/kernel-modversions/Makefile \ +test-symtab/kernel-modversions/one_of_each.c \ +test-symtab/kernel-modversions/one_of_each.ko diff --git a/tests/data/test-abidiff-exit/test-crc-report.txt b/tests/data/test-abidiff-exit/test-crc-report.txt new file mode 100644 index 000000000000..ddba41f40dad --- /dev/null +++ b/tests/data/test-abidiff-exit/test-crc-report.txt @@ -0,0 +1,15 @@ +Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions +Variables changes summary: 0 Removed, 1 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C] 'function void func1(E)' has some indirect sub-type changes: + + CRC value (modversions) changed from 0x10000001 to 0x10000002 + +1 Changed variable: + + [C] 'int var1' was changed: + + CRC value (modversions) changed from 0x30000001 to 0x30000002 + diff --git a/tests/data/test-abidiff-exit/test-crc-v0.abi b/tests/data/test-abidiff-exit/test-crc-v0.abi new file mode 100644 index 000000000000..320899fc97ff --- /dev/null +++ b/tests/data/test-abidiff-exit/test-crc-v0.abi @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-abidiff-exit/test-crc-v1.abi b/tests/data/test-abidiff-exit/test-crc-v1.abi new file mode 100644 index 000000000000..0baa66e4766b --- /dev/null +++ b/tests/data/test-abidiff-exit/test-crc-v1.abi @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-abidiff/test-PR18166-libtirpc.so.report.txt b/tests/data/test-abidiff/empty-report.txt similarity index 100% rename from tests/data/test-abidiff/test-PR18166-libtirpc.so.report.txt rename to tests/data/test-abidiff/empty-report.txt diff --git a/tests/data/test-abidiff/test-PR24552-report0.txt b/tests/data/test-abidiff/test-PR24552-report0.txt deleted file mode 100644 index a9d032e74e35..000000000000 --- a/tests/data/test-abidiff/test-PR24552-report0.txt +++ /dev/null @@ -1,3 +0,0 @@ -Functions changes summary: 0 Removed, 0 Changed, 0 Added function -Variables changes summary: 0 Removed, 0 Changed, 0 Added variable - diff --git a/tests/data/test-abidiff/test-crc-0.xml b/tests/data/test-abidiff/test-crc-0.xml new file mode 100644 index 000000000000..a5cdee7adcec --- /dev/null +++ b/tests/data/test-abidiff/test-crc-0.xml @@ -0,0 +1,1601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-abidiff/test-crc-1.xml b/tests/data/test-abidiff/test-crc-1.xml new file mode 100644 index 000000000000..9e1289ce5584 --- /dev/null +++ b/tests/data/test-abidiff/test-crc-1.xml @@ -0,0 +1,1601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-abidiff/test-crc-2.xml b/tests/data/test-abidiff/test-crc-2.xml new file mode 100644 index 000000000000..bf21ca6f93e4 --- /dev/null +++ b/tests/data/test-abidiff/test-crc-2.xml @@ -0,0 +1,1601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-abidiff/test-crc-report.txt b/tests/data/test-abidiff/test-crc-report.txt new file mode 100644 index 000000000000..4572a207a5ae --- /dev/null +++ b/tests/data/test-abidiff/test-crc-report.txt @@ -0,0 +1,9 @@ +Functions changes summary: 0 Removed, 1 Changed, 0 Added function +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C] 'function void exported_function()' has some indirect sub-type changes: + + CRC value (modversions) changed from 0xe52d5bcf to 0xe52d5bd0 + diff --git a/tests/data/test-abidiff/test-empty-corpus-report.txt b/tests/data/test-abidiff/test-empty-corpus-report.txt deleted file mode 100644 index a9d032e74e35..000000000000 --- a/tests/data/test-abidiff/test-empty-corpus-report.txt +++ /dev/null @@ -1,3 +0,0 @@ -Functions changes summary: 0 Removed, 0 Changed, 0 Added function -Variables changes summary: 0 Removed, 0 Changed, 0 Added variable - diff --git a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi index 4c9a766f1c7c..a8f632bea3f7 100644 --- a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi +++ b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-write/test-crc.xml b/tests/data/test-read-write/test-crc.xml new file mode 100644 index 000000000000..d74bb5700383 --- /dev/null +++ b/tests/data/test-read-write/test-crc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/data/test-symtab/kernel-modversions/Makefile b/tests/data/test-symtab/kernel-modversions/Makefile new file mode 100644 index 000000000000..1479ae4b03b0 --- /dev/null +++ b/tests/data/test-symtab/kernel-modversions/Makefile @@ -0,0 +1,19 @@ +obj-m += one_of_each.o + +# Overwrite to an actual kernel dir when using this: +# +# $ make KDIR=/path/to/actual/kernel/source/dir +# +KDIR := /tmp/some/kernel/source/dir + +PWD := $(shell pwd) +default: + make -C $(KDIR) tinyconfig + cd $(KDIR) && ./scripts/config -e 64BIT -e MODULES -e MODVERSIONS -e CONFIG_DEBUG_INFO + $(MAKE) -C $(KDIR) olddefconfig + $(MAKE) -C $(KDIR) + $(MAKE) -C $(KDIR) M=$(PWD) modules + rm -rf *.mod.c *.o .*.cmd .*.d *.mod modules.order Module.symvers .tmp_versions + +clean: + rm -f *.ko diff --git a/tests/data/test-symtab/kernel-modversions/one_of_each.c b/tests/data/test-symtab/kernel-modversions/one_of_each.c new file mode 120000 index 000000000000..27c87e5758cb --- /dev/null +++ b/tests/data/test-symtab/kernel-modversions/one_of_each.c @@ -0,0 +1 @@ +../kernel/one_of_each.c \ No newline at end of file diff --git a/tests/data/test-symtab/kernel-modversions/one_of_each.ko b/tests/data/test-symtab/kernel-modversions/one_of_each.ko new file mode 100644 index 0000000000000000000000000000000000000000..c6f1bed5a04fdd035459d11260a940ef1b45f35d GIT binary patch literal 131760 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 literal 0 HcmV?d00001 diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc index 38f1301eb924..76fde58fdbae 100644 --- a/tests/test-abidiff-exit.cc +++ b/tests/test-abidiff-exit.cc @@ -392,6 +392,17 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-non-leaf-array-report.txt", "output/test-abidiff-exit/test-non-leaf-array-report.txt" }, + { + "data/test-abidiff-exit/test-crc-v0.abi", + "data/test-abidiff-exit/test-crc-v1.abi", + "", + "", + "", + "", + abigail::tools_utils::ABIDIFF_ABI_CHANGE, + "data/test-abidiff-exit/test-crc-report.txt", + "output/test-abidiff-exit/test-crc-report.txt" + }, { "data/test-abidiff-exit/test-missing-alias.abi", "data/test-abidiff-exit/test-missing-alias.abi", diff --git a/tests/test-abidiff.cc b/tests/test-abidiff.cc index 82683f426d66..3452b7ee7284 100644 --- a/tests/test-abidiff.cc +++ b/tests/test-abidiff.cc @@ -77,7 +77,7 @@ static InOutSpec specs[] = { "data/test-abidiff/test-PR18166-libtirpc.so.abi", "data/test-abidiff/test-PR18166-libtirpc.so.abi", - "data/test-abidiff/test-PR18166-libtirpc.so.report.txt", + "data/test-abidiff/empty-report.txt", "output/test-abidiff/test-PR18166-libtirpc.so.report.txt" }, { @@ -89,26 +89,44 @@ static InOutSpec specs[] = { "data/test-abidiff/test-PR24552-v0.abi", "data/test-abidiff/test-PR24552-v1.abi", - "data/test-abidiff/test-PR24552-report0.txt", + "data/test-abidiff/empty-report.txt", "output/test-abidiff/test-PR24552-report0.txt" }, { "data/test-abidiff/test-empty-corpus-0.xml", "data/test-abidiff/test-empty-corpus-0.xml", - "data/test-abidiff/test-empty-corpus-report.txt", - "output/test-abidiff/test-empty-corpus-report.txt" + "data/test-abidiff/empty-report.txt", + "output/test-abidiff/test-empty-corpus-report-0.txt" }, { "data/test-abidiff/test-empty-corpus-1.xml", "data/test-abidiff/test-empty-corpus-1.xml", - "data/test-abidiff/test-empty-corpus-report.txt", - "output/test-abidiff/test-empty-corpus-report.txt" + "data/test-abidiff/empty-report.txt", + "output/test-abidiff/test-empty-corpus-report-1.txt" }, { "data/test-abidiff/test-empty-corpus-2.xml", "data/test-abidiff/test-empty-corpus-2.xml", - "data/test-abidiff/test-empty-corpus-report.txt", - "output/test-abidiff/test-empty-corpus-report.txt" + "data/test-abidiff/empty-report.txt", + "output/test-abidiff/test-empty-corpus-report-1.txt" + }, + { + "data/test-abidiff/test-crc-0.xml", + "data/test-abidiff/test-crc-1.xml", + "data/test-abidiff/empty-report.txt", + "output/test-abidiff/test-crc-report-0-1.txt" + }, + { + "data/test-abidiff/test-crc-1.xml", + "data/test-abidiff/test-crc-0.xml", + "data/test-abidiff/empty-report.txt", + "output/test-abidiff/test-crc-report-1-0.txt" + }, + { + "data/test-abidiff/test-crc-1.xml", + "data/test-abidiff/test-crc-2.xml", + "data/test-abidiff/test-crc-report.txt", + "output/test-abidiff/test-crc-report-1-2.txt" }, // This should be the last entry. {0, 0, 0, 0} diff --git a/tests/test-read-write.cc b/tests/test-read-write.cc index ffca005251c0..54bc2b5e9fb2 100644 --- a/tests/test-read-write.cc +++ b/tests/test-read-write.cc @@ -238,6 +238,12 @@ InOutSpec in_out_specs[] = "data/test-read-write/test28-without-std-vars-ref.xml", "output/test-read-write/test28-without-std-vars.xml" }, + { + "data/test-read-write/test-crc.xml", + "", + "data/test-read-write/test-crc.xml", + "output/test-read-write/test-crc.xml", + }, // This should be the last entry. {NULL, NULL, NULL, NULL} }; diff --git a/tests/test-symtab.cc b/tests/test-symtab.cc index e843738bedad..830f3ec80608 100644 --- a/tests/test-symtab.cc +++ b/tests/test-symtab.cc @@ -410,3 +410,18 @@ TEST_CASE("Symtab::SimpleKernelSymtabs", "[symtab, basic, kernel, ksymtab]") } } } + +TEST_CASE("Symtab::KernelSymtabsWithCRC", "[symtab, crc, kernel, ksymtab]") +{ + const std::string base_path = "kernel-modversions/"; + + GIVEN("a binary with one function and one variable (GPL) exported") + { + const std::string binary = base_path + "one_of_each.ko"; + const corpus_sptr& corpus = assert_symbol_count(binary, 2, 2); + CHECK(corpus->lookup_function_symbol("exported_function")->get_crc() != 0); + CHECK(corpus->lookup_function_symbol("exported_function_gpl")->get_crc() != 0); + CHECK(corpus->lookup_variable_symbol("exported_variable")->get_crc() != 0); + CHECK(corpus->lookup_variable_symbol("exported_variable_gpl")->get_crc() != 0); + } +}