From patchwork Fri Jul 3 16:46:50 2020 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: 39903 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 8DEEC3844079; Fri, 3 Jul 2020 16:48:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8DEEC3844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794933; bh=ZMRxlLUp/Cnf94I4kCaQMrEruJZ9M1pS8XzKivdWLYY=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=b9b12qnE7WGU6pZrXiE/A2HxPWq3IFKT4JK3wOi914dbFRXp70IEbn5Vo3146pIa8 YPbpOJVoqiDxyVVW8Uf3I5KeIdDFeLjbK30JTt/g9/BwbZsWJbNHJiE/TbKCDDG6Cq FN95j+Qy5FoW7Yyu8/eHphdhRUD6i8ewa+nCLf1k= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by sourceware.org (Postfix) with ESMTPS id C77C63844079 for ; Fri, 3 Jul 2020 16:48:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C77C63844079 Received: by mail-qt1-x84a.google.com with SMTP id q7so3837297qtq.14 for ; Fri, 03 Jul 2020 09:48:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZMRxlLUp/Cnf94I4kCaQMrEruJZ9M1pS8XzKivdWLYY=; b=f7qtVt/Ju/7rCSmAlp7np/wHPtCm7hG+PXXWfomHdaRany6qvHjCDAp8zVvsaUxiN2 tQn7u151IXkBEHr7Jkg/BtmyRVeZHPjQMRIjWdKU4YfT5G/UyB0eus9JgWKwFneCelrB Jx0IZ0bqA48UFlpwZH9QxrZdEqBZAbba6LnXB5xbrrj4tABp6JwyRAZC77wVCetCc0YZ 1WqGcwV64g/YGqnyOnEoqno42PYSfB6edI0V6vmfXTlJrCeno77bFCdMUdTAswAo+YVU l/8qkUd6S8phKa/riMGs3ceC9exepCiNPu1L99g8HX5QpsWY4rfLm94Pa9af8noGmRU3 Uqhg== X-Gm-Message-State: AOAM532Dj9OIsqGw5wtNXi61BrmwS/zZbJRL1R8RPsW6v9tLcnaj4QPY 7FFaKZY8vCrahGNX29UxmwoYGqIZTY66hMLtzgMUG0KIVO3cT4swvJT3xX41chkbpb/zjPalenu Jy4Rx3RRryzQJBUbOocmqvXqoQa+yBGtFdAXptubQrxnm05fgwkPA31X3V8iuHyHc2Zn93zg= X-Google-Smtp-Source: ABdhPJwGS788Fmse2k7tKU05kO89TQDn/vM7eTnz4w3JhcBg0tjKFO5xNUA6Vk2ld0lyLnAyL2zgPv6TWTvCbQ== X-Received: by 2002:ad4:4672:: with SMTP id z18mr36955605qvv.104.1593794899170; Fri, 03 Jul 2020 09:48:19 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:50 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-21-maennich@google.com> Mime-Version: 1.0 References: <20200619214305.562-1-maennich@google.com> <20200703164651.1510825-1-maennich@google.com> X-Mailer: git-send-email 2.27.0.212.ge8ba1cc988-goog Subject: [PATCH v2 20/21] symtab: Add support for MODVERSIONS (CRC checksums) To: libabigail@sourceware.org X-Spam-Status: No, score=-18.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. 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-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/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.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-ir.cc | 30 +- src/abg-reader.cc | 8 + src/abg-reporter-priv.cc | 18 +- src/abg-symtab-reader.cc | 25 + src/abg-writer.cc | 12 +- tests/data/Makefile.am | 14 +- ...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.cc | 34 +- tests/test-read-write.cc | 6 + tests/test-symtab.cc | 15 + 22 files changed, 5025 insertions(+), 65 deletions(-) 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 c150075df3b8..6c368f03ddf8 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -854,6 +854,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&); @@ -879,6 +880,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* @@ -953,6 +955,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-ir.cc b/src/abg-ir.cc index 5a0f9f968034..268d478cb871 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -24,13 +24,14 @@ /// /// Definitions for the Internal Representation artifacts of libabigail. -#include -#include -#include #include +#include +#include #include -#include #include +#include +#include +#include #include "abg-cxx-compat.h" #include "abg-internal.h" @@ -1301,6 +1302,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_; @@ -1318,6 +1320,7 @@ struct elf_symbol::priv is_common_(false), is_linux_string_cst_(false), is_in_ksymtab_(false), + crc_(0), is_suppressed_(false) {} @@ -1333,6 +1336,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), @@ -1346,6 +1350,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_) @@ -1404,6 +1409,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, @@ -1417,6 +1423,7 @@ elf_symbol::elf_symbol(const environment* e, vi, is_linux_string_cst, is_in_ksymtab, + crc, is_suppressed)) {} @@ -1476,11 +1483,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; } @@ -1501,7 +1509,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. @@ -1708,6 +1718,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 fbdcce590bc3..3f636d00f9b8 100644 --- a/src/abg-reader.cc +++ b/src/abg-reader.cc @@ -2835,6 +2835,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); @@ -2855,6 +2859,10 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node, is_defined, is_common, version, visibility, /*is_linux_string_cst=*/false); + + if (crc != 0) + e->set_crc(crc); + return e; } diff --git a/src/abg-reporter-priv.cc b/src/abg-reporter-priv.cc index 9f2c5a4afdd4..2ca48c2143af 100644 --- a/src/abg-reporter-priv.cc +++ b/src/abg-reporter-priv.cc @@ -57,8 +57,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 @@ -1194,6 +1193,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 f84ed79dae17..c50c0f643386 100644 --- a/src/abg-symtab-reader.cc +++ b/src/abg-symtab-reader.cc @@ -176,6 +176,7 @@ symtab::load_(Elf* elf_handle, const bool is_kernel = elf_helpers::is_linux_kernel(elf_handle); abg_compat::unordered_set exported_kernel_symbols; + abg_compat::unordered_map crc_values; const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle); @@ -220,6 +221,13 @@ 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.insert(std::make_pair(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. @@ -319,6 +327,23 @@ symtab::load_(Elf* elf_handle, has_ksymtab_entries_ = true; } + // Now add the CRC values + for (abg_compat::unordered_map::const_iterator + it = crc_values.begin(), + end = crc_values.end(); + it != end; ++it) + { + const name_symbol_map_type::const_iterator r = + name_symbol_map_.find(it->first); + if (r == name_symbol_map_.end()) + continue; + + for (elf_symbols::const_iterator sym_it = r->second.begin(), + sym_end = r->second.end(); + sym_it != sym_end; ++sym_it) + (*sym_it)->set_crc(it->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 723db1a51256..f7a773defe6d 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -26,14 +26,15 @@ /// native XML format is named "abixml". #include "config.h" +#include #include +#include #include +#include #include -#include #include -#include #include -#include +#include #include "abg-cxx-compat.h" #include "abg-tools-utils.h" @@ -3059,6 +3060,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 << "/>"; return true; diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 54ccb103c8ab..f39a6d427b1d 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 \ @@ -1851,4 +1854,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/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 24c25c06d61c..d3c0f74c62de 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.cc b/tests/test-abidiff.cc index dcb1401b5172..b4c5869de41a 100644 --- a/tests/test-abidiff.cc +++ b/tests/test-abidiff.cc @@ -92,7 +92,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" }, { @@ -104,26 +104,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 7d24bee57051..b768c13cbd57 100644 --- a/tests/test-read-write.cc +++ b/tests/test-read-write.cc @@ -253,6 +253,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 62e16e535f49..b8f729855436 100644 --- a/tests/test-symtab.cc +++ b/tests/test-symtab.cc @@ -425,3 +425,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); + } +}