From patchwork Fri Jul 3 16:46:31 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: 39884 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 604993844079; Fri, 3 Jul 2020 16:47:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 604993844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794861; bh=R0k0bmRmHWlMXsZQ4l93Qyy6b7XPfg32VrU7d+Bz7Jc=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Jm4iJ9OD2GqL6dT/7xb8coxPM2HjgM1XFOrfT6yfNqds0E9GdQaxfrkWPd6UeL/IJ iHNf8B9UIrMGq/RVS9RGHRqGCwwJ/B8PcyeIrRnPWjumsslPD5vWkTrQeoddTLwa5U 8fkhGMRE90TgyLRpV6y+xqbn4upk58QMXgrqaGxM= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wr1-x44a.google.com (mail-wr1-x44a.google.com [IPv6:2a00:1450:4864:20::44a]) by sourceware.org (Postfix) with ESMTPS id 399A6384402F for ; Fri, 3 Jul 2020 16:47:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 399A6384402F Received: by mail-wr1-x44a.google.com with SMTP id i14so32066383wru.17 for ; Fri, 03 Jul 2020 09:47:38 -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=R0k0bmRmHWlMXsZQ4l93Qyy6b7XPfg32VrU7d+Bz7Jc=; b=YcXhb4MoxX3bBQAtj+RYcTXFOt9p1TQBgfYxs0H85G2CnGVH4f9q8lce99H3PfiiBx 0+aP5FhTx/Fl8RrIaMd2DxY/SmxGCkL7BAvUmRpEqv+lSKyZR1NQgLUk9oBoiI6SSeVo NxPx4pfYgtEztR15ZHcF0eCwAVbH06rlEUoI7fKCjKsRPJ/O32v37sXctexHc2LQQ4wN r3d2C/mUIDC91ckLpnSstlMNybVjFiuLewLLtnp9fBlNWA50FLUycX2H6fvbF1fqAAxV lr0JF+xmH2aAkhRnpjLJ1Alwg+bZmJhKZz3+/goOKKnuoiiard2dHlSRmdIVKIOX0XE+ J4gw== X-Gm-Message-State: AOAM530/qQG5SSY9xdI6/Kjto2UyVUStk5IFog5IZI0m8J9gXWp1XjUn q1Agq0Vvn0oaQrlm2hksBgKeLxUQKEwnfIauBXnJHBwzevyLoIYv4VPbnRXmn7GH57GwF8rRvX4 +r/FHv70Nw6m3KIIQFXbsNEVwj7aihcgUobD3byhb/DvdnMhehNdRN2xLpU0xYMhsUrTS/lQ= X-Google-Smtp-Source: ABdhPJxwFIg3c1Or4dMkw5DE85N5aYsRj0erxQoc/lxWuZzsBhPYKRppM7XBrGODLytuQAF1GHGlZXHpTwXO7Q== X-Received: by 2002:a5d:43d0:: with SMTP id v16mr39446817wrr.296.1593794857166; Fri, 03 Jul 2020 09:47:37 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:31 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-2-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 01/21] abg-cxx-compat: add simplified version of std::optional To: libabigail@sourceware.org X-Spam-Status: No, score=-23.2 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" In the absence (but desire) of std::optional, add a simplified version of it to abg_compat:: in case we are compiling with a pre-C++17 standard. Otherwise use std::optional from directly. This is being used by a later patch and serves as a prerequisite. It only serves the purpose of being a compatibility implementation and does not claim to be complete at all. Just enough for the project's needs. * include/abg-cxx-compat.h (abg_compat::optional): Add new class. * tests/tests-cxx-compat.cc: Add new test cases. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-cxx-compat.h | 86 ++++++++++++++++++++++++++++++++++++++++ tests/test-cxx-compat.cc | 51 ++++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/include/abg-cxx-compat.h b/include/abg-cxx-compat.h index 714177183945..1283e9191d46 100644 --- a/include/abg-cxx-compat.h +++ b/include/abg-cxx-compat.h @@ -23,6 +23,8 @@ #ifndef __ABG_CXX_COMPAT_H #define __ABG_CXX_COMPAT_H +// C++11 support (mostly via tr1 if compiled with earlier standard) + #if __cplusplus >= 201103L #include @@ -39,6 +41,18 @@ #endif +// C++17 support (via custom implementations if compiled with earlier standard) + +#if __cplusplus >= 201703L + +#include + +#else + +#include // for throwing std::runtime_error("bad_optional_access") + +#endif + namespace abg_compat { #if __cplusplus >= 201103L @@ -77,6 +91,78 @@ using std::tr1::unordered_set; #endif +#if __cplusplus >= 201703L + +using std::optional; + +#else + +// + +/// Simplified implementation of std::optional just enough to be used as a +/// replacement for our purposes and when compiling with pre C++17. +/// +/// The implementation intentionally does not support a whole lot of features +/// to minimize the maintainence effort with this. +template class optional +{ + bool has_value_; + T value_; + +public: + optional() : has_value_(false), value_() {} + optional(const T& value) : has_value_(true), value_(value) {} + + bool + has_value() const + { + return has_value_; + } + + const T& + value() const + { + if (!has_value_) + throw std::runtime_error("bad_optional_access"); + return value_; + } + + const T + value_or(const T& default_value) const + { + if (!has_value_) + return default_value; + return value_; + } + + const T& + operator*() const + { return value_; } + + T& + operator*() + { return value_; } + + const T* + operator->() const + { return &value_; } + + T* + operator->() + { return &value_; } + + optional& + operator=(const T& value) + { + has_value_ = true; + value_ = value; + return *this; + } + + explicit operator bool() const { return has_value_; } +}; + +#endif } #endif // __ABG_CXX_COMPAT_H diff --git a/tests/test-cxx-compat.cc b/tests/test-cxx-compat.cc index 0a230a54e1a5..adeb7b8d7e4f 100644 --- a/tests/test-cxx-compat.cc +++ b/tests/test-cxx-compat.cc @@ -28,3 +28,54 @@ #include "abg-cxx-compat.h" +using abg_compat::optional; + +TEST_CASE("OptionalConstruction", "[abg_compat::optional]") +{ + optional opt1; + REQUIRE_FALSE(opt1.has_value()); + + optional opt2(true); + REQUIRE(opt2.has_value()); + CHECK(opt2.value() == true); + + optional opt3(false); + REQUIRE(opt3.has_value()); + CHECK(opt3.value() == false); +} + +TEST_CASE("OptionalValue", "[abg_compat::optional]") +{ + optional opt; + REQUIRE_FALSE(opt.has_value()); + REQUIRE_THROWS(opt.value()); + + opt = true; + REQUIRE_NOTHROW(opt.value()); + CHECK(opt.value() == true); +} + +TEST_CASE("OptionalValueOr", "[abg_compat::optional]") +{ + optional opt; + REQUIRE_FALSE(opt.has_value()); + + const std::string& mine = "mine"; + // Ensure we get a copy of our own value. + CHECK(opt.value_or(mine) == mine); + + // Now set the value + const std::string& other = "other"; + opt = other; + CHECK(opt.value_or(mine) != mine); + CHECK(opt.value_or(mine) == other); +} + +TEST_CASE("OptionalDeref", "[abg_compat::optional]") +{ + optional opt("asdf"); + REQUIRE(opt.has_value()); + + CHECK(*opt == "asdf"); + CHECK(opt->size() == 4); +} From patchwork Fri Jul 3 16:46:32 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: 39885 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 A8FEB386F44A; Fri, 3 Jul 2020 16:47:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A8FEB386F44A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794861; bh=8qw5GfPGmVc393aUCLS/D80TJFnjcA1tEHmU5k8NzHg=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=RlebFRrlK93OtmuKn9CoqTpefm8LqmvDXjQcq6Xy2Le3sfGdW2lAZvIh2O7zLXxh4 LRu+oNUoI26FDheJfFEJfA0yJ+PJhWgrnb7ECAA5eoFYiddvQxcPrUr9XSnQCetT9j iD4vHrPQw7aqAZLlnkvN7uOEjK8NtLvSPCKJ4l60= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by sourceware.org (Postfix) with ESMTPS id D8940384402F for ; Fri, 3 Jul 2020 16:47:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D8940384402F Received: by mail-qt1-x849.google.com with SMTP id e6so21182754qtb.19 for ; Fri, 03 Jul 2020 09:47:39 -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=8qw5GfPGmVc393aUCLS/D80TJFnjcA1tEHmU5k8NzHg=; b=H+CCkKFPbdl5loTSOztkqrA+l6JpH4L6vgWpgqmDys209jrW5QwwUub/eXLLQZpUnX IMZ6S7lLs76pkJU1sP7szQeTjogFfsGetDpDS8te84W669i3hf388SpX84n1Fn8F+xNZ RZfQBeY1KH7PyGlJ7X7//594WPFoH7YzOX7F0hXgFVe10NdUHNtd8jSLRryvRpr4A0+m QlJYi69y64gEXujtzpn+A6DHj+mMMJ08wJ/pwfEa7C52vKXfSD3lI6sU+VTdTKW2bUKo SHcaeLgz4oN4uVnqJZ/p4j5NbEaFybhMRpUBpsJFfdrkh+guaILPRbi0eTc6nQ9jE2bg pNUw== X-Gm-Message-State: AOAM532PlTB6npEMSU1CNtjG6gjkfkGt5zVcM6E2JzUtM1dg/oEQU6oS 6+pjtVGGS7JnKN6aLY7/4wk2oGo8OIrERc4R9Urd5CiZX2HpMd9qeQ6ECmld/LlhHbYfmAGybnm pWHWsjjChV6JWFs9EGtK39U97cLS91yDpASleEGQM4m+7h7DFDGMQcAk16rPUIiyg1mJl6/A= X-Google-Smtp-Source: ABdhPJy6KOnYupK12E6naE1kmsA7Yc/1p7LKh7VBiPJcJxBeRFY53iAduWAJIYFLNt/eot53onJvnhJfLq6R0A== X-Received: by 2002:a0c:a4e3:: with SMTP id x90mr6889267qvx.36.1593794859271; Fri, 03 Jul 2020 09:47:39 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:32 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-3-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 02/21] abg-cxx-compat: more support: std::bind and friends To: libabigail@sourceware.org X-Spam-Status: No, score=-22.0 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Add abg_compat::{bind,function,placeholders} to the compatibility layer. That is made use of in a later patch. As usual, for C++ standards that natively support this functionality (C++11 and later), the native implementation is aliased into the abg_compat namespace. * include/abg-cxx-compat.h: add support for abg_compat::{bind,function,placeholders} Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-cxx-compat.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/abg-cxx-compat.h b/include/abg-cxx-compat.h index 1283e9191d46..cab2883b231e 100644 --- a/include/abg-cxx-compat.h +++ b/include/abg-cxx-compat.h @@ -58,8 +58,15 @@ namespace abg_compat { #if __cplusplus >= 201103L // +using std::bind; +using std::function; using std::hash; +namespace placeholders +{ +using namespace std::placeholders; +} + // using std::shared_ptr; using std::weak_ptr; @@ -75,8 +82,15 @@ using std::unordered_set; #else // +using std::tr1::bind; +using std::tr1::function; using std::tr1::hash; +namespace placeholders +{ +using namespace std::tr1::placeholders; +} + // using std::tr1::shared_ptr; using std::tr1::weak_ptr; From patchwork Fri Jul 3 16:46:33 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: 39886 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 EED643844038; Fri, 3 Jul 2020 16:47:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EED643844038 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794865; bh=mrghdtHAySIBsioKmcYriEEx5Vvebb2GJ8AAq7jXiXU=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=El5oZwxjTdv1Q9Btv5ABQYtPQv30NCz/7CwPf3VFl6ZqXhmMmLwCyA1PUDUbh761S isBZX8gPxdlCsdYDVanzpcqJBtghMHXRoAUAWc9+PeQEHSf7pKwzBiVu40BzrEEpoe sPEZ4jAD7kpYZPqLrnGF26jAE1AiaIu0GNSf+3fI= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wm1-x34a.google.com (mail-wm1-x34a.google.com [IPv6:2a00:1450:4864:20::34a]) by sourceware.org (Postfix) with ESMTPS id 8EB34384240C for ; Fri, 3 Jul 2020 16:47:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8EB34384240C Received: by mail-wm1-x34a.google.com with SMTP id e15so35575850wme.8 for ; Fri, 03 Jul 2020 09:47:42 -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=mrghdtHAySIBsioKmcYriEEx5Vvebb2GJ8AAq7jXiXU=; b=j7l1Ty93jDtJSVd6XYsmG5eaLtUBRtcev/gOgjW7YC8cBH/OWV5X9e3IIxDsIXPQS9 SxmYEJ6+tj92wTeL2nIoJSy/Rl/MKia5tG1Y33qDf7Qn4SY6bG+2GOuPd3Bvcg/TuxQb L0Z26RJGbNoBCwyIeLBHXH9x25CZ1LJEi0DKc5ScUAhQmwOedsBxSLN4W8vuupY+68nr I6cLDPuQQll4egjuPu64PMPGfFmAJ+uYw9NByygVhHM/sXj9LU56ONBZBq9FsXA9g3fM tLvblPBzU+YKOwIkPLoYYsFwD2kJtD9/3aupDHor29DgqOq1Vz5mlRFxxp6vaUUdOYXV peaQ== X-Gm-Message-State: AOAM5330BQO8FnZmtbbvs9NNf2zEiNoEG+WdCNBC09TJkFUQCkRfGGlt yE3yVQ4ZaVLfrHZYsDlCPyxvEfErZPRhaGKUk7oWWXzFux13o4EfvEmfJ1uK95RLJoDDeJzMYdV aDg3ZzhVVU2VMUb9Cdp+wEdkVl2F3e4H1nSatksZnoAyGJeWbKjrST7FBFtr63Bjp+vhxDyk= X-Google-Smtp-Source: ABdhPJz9HL6R9AwxHTJ4kqQoupkeFUtjimmgl3GgiI5gyFS9D/wDVoBE3l7S3pswHemTa2XT7HmuLbiAS/0irg== X-Received: by 2002:a1c:4e08:: with SMTP id g8mr38974909wmh.77.1593794861559; Fri, 03 Jul 2020 09:47:41 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:33 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-4-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 03/21] abg-ir: elf_symbol: add is_in_ksymtab field To: libabigail@sourceware.org X-Spam-Status: No, score=-23.7 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Being exported through a ksymtab (in case of Linux Kernel binaries) is actually a property of the Elf symbol itself and we can therefore track it along with the symbol that we collect from symtab. While tracking is currently done by keeping separate symbol lists and maps for symtab and ksymtab symbols, they can be consolidated having a property to indicate whether this symbol also appeared as a ksymtab entry. Hence, and for future changes in this area, add this property and update all references. The flag is false initially unless otherwise specified. * include/abg-ir.h (elf_symbol::elf_symbol): Add is_in_ksymtab parameter. (elf_symbol::create): Likewise. (elf_symbol::is_in_ksymtab): New getter declaration. (elf_symbol::set_is_in_ksymtab): New setter declaration. * src/abg-ir.cc (elf_symbol::priv::priv): Add is_in_ksymtab parameter. (elf_symbol::priv::is_in_ksymtab_): New field. (elf_symbol::elf_symbol): Add is_in_ksymtab parameter. (elf_symbol::create): Likewise. (elf_symbol::is_in_ksymtab): New getter implementation. (elf_symbol::set_is_in_ksymtab): New setter implementation. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-ir.h | 34 +++++++++------ src/abg-ir.cc | 105 +++++++++++++++++++++++++++++------------------ 2 files changed, 86 insertions(+), 53 deletions(-) diff --git a/include/abg-ir.h b/include/abg-ir.h index d81de217702b..5766385c8b73 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -851,8 +851,9 @@ private: bool d, bool c, const version& ve, - visibility vi, - bool is_linux_string_cst = false); + visibility vi, + bool is_linux_string_cst = false, + bool is_in_ksymtab = false); elf_symbol(const elf_symbol&); @@ -865,17 +866,18 @@ public: create(); static elf_symbol_sptr - create(const environment* e, - size_t i, - size_t s, - const string& n, - type t, - binding b, - bool d, - bool c, - const version& ve, - visibility vi, - bool is_linux_string_cst = false); + create(const environment* e, + size_t i, + size_t s, + const string& n, + type t, + binding b, + bool d, + bool c, + const version& ve, + visibility vi, + bool is_linux_string_cst = false, + bool is_in_ksymtab = false); const environment* get_environment() const; @@ -943,6 +945,12 @@ public: bool is_variable() const; + bool + is_in_ksymtab() const; + + void + set_is_in_ksymtab(bool is_in_ksymtab); + const elf_symbol_sptr get_main_symbol() const; diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 4813035e5935..00fc00b064d1 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -1300,6 +1300,7 @@ struct elf_symbol::priv // STT_COMMON definition of that name that has the largest size. bool is_common_; bool is_linux_string_cst_; + bool is_in_ksymtab_; elf_symbol_wptr main_symbol_; elf_symbol_wptr next_alias_; elf_symbol_wptr next_common_instance_; @@ -1314,20 +1315,22 @@ struct elf_symbol::priv visibility_(elf_symbol::DEFAULT_VISIBILITY), is_defined_(false), is_common_(false), - is_linux_string_cst_(false) + is_linux_string_cst_(false), + is_in_ksymtab_(false) {} - priv(const environment* e, - size_t i, - size_t s, - const string& n, - elf_symbol::type t, - elf_symbol::binding b, - bool d, - bool c, - const elf_symbol::version& ve, - elf_symbol::visibility vi, - bool is_linux_string_cst) + priv(const environment* e, + size_t i, + size_t s, + const string& n, + elf_symbol::type t, + elf_symbol::binding b, + bool d, + bool c, + const elf_symbol::version& ve, + elf_symbol::visibility vi, + bool is_linux_string_cst, + bool is_in_ksymtab) : env_(e), index_(i), size_(s), @@ -1338,7 +1341,8 @@ struct elf_symbol::priv visibility_(vi), is_defined_(d), is_common_(c), - is_linux_string_cst_(is_linux_string_cst) + is_linux_string_cst_(is_linux_string_cst), + is_in_ksymtab_(is_in_ksymtab) { if (!is_common_) is_common_ = type_ == COMMON_TYPE; @@ -1384,19 +1388,30 @@ elf_symbol::elf_symbol() /// /// @param is_linux_string_cst true if the symbol is a Linux Kernel /// string constant defined in the __ksymtab_strings section. -elf_symbol::elf_symbol(const environment* e, - size_t i, - size_t s, - const string& n, - type t, - binding b, - bool d, - bool c, - const version& ve, - visibility vi, - bool is_linux_string_cst) - : priv_(new priv(e, i, s, n, t, b, d, - c, ve, vi, is_linux_string_cst)) +elf_symbol::elf_symbol(const environment* e, + size_t i, + size_t s, + const string& n, + type t, + binding b, + bool d, + bool c, + const version& ve, + visibility vi, + bool is_linux_string_cst, + bool is_in_ksymtab) + : priv_(new priv(e, + i, + s, + n, + t, + b, + d, + c, + ve, + vi, + is_linux_string_cst, + is_in_ksymtab)) {} /// Factory of instances of @ref elf_symbol. @@ -1443,20 +1458,22 @@ elf_symbol::create() /// @return a (smart) pointer to a newly created instance of @ref /// elf_symbol. elf_symbol_sptr -elf_symbol::create(const environment* e, - size_t i, - size_t s, - const string& n, - type t, - binding b, - bool d, - bool c, - const version& ve, - visibility vi, - bool is_linux_string_cst) -{ - elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, - vi, is_linux_string_cst)); +elf_symbol::create(const environment* e, + size_t i, + size_t s, + const string& n, + type t, + binding b, + bool d, + bool c, + const version& ve, + visibility vi, + bool is_linux_string_cst, + bool is_in_ksymtab) +{ + elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi, + is_linux_string_cst, + is_in_ksymtab)); sym->priv_->main_symbol_ = sym; return sym; } @@ -1676,6 +1693,14 @@ bool elf_symbol::is_variable() const {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;} +bool +elf_symbol::is_in_ksymtab() const +{return priv_->is_in_ksymtab_;} + +void +elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab) +{priv_->is_in_ksymtab_ = is_in_ksymtab;} + /// @name Elf symbol aliases /// /// An alias A for an elf symbol S is a symbol that is defined at the From patchwork Fri Jul 3 16:46:34 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: 39887 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 65FE6384402F; Fri, 3 Jul 2020 16:47:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 65FE6384402F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794867; bh=8FdbbTMciZcgKbTmN8sZuy/sl2HraJgPx/WrQSdzWRw=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=NiaYXtLFvmF4NJHFHirX4NcrbG7iUv3HhM2waGiRqOJsUAYdwaXNBzO7oYF/4P4NF Dto+Kre7YhcQWX/Pj8brqFTHkAnV2cOZHtxTIaAFK2FibNmgo6KFjScRD6wfBrW3fd KZSQoJKRx6sjnqo+3rF0pBkvxvGVL6zKKBaRq/P4= 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 EF7C33844079 for ; Fri, 3 Jul 2020 16:47:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EF7C33844079 Received: by mail-qt1-x84a.google.com with SMTP id m25so17582127qtk.1 for ; Fri, 03 Jul 2020 09:47:43 -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=8FdbbTMciZcgKbTmN8sZuy/sl2HraJgPx/WrQSdzWRw=; b=djSYRrzS7/PdTbDMVXTqaw0Db1yJfBycaAdyrqFYqxgx8xJZdd9ulpr3e7FgvhpOIH lZJTfrmnDB+EA3FJRgGTjdPtBOWtdXx+FuKYBzsa4PJTdbN95klXamJr/IECy6Z3mWwa uIZdoDQDzpHjPVpaICMNqjnoCOn5UOPQyzudPHGlmyYhv3+BVK+1CrzhdbwIMuTFGK+9 NVYsTz1ELCI7dAB2pCA/lkMpXN9bO9i+P9l1lJL2+NmRYCbtRYMM7wQH0m9/D5+QXgrA ssfaW/YTI3XdXt6B8axSJ733g25SoYogRSBRhoAHdCw90M3KCYo8gGRrVGSs0VYAVMN3 hwHA== X-Gm-Message-State: AOAM531X5sdktTpQiDoNANDrc0artmhZheshvug0AVHWLkC602NWQRm3 e8B03uuOKLrd6qENXtLNfQ6U/SvCmErjS/MPPqroHuC2cQldKSil1YS8xFA3/gONMZ4BoCdLayn jutLtSG8Pdzx4V/mEhg0AVxQ1stAV/LKIbtDDapva+iiXGknaCEqt+UcLmwKu6fREK3W25RQ= X-Google-Smtp-Source: ABdhPJz+G5HSPk1d6I/ZTynb3EPtn5Bk0rpZs8i0dGXAU5GGfaN/Lyms0xN+fGc9/SvG/bciJUh90ZLUDsV+YQ== X-Received: by 2002:a0c:bd88:: with SMTP id n8mr36978768qvg.194.1593794863501; Fri, 03 Jul 2020 09:47:43 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:34 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-5-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 04/21] abg-ir: elf_symbol: add is_suppressed field To: libabigail@sourceware.org X-Spam-Status: No, score=-22.4 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" In the context of libabigail and a single library run (when reading from dwarf or from xml), a symbol is either suppressed or it is not. While one could argue that this is a property of the read_context, the read_context might not be around anymore when the symbol still is. Hence, persist the 'is_suppressed' state along with the symbol itself. * include/abg-ir.h (elf_symbol::elf_symbol): Add is_suppressed parameter. (elf_symbol::create): Likewise. (elf_symbol::is_suppressed): New getter declaration. (elf_symbol::set_is_suppressed): New setter declaration. * src/abg-ir.cc (elf_symbol::priv::priv): Add is_suppressed parameter. (elf_symbol::priv::is_suppressed_): New field. (elf_symbol::elf_symbol): Add is_suppressed parameter. (elf_symbol::create): Likewise. (elf_symbol::is_suppressed): New getter implementation. (elf_symbol::set_is_suppressed): New setter implementation. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-ir.h | 12 ++++++++++-- src/abg-ir.cc | 29 ++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/include/abg-ir.h b/include/abg-ir.h index 5766385c8b73..838d3f80695a 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -853,7 +853,8 @@ private: const version& ve, visibility vi, bool is_linux_string_cst = false, - bool is_in_ksymtab = false); + bool is_in_ksymtab = false, + bool is_suppressed = false); elf_symbol(const elf_symbol&); @@ -877,7 +878,8 @@ public: const version& ve, visibility vi, bool is_linux_string_cst = false, - bool is_in_ksymtab = false); + bool is_in_ksymtab = false, + bool is_suppressed = false); const environment* get_environment() const; @@ -951,6 +953,12 @@ public: void set_is_in_ksymtab(bool is_in_ksymtab); + bool + is_suppressed() const; + + void + set_is_suppressed(bool is_suppressed); + const elf_symbol_sptr get_main_symbol() const; diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 00fc00b064d1..c69284f0946a 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -1301,6 +1301,7 @@ struct elf_symbol::priv bool is_common_; bool is_linux_string_cst_; bool is_in_ksymtab_; + bool is_suppressed_; elf_symbol_wptr main_symbol_; elf_symbol_wptr next_alias_; elf_symbol_wptr next_common_instance_; @@ -1316,7 +1317,8 @@ struct elf_symbol::priv is_defined_(false), is_common_(false), is_linux_string_cst_(false), - is_in_ksymtab_(false) + is_in_ksymtab_(false), + is_suppressed_(false) {} priv(const environment* e, @@ -1330,7 +1332,8 @@ struct elf_symbol::priv const elf_symbol::version& ve, elf_symbol::visibility vi, bool is_linux_string_cst, - bool is_in_ksymtab) + bool is_in_ksymtab, + bool is_suppressed) : env_(e), index_(i), size_(s), @@ -1342,7 +1345,8 @@ struct elf_symbol::priv is_defined_(d), is_common_(c), is_linux_string_cst_(is_linux_string_cst), - is_in_ksymtab_(is_in_ksymtab) + is_in_ksymtab_(is_in_ksymtab), + is_suppressed_(is_suppressed) { if (!is_common_) is_common_ = type_ == COMMON_TYPE; @@ -1399,7 +1403,8 @@ elf_symbol::elf_symbol(const environment* e, const version& ve, visibility vi, bool is_linux_string_cst, - bool is_in_ksymtab) + bool is_in_ksymtab, + bool is_suppressed) : priv_(new priv(e, i, s, @@ -1411,7 +1416,8 @@ elf_symbol::elf_symbol(const environment* e, ve, vi, is_linux_string_cst, - is_in_ksymtab)) + is_in_ksymtab, + is_suppressed)) {} /// Factory of instances of @ref elf_symbol. @@ -1469,11 +1475,12 @@ elf_symbol::create(const environment* e, const version& ve, visibility vi, bool is_linux_string_cst, - bool is_in_ksymtab) + bool is_in_ksymtab, + 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_in_ksymtab, is_suppressed)); sym->priv_->main_symbol_ = sym; return sym; } @@ -1701,6 +1708,14 @@ void elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab) {priv_->is_in_ksymtab_ = is_in_ksymtab;} +bool +elf_symbol::is_suppressed() const +{return priv_->is_suppressed_;} + +void +elf_symbol::set_is_suppressed(bool is_suppressed) +{priv_->is_suppressed_ = is_suppressed;} + /// @name Elf symbol aliases /// /// An alias A for an elf symbol S is a symbol that is defined at the From patchwork Fri Jul 3 16:46:35 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: 39888 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 AA4CE384402F; Fri, 3 Jul 2020 16:47:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA4CE384402F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794869; bh=ZH+lIwuupp3WVsF2ZgQPEijItKU4C60w6UDTOfKT3vw=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=DOTSSUou7JlqQ71EzO0RxLKpcPUr++m9EkJEzTcNULicIIFE4FORTqO+CUflUVP8x qlHDE80hK8zai515zHYWosSimbh1SCo/tXeN7vGonXTexVNDvpGwPzbcEfS5OYnaWo PP5/xFVf77LpAwmD8gWE/YvC7skSZ8Nj7h1BWnvM= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by sourceware.org (Postfix) with ESMTPS id 3D9F93844079 for ; Fri, 3 Jul 2020 16:47:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3D9F93844079 Received: by mail-qk1-x749.google.com with SMTP id 13so10135966qkk.10 for ; Fri, 03 Jul 2020 09:47:46 -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=ZH+lIwuupp3WVsF2ZgQPEijItKU4C60w6UDTOfKT3vw=; b=qIPSPGKbfggo/aeZA0/cmRrCCTD+acL4Px2WmJyI/n1IxeKfcSrqkgc8YWw7RLfJta s+uX717a8n5FedawfCb1SmK0gEsaNbTSpm5Um+eYAoRrtz+f6osN8Z6QiRaphhKtPure pYJzIsTWXQylXbfyefzu7zYJppp4cvjp/3azRaULHL31afUpDO03fFbLlsjF5hx7OWtc og5CFuzJpiXbwaKWphTK6S1hQyloTev138zMeYfqB2xeCGV967TBdd4rLDjR0zcxfgHt VoZWex+b6D7ey4x0OvOotHkUcquHRfvkb/WiTqdKOF4/Fqoao679WnkPhbOmPI8te1g5 PQyA== X-Gm-Message-State: AOAM533usdabfXxqPeNE5t5qS9VcptfF9NYGjJqfjrQFi2ID7jsY4xMm VPPlyQUJa5cbXL/zmmGyQjccGABcxPEiP0yjMhkfUcAK2SVLGEVpryqGA/ewTV+1UjDTKER9R6A xxhIhM7xpqTNyl7ev6JL+1I+AuVrFBya3v0hi9OR+/YOhOJ22JhKew+0S55joFj+KZCOY+hM= X-Google-Smtp-Source: ABdhPJw813wZK9uu6Y9ZKAukMocYI7vrP69SWbe3+f6dA2rqLIz1LOe3KeSWSNnFxuKTKkrHkvTiD2lzImBTOQ== X-Received: by 2002:a0c:f345:: with SMTP id e5mr23032288qvm.84.1593794865764; Fri, 03 Jul 2020 09:47:45 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:35 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-6-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 05/21] dwarf-reader split: create abg-symtab-reader.{h, cc} and test case To: libabigail@sourceware.org X-Spam-Status: No, score=-22.9 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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" abg-symtab-reader.{h,cc} shall contain the refactored symtab reader. Create the stub files, an empty unit test and hook everything up in the make system. * include/abg-symtab-reader.h: New header file. * include/Makefile.am: Add new header file abg-symtab-reader.h. * src/Makefile.am: Add new source file abg-symtab-reader.cc. * src/abg-symtab-reader.cc: New source file. * tests/Makefile.am: Add new test case runtestsymtabreader. * tests/test-symtab-reader.cc: New test source file. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/Makefile.am | 3 ++- include/abg-symtab-reader.h | 39 +++++++++++++++++++++++++++++++++++++ src/Makefile.am | 1 + src/abg-symtab-reader.cc | 36 ++++++++++++++++++++++++++++++++++ tests/Makefile.am | 4 ++++ tests/test-symtab-reader.cc | 30 ++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 include/abg-symtab-reader.h create mode 100644 src/abg-symtab-reader.cc create mode 100644 tests/test-symtab-reader.cc diff --git a/include/Makefile.am b/include/Makefile.am index b547525238ec..639906aafe5b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -25,6 +25,7 @@ abg-version.h \ abg-viz-common.h \ abg-viz-dot.h \ abg-viz-svg.h \ -abg-regex.h +abg-regex.h \ +abg-symtab-reader.h EXTRA_DIST = abg-version.h.in diff --git a/include/abg-symtab-reader.h b/include/abg-symtab-reader.h new file mode 100644 index 000000000000..b61e6399fe93 --- /dev/null +++ b/include/abg-symtab-reader.h @@ -0,0 +1,39 @@ +// -*- Mode: C++ -*- +// +// Copyright (C) 2020 Google, Inc. +// +// This file is part of the GNU Application Binary Interface Generic +// Analysis and Instrumentation Library (libabigail). This library is +// free software; you can redistribute it and/or modify it under the +// terms of the GNU Lesser General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) any +// later version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this program; see the file COPYING-LGPLV3. If +// not, see . +// +// Author: Matthias Maennich + +/// @file +/// +/// This contains the declarations for the symtab reader. + +#ifndef __ABG_SYMTAB_READER_H__ +#define __ABG_SYMTAB_READER_H__ + +namespace abigail +{ + +namespace symtab_reader +{ + +} // end namespace symtab_reader +} // end namespace abigail + +#endif // __ABG_SYMTAB_READER_H__ diff --git a/src/Makefile.am b/src/Makefile.am index 1153a5f8b158..dff17d9c02c1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ abg-tools-utils.cc \ abg-elf-helpers.h \ abg-elf-helpers.cc \ abg-regex.cc \ +abg-symtab-reader.cc \ $(CXX11_SOURCES) libabigail_la_LIBADD = $(DEPS_LIBS) diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc new file mode 100644 index 000000000000..1f934d3a7609 --- /dev/null +++ b/src/abg-symtab-reader.cc @@ -0,0 +1,36 @@ +// -*- Mode: C++ -*- +// +// Copyright (C) 2020 Google, Inc. +// +// This file is part of the GNU Application Binary Interface Generic +// Analysis and Instrumentation Library (libabigail). This library is +// free software; you can redistribute it and/or modify it under the +// terms of the GNU Lesser General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) any +// later version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this program; see the file COPYING-LGPLV3. If +// not, see . +// +// Author: Matthias Maennich + +/// @file +/// +/// This contains the definition of the symtab reader + +#include "abg-symtab-reader.h" + +namespace abigail +{ + +namespace symtab_reader +{ + +} // end namespace symtab_reader +} // end namespace abigail diff --git a/tests/Makefile.am b/tests/Makefile.am index c2d4d1dc5d35..068725326b75 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -50,6 +50,7 @@ runtestkmiwhitelist \ runtestlookupsyms \ runtestreadwrite \ runtestsymtab \ +runtestsymtabreader \ runtesttoolsutils \ $(FEDABIPKGDIFF_TEST) \ $(ZIP_ARCHIVE_TESTS) \ @@ -158,6 +159,9 @@ runtestcxxcompat_LDADD = libcatch.la $(top_builddir)/src/libabigail.la runtestsymtab_SOURCES = test-symtab.cc runtestsymtab_LDADD = libtestutils.la libcatch.la $(top_builddir)/src/libabigail.la +runtestsymtabreader_SOURCES = test-symtab-reader.cc +runtestsymtabreader_LDADD = libcatch.la $(top_builddir)/src/libabigail.la + runtestsvg_SOURCES=test-svg.cc runtestsvg_LDADD=$(top_builddir)/src/libabigail.la diff --git a/tests/test-symtab-reader.cc b/tests/test-symtab-reader.cc new file mode 100644 index 000000000000..c2e30d661017 --- /dev/null +++ b/tests/test-symtab-reader.cc @@ -0,0 +1,30 @@ +// -*- Mode: C++ -*- +// +// Copyright (C) 2020 Google, Inc. +// +// This file is part of the GNU Application Binary Interface Generic +// Analysis and Instrumentation Library (libabigail). This library is +// free software; you can redistribute it and/or modify it under the +// terms of the GNU Lesser General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) any +// later version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this program; see the file COPYING-LGPLV3. If +// not, see . +// +// Author: Matthias Maennich + +/// @file +/// +/// This program tests libabigail's symtab reader. + +#include "lib/catch.hpp" + +#include "abg-symtab-reader.h" + From patchwork Fri Jul 3 16:46:36 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: 39889 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 EE8CF3844079; Fri, 3 Jul 2020 16:47:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EE8CF3844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794873; bh=qoDUt3S3vIZHdXWTdiOdry3Be/R+OSOKzyDmvtlQI8M=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=NbrpYQ6FXDf/glv7Vot/nIsHhomfwnMlEWlMP2AevxWJorATiSJKDEWUcIn9JmjpG WSB4p46Lq4DMdJzh0qwg9cy9RpDcYyi5iuE9S9Hi1P/ni59scO+J2fo6VQoZpuXTVT foBKbizFkK4uvGTLqFeRQBvb437gL2GY43TYFs/M= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wm1-x349.google.com (mail-wm1-x349.google.com [IPv6:2a00:1450:4864:20::349]) by sourceware.org (Postfix) with ESMTPS id E9C7C3844079 for ; Fri, 3 Jul 2020 16:47:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E9C7C3844079 Received: by mail-wm1-x349.google.com with SMTP id v11so16950325wmb.1 for ; Fri, 03 Jul 2020 09:47:48 -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=qoDUt3S3vIZHdXWTdiOdry3Be/R+OSOKzyDmvtlQI8M=; b=b8MQz9RzkYPc5dVFGJte0MTBtkHobRrsj6EYN0i2gp0fflNJwwlXlDdb5GlThYhLMa au0tRJNDueLIbRaFJ7U7PENzoESq3aKyS7UTMjSwzXYskXBUPJnPV3St6lIQRBEjm8wF oMA9Z7u2WSjDK7MSozABtCU+krRvLS3Cr+hUY8O0dXWezSkLi3wbBgvCZ3SpWXm7bdaE JNLqyEXTdn/1ElcatgmozAuR7K4PaJ7xcHjD7Up+NIUYOW7t6Zx8IbbwTU7o8EgFVPSk iflFlmechyiqxbZtAkYI96LaTIsUpzpg51beqmr04+h6xbTn7WPronausjUyQXCq5Hw7 dWhA== X-Gm-Message-State: AOAM531bFRinZTg0kCXXNMYraqLBZKdD8atfCZrid2W1gJZqkXIUVQ3K SFyo9GUr8ZQpeS+6BMuS76ALh97UWLVn8FIBujPBnAV3Tui18BAgjEQFHPX9CnM2GEkvLYHVAYB alRwcuzBlpSfXAkKj7jVtS5uwvd8ruqFy33mSsQzaZWPETTQJNEifrcbhmH8PqexbzyPVao8= X-Google-Smtp-Source: ABdhPJw3b0PBtVAfW+TIlGWYj/k4Rqg1wuunj1LKbU49Wzt8ShLFsDGZayPwOxuPgas7JMgOD7EL7qWghVsn+g== X-Received: by 2002:a1c:7306:: with SMTP id d6mr28322542wmb.113.1593794867984; Fri, 03 Jul 2020 09:47:47 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:36 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-7-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 06/21] Refactor ELF symbol table reading by adding a new symtab reader To: libabigail@sourceware.org X-Spam-Status: No, score=-23.4 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Based on existing functionality, implement the reading of ELF symbol tables as a separate component. This reduces the complexity of abg-dwarf-reader's read_context by separating and delegating the functionality. This also allows dedicated testing. The new namespace symtab_reader contains a couple of new components that work loosely coupled together. Together they allow for a consistent view on a symbol table. With filter criteria those views can be restricted, iterated and consistent lookup maps can be built on top of them. While this implementation tries to address some shortcomings of the previous model, it still provides the high level interfaces to the symbol table contents through sorted iterating and name/address mapped access. symtab_reader::symtab While the other classes in the same namespace are merely helpers, this is the main implementation of symtab reading and storage. Symtab objects are factory created to ensure a consistent construction and valid invariants. Thus a symtab will be loaded by either passing an ELF handle (when reading from binary) or by passing a set of function/variable symbol maps (when reading from XML). When constructed they are considered const and are not writable anymore. As such, all public methods are const. The load reuses the existing implementation for loading symtab sections, but since the new implementation does not distinguish between functions and variables, the code could be simplified. The support for ppc64 function entry addresses has been deferred to a later commit. Linux Kernel symbol tables are now directly loaded by name when encountering symbols prefixed with the __ksymtab_ as per convention. This has been tricky in the past due to various different binary layouts (relocations, position relative relocations, symbol namespaces, CFI indirections, differences between vmlinux and kernel modules). Thus the new implementation is much simpler and is less vulnerable to future ksymtab changes. As we are also not looking up the Kernel symbols by addresses, we could resolve shortcomings with symbol aliasing: Previously a symbol and its alias were indistinguishable as they are having the same symbol address. We could not identify the one that is actually exported via ksymtab. One major architectural difference of this implementation is that we do not early discard suppressed symbols. While we keep them out of the vector of exported symbols, we still make them available for lookup. That helps addressing issues when looking up a symbol by address (e.g. from the ksymtab read implementation) that is suppressed. That would fail in the existing implementation. Still, we intend to only instantiate each symbol once and pass around shared_ptr instances to refer to it from the vector as well as from the lookup maps. For reading, there are two access paths that serve the existing patterns: 1) lookup_symbol: either via a name or an address 2) filtered iteration with begin(), end() The former is used for direct access with a clue in hand (like a name or an address), the latter is used for iteration (e.g. when emitting the XML). symtab_reader::symtab_iterator The symtab_iterator is an STL compatible iterator that is returned from begin() and end() of the symtab. It allows usual forward iterator operations and can optionally take a filter predicate to skip non matching elements. symtab_reader::symtab_filter The symtab_filter serves as a predicate for the symtab_iterator by providing a matches(const elf_symbol_sptr&) function. The predicate is built by ANDing together several conditions on attributes a symbol can have. The filter conditions are implemented in terms of std::optional members to allow a tristate: "needs to have the condition set", "must not have it set" and "don't care". symtab_reader::symtab_filter_builder This is a convenient way of building filters with a builder pattern and a fluent interface. Hence, filters can be expressed neatly, expressive and precise. When instantiated, via symtab::make_filter(), the filter_builder is preset with suitable defaults. The filter_builder is convertable to a symtab_filter by passing on the local filter copy and therefore serving the fluent interface. symtab_reader::filtered_symtab The filtered_symtab is a convenience zero cost abstraction that allows prepopulating the symtab_filter (call it a capture) such that begin() and end() are now accessible without the need to pass the filter again. Argumentless begin() and end() are a requirement for range-for loops and other STL based algorithms. * include/abg-symtab-reader.h (symtab_filter): New class. (symtab_filter_builder): Likewise. (symtab_iterator): Likewise. (symtab): Likewise. (filtered_symtab): Likewise. * src/abg-symtab-reader.cc (symtab_filter::matches): New. (symtab::make_filter): Likewise. (symtab::lookup_symbol): Likewise. (symbol_sort): Likewise. (symtab::load): Likewise. (symtab::load_): Likewise. * tests/test-symtab-reader.cc (default filter matches anything): New test case. (default filter built with filter_builder matches anything): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-symtab-reader.h | 371 +++++++++++++++++++++++++++++++++++- src/abg-symtab-reader.cc | 313 ++++++++++++++++++++++++++++++ tests/test-symtab-reader.cc | 23 +++ 3 files changed, 706 insertions(+), 1 deletion(-) diff --git a/include/abg-symtab-reader.h b/include/abg-symtab-reader.h index b61e6399fe93..86335617d46a 100644 --- a/include/abg-symtab-reader.h +++ b/include/abg-symtab-reader.h @@ -27,12 +27,381 @@ #ifndef __ABG_SYMTAB_READER_H__ #define __ABG_SYMTAB_READER_H__ +#include + +#include +#include + +#include "abg-cxx-compat.h" +#include "abg-ir.h" + namespace abigail { - namespace symtab_reader { +class symtab_filter_builder; + +/// The symtab filter is the object passed to the symtab object in order to +/// iterate over the symbols in the symtab while applying filters. +/// +/// The general idea is that it consists of a set of optionally enforced flags, +/// such as 'functions' or 'variables'. If not set, those are not filtered for, +/// neither inclusive nor exclusive. If set they are all ANDed together. +class symtab_filter +{ +public: + // The symtab_filter_builder helps us to build filters efficiently, hence + // let's be nice and grant access to our internals. + friend class symtab_filter_builder; + + // Default constructor disabling all features. + symtab_filter() {} + + /// Determine whether a symbol is matching the filter criteria of this filter + /// object. In terms of a filter functionality, you would _not_ filter out + /// this symbol if it passes this (i.e. returns true). + /// + /// @param symbol The Elf symbol under test. + /// + /// @return whether the symbol matches all relevant / required criteria + bool + matches(const elf_symbol_sptr& symbol) const; + +private: + // The symbol is a function (FUNC) + abg_compat::optional functions_; + + // The symbol is a variables (OBJECT) + abg_compat::optional variables_; + + // The symbol is publicly accessible (global/weak with default/protected + // visibility) + abg_compat::optional public_symbols_; + + // The symbols is not defined (declared) + abg_compat::optional undefined_symbols_; + + // The symbol is listed in the ksymtab (for Linux Kernel binaries). + abg_compat::optional kernel_symbols_; +}; + +/// Helper class to provide an attractive interface to build symtab_filters. +/// +/// When constructed, the helper instantiates a default symtab_filter and +/// allows modifications to it via builder pattern / fluent interface. +/// +/// When assigned to a symtab_filter instance, it converts by returning the +/// locally build symtab_filter instance. +/// +/// Example usage: +/// +/// const symtab_filter filter = +/// symtab_filter_builder().functions().kernel_symbols(); +/// +/// In that case we would filter for the conjunction of function symbols that +/// also appear in the ksymtab (i.e. kernel symbols). +class symtab_filter_builder +{ +public: + /// Enable inclusive / exclusive filtering for functions. + symtab_filter_builder& + functions(bool value = true) + { filter_.functions_ = value; return *this; } + + /// Enable inclusive / exclusive filtering for variables. + symtab_filter_builder& + variables(bool value = true) + { filter_.variables_ = value; return *this; } + + /// Enable inclusive / exclusive filtering for public symbols. + symtab_filter_builder& + public_symbols(bool value = true) + { filter_.public_symbols_ = value; return *this; } + + /// Enable inclusive / exclusive filtering for undefined symbols. + symtab_filter_builder& + undefined_symbols(bool value = true) + { filter_.undefined_symbols_ = value; return *this; } + + /// Enable inclusive / exclusive filtering for kernel symbols. + symtab_filter_builder& + kernel_symbols(bool value = true) + { filter_.kernel_symbols_ = value; return *this; } + + /// Convert seamlessly to a symtab_filter instance. + /// + /// We could possibly validate the filter constellations here. For now, we + /// just return the local filter instance. + operator symtab_filter() { return filter_; } + +private: + /// Local symtab_filter instance that we build and eventually pass on. + symtab_filter filter_; +}; + +/// Base iterator for our custom iterator based on whatever the const_iterator +/// is for a vector of symbols. +/// As of writing this, std::vector::const_iterator. +typedef elf_symbols::const_iterator base_iterator; + +/// An iterator to walk a vector of elf_symbols filtered by symtab_filter. +/// +/// The implementation inherits all properties from the vector's +/// const_iterator, but intercepts where necessary to allow effective +/// filtering. This makes it a STL compatible iterator for general purpose +/// usage. +class symtab_iterator : public base_iterator +{ +public: + typedef base_iterator::value_type value_type; + typedef base_iterator::reference reference; + typedef base_iterator::pointer pointer; + typedef base_iterator::difference_type difference_type; + typedef std::forward_iterator_tag iterator_category; + + /// Construct the iterator based on a pair of underlying iterators and a + /// symtab_filter object. Immediately fast forward to the next element that + /// matches the criteria (if any). + symtab_iterator(base_iterator begin, + base_iterator end, + const symtab_filter& filter = symtab_filter()) + : base_iterator(begin), end_(end), filter_(filter) + { skip_to_next(); } + + /// Pre-increment operator to advance to the next matching element. + symtab_iterator& + operator++() + { + base_iterator::operator++(); + skip_to_next(); + return *this; + } + + /// Post-increment operator to advance to the next matching element. + symtab_iterator + operator++(int) + { + symtab_iterator result(*this); + ++(*this); + return result; + } + +private: + /// The end of the underlying iterator. + const base_iterator end_; + + /// The symtab_filter used to determine when to advance. + const symtab_filter& filter_; + + /// Skip to the next element that matches the filter criteria (if any). Hold + /// off when reaching the end of the underlying iterator. + void + skip_to_next() + { + while (*this != end_ && !filter_.matches(**this)) + ++(*this); + } +}; + +/// Convenience declaration of a shared_ptr +class symtab; +typedef abg_compat::shared_ptr symtab_sptr; + +/// symtab is the actual data container of the symtab_reader implementation. +/// +/// The symtab is instantiated either via an Elf handle (from binary) or from a +/// set of existing symbol maps (usually when instantiated from XML). It will +/// then discover the symtab, possibly the ksymtab (for Linux Kernel binaries) +/// and setup the data containers and lookup maps for later perusal. +/// +/// The symtab is supposed to be used in a const context as all information is +/// already computed at construction time. Symbols are stored sorted to allow +/// deterministic reading of the entries. +/// +/// An example use of the symtab class is +/// +/// const symtab_sptr tab = symtab::load(elf_handle, env); +/// const symtab_filter filter = tab->make_filter() +/// .public_symbols() +/// .functions(); +/// +/// for (symtab::const_iterator I = tab.begin(filter), E = tab.end(); +/// I != E; ++I) +/// { +/// std::cout << (*I)->get_name() << "\n"; +/// } +/// +/// C++11 and later allows a more brief syntax for the same: +/// +/// for (const auto& symbol : filtered_symtab(*tab, filter)) +/// { +/// std::cout << symbol->get_name() << "\n"; +/// } +/// +/// This uses the filtered_symtab proxy object to capture the filter. +class symtab +{ +public: + typedef abg_compat::function symbol_predicate; + + /// Indicate whether any (kernel) symbols have been seen at construction. + /// + /// @return true if there are symbols detected earlier. + bool + has_symbols() const + { return is_kernel_binary_ ? has_ksymtab_entries_ : !symbols_.empty(); } + + /// Obtain a suitable default filter for iterating this symtab object. + /// + /// The symtab_filter_build obtained is populated with some sensible default + /// settings, such as public_symbols(true) and kernel_symbols(true) if the + /// binary has been identified as Linux Kernel binary. + /// + /// @return a symtab_filter_builder with sensible populated defaults + symtab_filter_builder + make_filter() const; + + /// The (only) iterator type we offer is a const_iterator implemented by the + /// symtab_iterator. + typedef symtab_iterator const_iterator; + + /// Obtain an iterator to the beginning of the symtab according to the filter + /// criteria. Whenever this iterator advances, it skips elements that do not + /// match the filter criteria. + /// + /// @param filter the symtab_filter to match symbols against + /// + /// @return a filtering const_iterator of the underlying type + const_iterator + begin(const symtab_filter& filter) const + { return symtab_iterator(symbols_.begin(), symbols_.end(), filter); } + + /// Obtain an iterator to the end of the symtab. + /// + /// @return an end iterator + const_iterator + end() const + { return symtab_iterator(symbols_.end(), symbols_.end()); } + + /// Get a vector of symbols that are associated with a certain name + /// + /// @param name the name the symbols need to match + /// + /// @return a vector of symbols, empty if no matching symbols have been found + const elf_symbols& + lookup_symbol(const std::string& name) const; + + /// Lookup a symbol by its address + /// + /// @param symbol_addr the starting address of the symbol + /// + /// @return a symbol if found, else an empty sptr + const elf_symbol_sptr& + lookup_symbol(GElf_Addr symbol_addr) const; + + /// Construct a symtab object and instantiate from an ELF handle. Also pass + /// in an ir::environment handle to interact with the context we are living + /// in. If specified, the symbol_predicate will be respected when creating + /// the full vector of symbols. + static symtab_sptr + load(Elf* elf_handle, + ir::environment* env, + symbol_predicate is_suppressed = NULL); + + /// Construct a symtab object from existing name->symbol lookup maps. + /// They were possibly read from a different representation (XML maybe). + static symtab_sptr + load(string_elf_symbols_map_sptr function_symbol_map, + string_elf_symbols_map_sptr variables_symbol_map); + +private: + /// Default constructor. Private to enforce creation by factory methods. + symtab(); + + /// The vector of symbols we discovered. + elf_symbols symbols_; + + /// Whether this is a Linux Kernel binary + bool is_kernel_binary_; + + /// Whether this kernel_binary has ksymtab entries + /// + /// A kernel module might not have a ksymtab if it does not export any + /// symbols. In order to quickly decide whether the symbol table is empty, we + /// remember whether we ever saw ksymtab entries. + bool has_ksymtab_entries_; + + /// Lookup map name->symbol(s) + typedef abg_compat::unordered_map > + name_symbol_map_type; + name_symbol_map_type name_symbol_map_; + + /// Lookup map name->symbol + typedef abg_compat::unordered_map + addr_symbol_map_type; + addr_symbol_map_type addr_symbol_map_; + + /// Load the symtab representation from an Elf binary presented to us by an + /// Elf* handle. + /// + /// This method iterates over the entries of .symtab and collects all + /// interesting symbols (functions and variables). + /// + /// In case of a Linux Kernel binary, it also collects information about the + /// symbols exported via EXPORT_SYMBOL in the Kernel that would then end up + /// having a corresponding __ksymtab entry. + /// + /// Symbols that are suppressed will be omitted from the symbols_ vector, but + /// still be discoverable through the name->symbol and addr->symbol lookup + /// maps. + bool + load_(Elf* elf_handle, ir::environment* env, symbol_predicate is_suppressed); + + /// Load the symtab representation from a function/variable lookup map pair. + /// + /// This method assumes the lookup maps are correct and sets up the data + /// vector as well as the name->symbol lookup map. The addr->symbol lookup + /// map cannot be set up in this case. + bool + load_(string_elf_symbols_map_sptr function_symbol_map, + string_elf_symbols_map_sptr variables_symbol_map); +}; + +/// Helper class to allow range-for loops on symtabs for C++11 and later code. +/// It serves as a proxy for the symtab iterator and provides a begin() method +/// without arguments, as required for range-for loops (and possibly other +/// iterator based transformations). +/// +/// Example usage: +/// +/// for (const auto& symbol : filtered_symtab(tab, filter)) +/// { +/// std::cout << symbol->get_name() << "\n"; +/// } +/// +class filtered_symtab +{ + const symtab& tab_; + const symtab_filter filter_; + +public: + /// Construct the proxy object keeping references to the underlying symtab + /// and the filter object. + filtered_symtab(const symtab& tab, const symtab_filter& filter) + : tab_(tab), filter_(filter) { } + + /// Pass through symtab.begin(), but also pass on the filter. + symtab::const_iterator + begin() const + { return tab_.begin(filter_); } + + /// Pass through symtab.end(). + symtab::const_iterator + end() const + { return tab_.end(); } +}; + } // end namespace symtab_reader } // end namespace abigail diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc index 1f934d3a7609..c98b9174490c 100644 --- a/src/abg-symtab-reader.cc +++ b/src/abg-symtab-reader.cc @@ -1,5 +1,6 @@ // -*- Mode: C++ -*- // +// Copyright (C) 2013-2020 Red Hat, Inc. // Copyright (C) 2020 Google, Inc. // // This file is part of the GNU Application Binary Interface Generic @@ -24,7 +25,18 @@ /// /// This contains the definition of the symtab reader +#include +#include + +#include "abg-cxx-compat.h" +#include "abg-elf-helpers.h" +#include "abg-fwd.h" +#include "abg-internal.h" +#include "abg-tools-utils.h" + +ABG_BEGIN_EXPORT_DECLARATIONS #include "abg-symtab-reader.h" +ABG_END_EXPORT_DECLARATIONS namespace abigail { @@ -32,5 +44,306 @@ namespace abigail namespace symtab_reader { +/// symtab_filter implementations + +bool +symtab_filter::matches(const elf_symbol_sptr& symbol) const +{ + if (functions_ && *functions_ != symbol->is_function()) + return false; + if (variables_ && *variables_ != symbol->is_variable()) + return false; + if (public_symbols_ && *public_symbols_ != symbol->is_public()) + return false; + if (undefined_symbols_ && *undefined_symbols_ == symbol->is_defined()) + return false; + if (kernel_symbols_ && *kernel_symbols_ != symbol->is_in_ksymtab()) + return false; + + return true; +} + +/// symtab implementations + +symtab_filter_builder +symtab::make_filter() const +{ + symtab_filter_builder builder; + builder.public_symbols(); + if (is_kernel_binary_) + builder.kernel_symbols(); + return builder; +} + +const elf_symbols& +symtab::lookup_symbol(const std::string& name) const +{ + static const elf_symbols empty_result; + const name_symbol_map_type::const_iterator it = name_symbol_map_.find(name); + if (it != name_symbol_map_.end()) + { + return it->second; + } + return empty_result; +} + +const elf_symbol_sptr& +symtab::lookup_symbol(GElf_Addr symbol_addr) const +{ + static const elf_symbol_sptr empty_result; + const addr_symbol_map_type::const_iterator it = + addr_symbol_map_.find(symbol_addr); + if (it != addr_symbol_map_.end()) + { + return it->second; + } + return empty_result; +} + +/// A symbol sorting functor. +static struct +{ + bool + operator()(const elf_symbol_sptr& left, const elf_symbol_sptr& right) + { return left->get_id_string() < right->get_id_string(); } +} symbol_sort; + +symtab_sptr +symtab::load(Elf* elf_handle, + ir::environment* env, + symbol_predicate is_suppressed) +{ + ABG_ASSERT(elf_handle); + ABG_ASSERT(env); + + symtab_sptr result(new symtab); + if (!result->load_(elf_handle, env, is_suppressed)) + return symtab_sptr(); + + return result; +} + +symtab_sptr +symtab::load(string_elf_symbols_map_sptr function_symbol_map, + string_elf_symbols_map_sptr variables_symbol_map) +{ + symtab_sptr result(new symtab); + if (!result->load_(function_symbol_map, variables_symbol_map)) + return symtab_sptr(); + + return result; +} + +symtab::symtab() : is_kernel_binary_(false), has_ksymtab_entries_(false) {} + +bool +symtab::load_(Elf* elf_handle, + ir::environment* env, + symbol_predicate is_suppressed) +{ + + Elf_Scn* symtab_section = elf_helpers::find_symbol_table_section(elf_handle); + if (!symtab_section) + { + std::cerr << "No symbol table found: Skipping symtab load.\n"; + return false; + } + + GElf_Shdr symtab_sheader; + gelf_getshdr(symtab_section, &symtab_sheader); + + // check for bogus section header + if (symtab_sheader.sh_entsize == 0) + { + std::cerr << "Invalid symtab header found: Skipping symtab load.\n"; + return false; + } + + const size_t number_syms = + symtab_sheader.sh_size / symtab_sheader.sh_entsize; + + Elf_Data* symtab = elf_getdata(symtab_section, 0); + if (!symtab) + { + std::cerr << "Could not load elf symtab: Skipping symtab load.\n"; + return false; + } + + const bool is_kernel = elf_helpers::is_linux_kernel(elf_handle); + abg_compat::unordered_set exported_kernel_symbols; + + for (size_t i = 0; i < number_syms; ++i) + { + GElf_Sym *sym, sym_mem; + sym = gelf_getsym(symtab, i, &sym_mem); + if (!sym) + { + std::cerr << "Could not load symbol with index " << i + << ": Skipping symtab load.\n"; + return false; + } + + const char* name_str = + elf_strptr(elf_handle, symtab_sheader.sh_link, sym->st_name); + + // no name, no game + if (!name_str) + continue; + + // Handle ksymtab entries. Every symbol entry that starts with __ksymtab_ + // indicates that the symbol in question is exported through ksymtab. We + // do not know whether this is ksymtab_gpl or ksymtab, but that is good + // enough for now. + // + // We could follow up with this entry: + // + // symbol_value -> ksymtab_entry in either ksymtab_gpl or ksymtab + // -> addr/name/namespace (in case of PREL32: offset) + // + // That way we could also detect ksymtab<>ksymtab_gpl changes or changes + // of the symbol namespace. + // + // As of now this lookup is fragile, as occasionally ksymtabs are empty + // (seen so far for kernel modules and LTO builds). Hence we stick to the + // fairly safe assumption that ksymtab exported entries are having an + // appearence as __ksymtab_ in the symtab. + const std::string name = name_str; + if (is_kernel && name.rfind("__ksymtab_", 0) == 0) + { + ABG_ASSERT(exported_kernel_symbols.insert(name.substr(10)).second); + continue; + } + + // filter out uninteresting entries and only keep functions/variables for + // now. The rest might be interesting in the future though. + const int sym_type = GELF_ST_TYPE(sym->st_info); + if (!(sym_type == STT_FUNC + || sym_type == STT_GNU_IFUNC + // If the symbol is for an OBJECT, the index of the + // section it refers to cannot be absolute. + // Otherwise that OBJECT is not a variable. + || (sym_type == STT_OBJECT && sym->st_shndx != SHN_ABS) + || sym_type == STT_TLS)) + continue; + + const bool sym_is_defined = sym->st_shndx != SHN_UNDEF; + // this occurs in relocatable files. + const bool sym_is_common = sym->st_shndx == SHN_COMMON; + + elf_symbol::version ver; + elf_helpers::get_version_for_symbol(elf_handle, i, sym_is_defined, ver); + + const elf_symbol_sptr& symbol_sptr = elf_symbol::create( + env, i, sym->st_size, name, + elf_helpers::stt_to_elf_symbol_type(GELF_ST_TYPE(sym->st_info)), + elf_helpers::stb_to_elf_symbol_binding(GELF_ST_BIND(sym->st_info)), + sym_is_defined, sym_is_common, ver, + elf_helpers::stv_to_elf_symbol_visibility( + GELF_ST_VISIBILITY(sym->st_other)), + false); // TODO: is_linux_strings_cstr + + // We do not take suppressed symbols into our symbol vector to avoid + // accidental leakage. But we ensure supressed symbols are otherwise set + // up for lookup. + if (!(is_suppressed && is_suppressed(symbol_sptr))) + // add to the symbol vector + symbols_.push_back(symbol_sptr); + else + symbol_sptr->set_is_suppressed(true); + + // add to the name->symbol lookup + name_symbol_map_[name].push_back(symbol_sptr); + + // add to the addr->symbol lookup + if (symbol_sptr->is_common_symbol()) + { + const name_symbol_map_type::iterator it = + name_symbol_map_.find(name); + ABG_ASSERT(it != name_symbol_map_.end()); + const elf_symbols& common_sym_instances = it->second; + ABG_ASSERT(!common_sym_instances.empty()); + if (common_sym_instances.size() > 1) + { + elf_symbol_sptr main_common_sym = common_sym_instances[0]; + ABG_ASSERT(main_common_sym->get_name() == name); + ABG_ASSERT(main_common_sym->is_common_symbol()); + ABG_ASSERT(symbol_sptr.get() != main_common_sym.get()); + main_common_sym->add_common_instance(symbol_sptr); + } + } + else if (symbol_sptr->is_defined()) + { + const GElf_Addr symbol_value = + elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle, + sym); + + const std::pair result = + addr_symbol_map_.insert( + std::make_pair(symbol_value, symbol_sptr)); + if (!result.second) + result.first->second->get_main_symbol()->add_alias(symbol_sptr); + } + } + + is_kernel_binary_ = elf_helpers::is_linux_kernel(elf_handle); + + // Now apply the ksymtab_exported attribute to the symbols we collected. + for (abg_compat::unordered_set::const_iterator + it = exported_kernel_symbols.begin(), + en = exported_kernel_symbols.end(); + it != en; ++it) + { + const name_symbol_map_type::const_iterator r = + name_symbol_map_.find(*it); + 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) + { + if ((*sym_it)->is_public()) + (*sym_it)->set_is_in_ksymtab(true); + } + has_ksymtab_entries_ = true; + } + + // sort the symbols for deterministic output + std::sort(symbols_.begin(), symbols_.end(), symbol_sort); + + return true; +} + +bool +symtab::load_(string_elf_symbols_map_sptr function_symbol_map, + string_elf_symbols_map_sptr variables_symbol_map) + +{ + if (function_symbol_map) + for (string_elf_symbols_map_type::const_iterator + it = function_symbol_map->begin(), + end = function_symbol_map->end(); + it != end; ++it) + { + symbols_.insert(symbols_.end(), it->second.begin(), it->second.end()); + ABG_ASSERT(name_symbol_map_.insert(*it).second); + } + + if (variables_symbol_map) + for (string_elf_symbols_map_type::const_iterator + it = variables_symbol_map->begin(), + end = variables_symbol_map->end(); + it != end; ++it) + { + symbols_.insert(symbols_.end(), it->second.begin(), it->second.end()); + ABG_ASSERT(name_symbol_map_.insert(*it).second); + } + + // sort the symbols for deterministic output + std::sort(symbols_.begin(), symbols_.end(), symbol_sort); + + return true; +} + } // end namespace symtab_reader } // end namespace abigail diff --git a/tests/test-symtab-reader.cc b/tests/test-symtab-reader.cc index c2e30d661017..383166c88875 100644 --- a/tests/test-symtab-reader.cc +++ b/tests/test-symtab-reader.cc @@ -28,3 +28,26 @@ #include "abg-symtab-reader.h" +namespace abigail +{ + +using symtab_reader::symtab_filter; +using symtab_reader::symtab_filter_builder; + +TEST_CASE("default symtab_filter matches anything", + "[symtab_reader, symtab_filter]") +{ + const symtab_filter filter; + const elf_symbol_sptr symbol; // not initialized! + CHECK(filter.matches(symbol)); +} + +TEST_CASE("default symtab_filter built with filter_builder matches anything", + "[symtab_reader, symtab_filter, symtab_filter_builder]") +{ + const symtab_filter filter = symtab_filter_builder(); + const elf_symbol_sptr symbol; // not initialized! + CHECK(filter.matches(symbol)); +} + +} // namespace abigail From patchwork Fri Jul 3 16:46:37 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: 39890 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 7745E384403B; Fri, 3 Jul 2020 16:47:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7745E384403B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794875; bh=U8ZzVKAzuHA6MRPOLfahUBWYf8Xo5g3urcVksFrxGas=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=mnswW7cA662jgWXUfBwmjEb3PsyoRzrMEOHGiMBEfR8N+gV918TKZNDKZQIESn6FF VsshuNbFwMlSTApkGCpDiENP+tY5J55bf1lxqweVQaLm1TdUwz+86I9VLyBduQ/Mr4 lNkSHK/FOkFty7dLQxHGXGbCzt2xgJBts20HsEE8= 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 B5FC1384402F for ; Fri, 3 Jul 2020 16:47:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B5FC1384402F Received: by mail-wr1-x449.google.com with SMTP id b8so18190256wro.19 for ; Fri, 03 Jul 2020 09:47:51 -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=U8ZzVKAzuHA6MRPOLfahUBWYf8Xo5g3urcVksFrxGas=; b=qBPJ+jrtm8mhuLBj6KqxOW7jkLi0GJzW+pf0NKu/ZxWzK1f4G6uiqCy2itnYd0FarQ Kl8cLaj5vXzikIFNXqHvyOKPkp+88u3ZqTIjiMuHnM97zh5CaJeiMT+97Dv2XbnTXv2Y yGeJDapG1hKMnif3N5qcUxYXzqHTiRIkusZaTY7sdX+7mT+tS/YPffDEjWzxMOjaz5bC NxxJFSrMicoqZ3DAwKifM+2/7ZYjpw5CpERyZwSnIhIBL7r8WHl6Wsq7RSJQWCICDgAp NmYc4Bh3/MzuYCirkE/OOwWu5MesP2+0RftO4bABYJidwZHxKmcVqQEW5Zh1ykq1zkzy /KVw== X-Gm-Message-State: AOAM531vp20l/qX4peT6BJ76C5VSEfQtz/UTRlObA3wiWHLOV8dByB0R XqOWJjlRLGTqQA9BJ1xi6WB/gzauXM2Rf2L1Upb1KRSS8rJ4vwwPtx2T6SDlV6/cVZV8DTCU2Ws NIee5JjYnPlNcLj4Rqv7slVV/QvW8pYj4ax1dF4Dqlrg6BiydWUNCxWWu843NaUxv1VWQUr4= X-Google-Smtp-Source: ABdhPJzYSHUs3DAopv2hZvKkw3gNMQe+y5YmnKdBnaZCLnZDJVsy89mS10hriJiPx04iGDN0RC9pE6kIPY70Fg== X-Received: by 2002:a7b:c1d8:: with SMTP id a24mr2314101wmj.0.1593794870008; Fri, 03 Jul 2020 09:47:50 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:37 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-8-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 07/21] Integrate new symtab reader into corpus and read_context To: libabigail@sourceware.org X-Spam-Status: No, score=-23.5 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" While reading the corpus in the read_context, also load the new type symtab object side-by-side and set it accordingly in the resulting corpus. This is still side by side and passive code that gets active in the following changes. This is applicable for the dwarf reader as well as for the reader that consumes XML. * include/abg-corpus.h (corpus::set_symtab): New method declaration. (corpus::get_symtab): New method declaration. * include/abg-fwd.h (symtab_reader::symtab_sptr): New forward declaration. * src/abg-corpus-priv.h (corpus::priv::symtab_): New data member. * src/abg-corpus.cc (corpus::set_symtab): Likewise. (corpus::get_symtab): Likewise. * src/abg-dwarf-reader.cc (read_context::symtab_): New data member. (read_context::initialize): reset symtab_ as well (read_context::symtab): new method that loads a symtab on first access and returns it. (read_debug_info_into_corpus): also set the new symtab object on the current corpus. (read_corpus_from_elf): Also determine (i.e. load) the new symtab object and contribute to the load status. * src/abg-reader.cc (read_corpus_from_input): also set the new type symtab when reading from xml. * tests/test-symtab.cc: Add test assertions. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-corpus.h | 6 ++++ include/abg-fwd.h | 8 ++++++ src/abg-corpus-priv.h | 2 ++ src/abg-corpus.cc | 9 ++++++ src/abg-dwarf-reader.cc | 27 ++++++++++++++++++ src/abg-reader.cc | 3 ++ tests/data/test-symtab/basic/no_debug_info.c | 2 +- tests/data/test-symtab/basic/no_debug_info.so | Bin 15360 -> 15544 bytes tests/test-symtab.cc | 15 ++++------ 9 files changed, 61 insertions(+), 11 deletions(-) diff --git a/include/abg-corpus.h b/include/abg-corpus.h index 410a9c2459e6..b94926996cde 100644 --- a/include/abg-corpus.h +++ b/include/abg-corpus.h @@ -169,6 +169,12 @@ public: bool operator==(const corpus&) const; + void + set_symtab(symtab_reader::symtab_sptr); + + const symtab_reader::symtab_sptr& + get_symtab() const; + void set_fun_symbol_map(string_elf_symbols_map_sptr); diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 999b071b5664..07ab0b9f163e 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -1331,6 +1331,14 @@ typedef vector suppressions_type; } // end namespace suppr +namespace symtab_reader +{ + +class symtab; +typedef abg_compat::shared_ptr symtab_sptr; + +} // end namespace symtab_reader + void dump(const decl_base_sptr, std::ostream&); diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h index ee8c823964e7..5c1e915ad2f3 100644 --- a/src/abg-corpus-priv.h +++ b/src/abg-corpus-priv.h @@ -32,6 +32,7 @@ #include "abg-internal.h" #include "abg-regex.h" #include "abg-sptr-utils.h" +#include "abg-symtab-reader.h" namespace abigail { @@ -700,6 +701,7 @@ struct corpus::priv string_elf_symbols_map_sptr undefined_var_symbol_map; elf_symbols sorted_var_symbols; elf_symbols sorted_undefined_var_symbols; + symtab_reader::symtab_sptr symtab_; string_elf_symbols_map_sptr fun_symbol_map; string_elf_symbols_map_sptr undefined_fun_symbol_map; elf_symbols sorted_fun_symbols; diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc index 9e90b99473d3..94702047dd82 100644 --- a/src/abg-corpus.cc +++ b/src/abg-corpus.cc @@ -38,6 +38,7 @@ ABG_BEGIN_EXPORT_DECLARATIONS #include "abg-ir.h" #include "abg-reader.h" #include "abg-sptr-utils.h" +#include "abg-symtab-reader.h" #include "abg-tools-utils.h" #include "abg-writer.h" @@ -905,6 +906,14 @@ corpus::operator==(const corpus& other) const && j == other.get_translation_units().end()); } +void +corpus::set_symtab(symtab_reader::symtab_sptr symtab) +{priv_->symtab_ = symtab;} + +const symtab_reader::symtab_sptr& +corpus::get_symtab() const +{ return priv_->symtab_; } + /// Setter of the function symbols map. /// /// @param map a shared pointer to the new function symbols map. diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index cf789d09a8be..d9c1c03d273f 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -50,6 +50,7 @@ #include "abg-suppression-priv.h" #include "abg-corpus-priv.h" #include "abg-elf-helpers.h" + #include "abg-internal.h" // @@ -57,6 +58,7 @@ ABG_BEGIN_EXPORT_DECLARATIONS #include "abg-dwarf-reader.h" #include "abg-sptr-utils.h" +#include "abg-symtab-reader.h" #include "abg-tools-utils.h" ABG_END_EXPORT_DECLARATIONS @@ -2277,6 +2279,9 @@ public: bool drop_undefined_syms_; read_context(); +private: + mutable symtab_reader::symtab_sptr symtab_; + public: /// Constructor of read_context. @@ -2426,6 +2431,8 @@ public: dt_soname_.clear(); elf_architecture_.clear(); + symtab_.reset(); + clear_per_translation_unit_data(); memset(&offline_callbacks_, 0, sizeof(offline_callbacks_)); @@ -5577,6 +5584,22 @@ public: return symbol; } + const symtab_reader::symtab_sptr& + symtab() const + { + using namespace abg_compat::placeholders; + if (!symtab_) + symtab_ = symtab_reader::symtab::load( + elf_handle(), options_.env, + abg_compat::bind(&read_context::is_elf_symbol_suppressed, this, _1)); + if (!symtab_) + { + std::cerr << "Symbol table of '" << elf_path_ + << "' could not be loaded\n"; + } + return symtab_; + } + /// Getter for a pointer to the map that associates the address of /// an entry point of a function with the symbol of that function. /// @@ -15481,6 +15504,7 @@ read_debug_info_into_corpus(read_context& ctxt) group->add_corpus(ctxt.current_corpus()); // Set symbols information to the corpus. + ctxt.current_corpus()->set_symtab(ctxt.symtab()); if (!get_ignore_symbol_table(ctxt)) { if (ctxt.load_in_linux_kernel_mode() @@ -16737,6 +16761,9 @@ read_corpus_from_elf(read_context& ctxt, status& status) status |= STATUS_NO_SYMBOLS_FOUND; } + if (!ctxt.symtab() || !ctxt.symtab()->has_symbols()) + status |= STATUS_NO_SYMBOLS_FOUND; + if (// If no elf symbol was found ... status & STATUS_NO_SYMBOLS_FOUND // ... or if debug info was found but not the required alternate diff --git a/src/abg-reader.cc b/src/abg-reader.cc index eb74659f1d46..188c23d2e5cd 100644 --- a/src/abg-reader.cc +++ b/src/abg-reader.cc @@ -47,6 +47,7 @@ ABG_BEGIN_EXPORT_DECLARATIONS #include "abg-libxml-utils.h" #include "abg-reader.h" #include "abg-corpus.h" +#include "abg-symtab-reader.h" #ifdef WITH_ZIP_ARCHIVE #include "abg-libzip-utils.h" @@ -1973,6 +1974,8 @@ read_corpus_from_input(read_context& ctxt) // Note that it's possible that both fn_sym_db and var_sym_db // are nil, due to potential suppression specifications. That's // fine. + corp.set_symtab(symtab_reader::symtab::load(fn_sym_db, var_sym_db)); + if (fn_sym_db) { corp.set_fun_symbol_map(fn_sym_db); diff --git a/tests/data/test-symtab/basic/no_debug_info.c b/tests/data/test-symtab/basic/no_debug_info.c index 5bb380ba0db8..8ac09016eb4d 100644 --- a/tests/data/test-symtab/basic/no_debug_info.c +++ b/tests/data/test-symtab/basic/no_debug_info.c @@ -1 +1 @@ -// empty! +void exported_function(){} diff --git a/tests/data/test-symtab/basic/no_debug_info.so b/tests/data/test-symtab/basic/no_debug_info.so index 827c1eee3e4e8f326af7e360ea444627ee59bee6..0b2310196a2a3a67369f80eb29e9ecefc22dc704 100755 GIT binary patch delta 1147 zcmZWoOH31C5T3tV9tB!<%cHzPw**bm(Cq`-Vl{1*M`I!w5)LMqVl09tfFOpVCM?DW zhJ&qhFdTd|AsW4SASPgpk#I5|(39dxV>oy)f(G?Kg0tN&N}SF7-_HE=`e*)Mj?a%L z?3Q^iY*PsQV1N*mfh8HV<=OS>j$NNT<1l0~Rmw`HB*SdRXEwQVUGVEvX&Z5vSu2jN zj>ggf#Ek7W;t0FD|IOD}WzFr0h4_JvUAv{Vajf89D27U`EMg^FHZg!mpGu0p>x*?7 zQ>+SmbUi{BDa=&z2Co|A;DWAO=#8Hp8X4`4MNgd{JUM!LXmGBSyIgRK-^l5T+*nN< zUz+>P>kB7XB^RhAKaN;j+u8~dItlv;Hwa}yg^E=GcA*nkoM)8t`c1_;F{ZxA$L0~!keTv z;X}8?jQGyo#udPQN>k4YvBP62H-i}38TK`a49qy;sc!+ur$O%AUnfxqd9azeAlmLP z`e7gdgfxwcMqKw;=yK6o?xh*;xLg_2NZKZbwuYZVw5`1>+7gMjc7~6%L?g|eSkl<~ z{{_TlT{XrVujr%wu@U^{PjQjfXUGCkqd)!B0ZJ*19R~t?4RV7T@f@ZCKEsbjRa&A- Gt$zTQCEAJr delta 769 zcmYjPO=uHA6rPt&tQ(Uy+mLRmfhLHOs?Gl7XR~cF5sGcW9~6V+lp+dMywrnjJTz(j zJKFexS`cbZA_yKrK~Igh9PLT;pqCy6Jy>W((An&6>0{=7^SycV-kUe`zFJ>cNy^0> z+mj;8vxBV2WH!(!B>Zi`-f0VsTPcyqX4GgZqSra&ZG3qwF^|Js#2gKwL-oYf&gaYe z@1AET?rp9f>8ssbT)rK#e63L3iG)|dE6)s~LWx*wQCJQ@_0B#GZCklpe?#8BR$O|} zi+U{5rZ6W#aPL=UZy~ay8qbXEJQ;Sd#Ynm+dvK7u`e9{Jl5RXE7 zge3gqJN+!qnG99GJIL2XyB?>D>@26mg4oa%3gD+cDIDUb=d>`+r4JACsHdI!9oXpl zOQ@w~9{+iIWW>Y#Y=@`ZFI!zNZY=J%GWG{ek4z#G8JUiDb-~i8XTIZ3cA}>;edT=R z`VBO*5o~22Vm`No?Oa&gds;|_A-S!0F^00CNN&SjT)--~y3gWb37Q_p4 X-Patchwork-Id: 39891 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 BE65F384402F; Fri, 3 Jul 2020 16:47:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BE65F384402F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794876; bh=PJCao9GdMPRw/azjkh5t/4Qc2GBgOTumrlCasZvQxW8=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=APmCnziGOXlAL2aiXWTZ7MHt0Q1FaaLukI7Yc+OLUOyWdjMOIPh1n5y1TE/NIb5Pd Dc9hGf/+nhz1M+s6nCxVgVCdl5m66zaIhrMD9J62bM6FiVJ1qu4Hdp+VIijovqgqKM 2y3mYFstYnfmHnxFjcbJzAtn2vz0HS/ZwF44k0ww= 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 B3C01384242C for ; Fri, 3 Jul 2020 16:47:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B3C01384242C Received: by mail-wr1-x449.google.com with SMTP id i14so32067325wru.17 for ; Fri, 03 Jul 2020 09:47:53 -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=PJCao9GdMPRw/azjkh5t/4Qc2GBgOTumrlCasZvQxW8=; b=migUSODNW4PFKsgDO/wJFfczZktK8cjBr6vFf71C1/vlBwhUuK3ycEx4duvmJioO7p +Gb9AOjRbke7LYlq0TrR3etmWJ7VAl0G759fXDvYPh5Kvi84V7cTzvWLx08hnFpZu/ws ahsn2OeSj/aKjYnDg/Xjvk+WB8FfGmI6ZXwa2ggMygYq2UFw9hQKs7pmOMxGqbnAsrex 5LKoiXPc3MySVWA+srqX4MsmMFCHYG+iy9yD2bE3kXTxslTbsk6n62moXJNarGDakUMW akcG9/+ByYSFC9GjmmxYLruabe4DU7PAcZGQFs+0jT/Zcn3LI4eBiqNmm+YyNWZ6wjp0 0rLw== X-Gm-Message-State: AOAM530KvWiu/f0SF+5Dtc+Q9vhgrSjK89ahUDUOzLnTm/YxEuW7sJ+H xxJ965K3k+gWjGp+YUl7pt/0mzrPJQBbZ7aAqMgiJ7ImalAXlqRg/WmMkA1zBcKu1yLrDAywfSp r3/BXgoC8XsvJrTS1r1ndlJcqVFShhVl0V8oRurDORsMzsr3MaJw/mjLNcBX20H4gAVIYNaA= X-Google-Smtp-Source: ABdhPJzpomxg16yKntvgW0b6HXadRzAX8lWxq63ojLGqTWpJatzfDvmtzU3h4DNOdTJHwC3SKc9t6IW2sl8VIw== X-Received: by 2002:adf:f04c:: with SMTP id t12mr35371397wro.382.1593794872792; Fri, 03 Jul 2020 09:47:52 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:38 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-9-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 08/21] corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab To: libabigail@sourceware.org X-Spam-Status: No, score=-23.5 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Make the corresponding members an implementation detail of corpus::priv. They get computed based on the new symtab whenever they are accessed first with an atomic instantiation. That simplifies the implementation and homogenizes the access to functions and variables. Sorting does not need to be done as the symtab already gives a guarantee for that. Due to improved alias detection in the new symtab reader, ensure we only write symbol aliases to ksymtab symbols if having a ksymtab main symbol. Test data needed to be adjusted as the new symtab reader is stricter in regards to symbols listed in ksymtab. I.e. init_module is not an exported symbol in the ksymtab of a kernel module. * src/abg-corpus-priv.h (corpus::priv::sorted_var_symbols): make private, mutable and optional. (corpus::sorted_undefined_var_symbols): Likewise. (corpus::sorted_fun_symbols): Likewise. (corpus::sorted_undefined_fun_symbols): Likewise. (corpus::priv::get_sorted_fun_symbols): New method declaration. (corpus::priv::get_sorted_undefined_fun_symbols): Likewise. (corpus::priv::get_sorted_var_symbols): Likewise. (corpus::priv::get_sorted_undefined_var_symbols): Likewise. * src/abg-corpus.cc (corpus::elf_symbol_comp_functor): Delete struct. (corpus::priv::get_sorted_fun_symbols): New method implementation. (corpus::priv::get_sorted_undefined_fun_symbols): Likewise. (corpus::priv::get_sorted_var_symbols): Likewise. (corpus::priv::get_sorted_undefined_var_symbols): Likewise. (corpus::get_sorted_fun_symbols): Proxy call to corpus::priv. (corpus::get_sorted_undefined_fun_symbols): Likewise. (corpus::get_sorted_var_symbols): Likewise. (corpus::get_sorted_undefined_var_symbols): Likewise. * src/abg-writer.cc (write_elf_symbol_aliases): When emitting aliases for a kernel symbol, ensure to only emit exported aliases. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: update test data. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-corpus-priv.h | 21 +- src/abg-corpus.cc | 242 +++++++----------- src/abg-writer.cc | 38 ++- .../data/test-read-dwarf/PR25007-sdhci.ko.abi | 3 - 4 files changed, 135 insertions(+), 169 deletions(-) diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h index 5c1e915ad2f3..ad96f260aa89 100644 --- a/src/abg-corpus-priv.h +++ b/src/abg-corpus-priv.h @@ -699,13 +699,9 @@ struct corpus::priv vector vars; string_elf_symbols_map_sptr var_symbol_map; string_elf_symbols_map_sptr undefined_var_symbol_map; - elf_symbols sorted_var_symbols; - elf_symbols sorted_undefined_var_symbols; symtab_reader::symtab_sptr symtab_; string_elf_symbols_map_sptr fun_symbol_map; string_elf_symbols_map_sptr undefined_fun_symbol_map; - elf_symbols sorted_fun_symbols; - elf_symbols sorted_undefined_fun_symbols; elf_symbols unrefed_fun_symbols; elf_symbols unrefed_var_symbols; // The type maps contained in this data member are populated if the @@ -727,6 +723,11 @@ struct corpus::priv private: priv(); + mutable abg_compat::optional sorted_var_symbols; + mutable abg_compat::optional sorted_undefined_var_symbols; + mutable abg_compat::optional sorted_fun_symbols; + mutable abg_compat::optional sorted_undefined_fun_symbols; + public: priv(const string & p, environment* e) @@ -746,6 +747,18 @@ public: const type_maps& get_types() const; + const elf_symbols& + get_sorted_fun_symbols() const; + + const elf_symbols& + get_sorted_undefined_fun_symbols() const; + + const elf_symbols& + get_sorted_var_symbols() const; + + const elf_symbols& + get_sorted_undefined_var_symbols() const; + unordered_set* get_public_types_pretty_representations(); diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc index 94702047dd82..6d4bedfd57b7 100644 --- a/src/abg-corpus.cc +++ b/src/abg-corpus.cc @@ -453,6 +453,88 @@ const type_maps& corpus::priv::get_types() const {return types_;} +/// Return a sorted vector of function symbols for this corpus. +/// +/// Note that the first time this function is called, the symbols are +/// sorted and cached. Subsequent invocations of this function return +/// the cached vector that was built previously. +/// +/// @return the sorted list of function symbols. +const elf_symbols& +corpus::priv::get_sorted_fun_symbols() const +{ + if (!sorted_fun_symbols) + { + const symtab_reader::symtab_filter filter = + symtab_->make_filter().functions(); + + sorted_fun_symbols = elf_symbols(symtab_->begin(filter), symtab_->end()); + } + return *sorted_fun_symbols; +} + +/// Getter for a sorted vector of the function symbols undefined in +/// this corpus. +/// +/// @return a vector of the function symbols undefined in this corpus, +/// sorted by name and then version. +const elf_symbols& +corpus::priv::get_sorted_undefined_fun_symbols() const +{ + if (!sorted_undefined_fun_symbols) + { + const symtab_reader::symtab_filter filter = symtab_->make_filter() + .functions() + .undefined_symbols() + .public_symbols(false); + + sorted_undefined_fun_symbols = + elf_symbols(symtab_->begin(filter), symtab_->end()); + } + return *sorted_undefined_fun_symbols; +} + +/// Getter for the sorted vector of variable symbols for this corpus. +/// +/// Note that the first time this function is called, it computes the +/// sorted vector, caches the result and returns it. Subsequent +/// invocations of this function just return the cached vector. +/// +/// @return the sorted vector of variable symbols for this corpus. +const elf_symbols& +corpus::priv::get_sorted_var_symbols() const +{ + if (!sorted_var_symbols) + { + const symtab_reader::symtab_filter filter = + symtab_->make_filter().variables(); + + sorted_var_symbols = elf_symbols(symtab_->begin(filter), symtab_->end()); + } + return *sorted_var_symbols; +} + +/// Getter for a sorted vector of the variable symbols undefined in +/// this corpus. +/// +/// @return a vector of the variable symbols undefined in this corpus, +/// sorted by name and then version. +const elf_symbols& +corpus::priv::get_sorted_undefined_var_symbols() const +{ + if (!sorted_undefined_var_symbols) + { + const symtab_reader::symtab_filter filter = symtab_->make_filter() + .variables() + .undefined_symbols() + .public_symbols(false); + + sorted_undefined_var_symbols = + elf_symbols(symtab_->begin(filter), symtab_->end()); + } + return *sorted_undefined_var_symbols; +} + /// Getter of the set of pretty representation of types that are /// reachable from public interfaces (global functions and variables). /// @@ -988,104 +1070,21 @@ const string_elf_symbols_map_type& corpus::get_undefined_fun_symbol_map() const {return *get_undefined_fun_symbol_map_sptr();} -/// Functor to sort instances of @ref elf_symbol. -struct elf_symbol_comp_functor -{ - - /// Return true if the first argument is less than the second one. - /// - /// @param l the first parameter to consider. - /// - /// @param r the second parameter to consider. - /// - /// @return true if @p l is less than @p r - bool - operator()(elf_symbol& l, elf_symbol& r) - {return (l.get_id_string() < r.get_id_string());} - - /// Return true if the first argument is less than the second one. - /// - /// @param l the first parameter to consider. - /// - /// @param r the second parameter to consider. - /// - /// @return true if @p l is less than @p r - bool - operator()(elf_symbol* l, elf_symbol* r) - {return operator()(*l, *r);} - - /// Return true if the first argument is less than the second one. - /// - /// @param l the first parameter to consider. - /// - /// @param r the second parameter to consider. - /// - /// @return true if @p l is less than @p r - bool - operator()(elf_symbol_sptr l, elf_symbol_sptr r) - {return operator()(*l, *r);} -}; // end struct elf_symbol_comp_functor - -/// Return a sorted vector of function symbols for this corpus. -/// -/// Note that the first time this function is called, the symbols are -/// sorted and cached. Subsequent invocations of this function return -/// the cached vector that was built previously. -/// -/// @return the sorted list of function symbols. const elf_symbols& corpus::get_sorted_fun_symbols() const -{ - if (priv_->sorted_fun_symbols.empty() - && !get_fun_symbol_map().empty()) - { - priv_->sorted_fun_symbols.reserve(get_fun_symbol_map().size()); - for (string_elf_symbols_map_type::const_iterator i = - get_fun_symbol_map().begin(); - i != get_fun_symbol_map().end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - priv_->sorted_fun_symbols.push_back(*s); +{ return priv_->get_sorted_fun_symbols(); } - elf_symbol_comp_functor comp; - std::sort(priv_->sorted_fun_symbols.begin(), - priv_->sorted_fun_symbols.end(), - comp); - } - return priv_->sorted_fun_symbols; -} - -/// Getter for a sorted vector of the function symbols undefined in -/// this corpus. -/// -/// @return a vector of the function symbols undefined in this corpus, -/// sorted by name and then version. const elf_symbols& corpus::get_sorted_undefined_fun_symbols() const -{ - if (priv_->sorted_undefined_fun_symbols.empty() - && !get_undefined_fun_symbol_map().empty()) - { - priv_->sorted_undefined_fun_symbols.reserve - (get_undefined_fun_symbol_map().size()); - for (string_elf_symbols_map_type::const_iterator i = - get_undefined_fun_symbol_map().begin(); - i != get_undefined_fun_symbol_map().end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - priv_->sorted_undefined_fun_symbols.push_back(*s); +{ return priv_->get_sorted_undefined_fun_symbols(); } - elf_symbol_comp_functor comp; - std::sort(priv_->sorted_undefined_fun_symbols.begin(), - priv_->sorted_undefined_fun_symbols.end(), - comp); - } - return priv_->sorted_undefined_fun_symbols; -} +const elf_symbols& +corpus::get_sorted_var_symbols() const +{ return priv_->get_sorted_var_symbols(); } + +const elf_symbols& +corpus::get_sorted_undefined_var_symbols() const +{ return priv_->get_sorted_undefined_var_symbols(); } /// Getter for the variable symbols map. /// @@ -1125,65 +1124,6 @@ const string_elf_symbols_map_type& corpus::get_undefined_var_symbol_map() const {return *get_undefined_var_symbol_map_sptr();} -/// Getter for the sorted vector of variable symbols for this corpus. -/// -/// Note that the first time this function is called, it computes the -/// sorted vector, caches the result and returns it. Subsequent -/// invocations of this function just return the cached vector. -/// -/// @return the sorted vector of variable symbols for this corpus. -const elf_symbols& -corpus::get_sorted_var_symbols() const -{ - if (priv_->sorted_var_symbols.empty() - && !get_var_symbol_map().empty()) - { - priv_->sorted_var_symbols.reserve(get_var_symbol_map().size()); - for (string_elf_symbols_map_type::const_iterator i = - get_var_symbol_map().begin(); - i != get_var_symbol_map().end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); ++s) - priv_->sorted_var_symbols.push_back(*s); - - elf_symbol_comp_functor comp; - std::sort(priv_->sorted_var_symbols.begin(), - priv_->sorted_var_symbols.end(), - comp); - } - return priv_->sorted_var_symbols; -} - -/// Getter for a sorted vector of the variable symbols undefined in -/// this corpus. -/// -/// @return a vector of the variable symbols undefined in this corpus, -/// sorted by name and then version. -const elf_symbols& -corpus::get_sorted_undefined_var_symbols() const -{ - if (priv_->sorted_undefined_var_symbols.empty() - && !get_undefined_var_symbol_map().empty()) - { - priv_->sorted_undefined_var_symbols.reserve - (get_undefined_var_symbol_map().size()); - for (string_elf_symbols_map_type::const_iterator i = - get_undefined_var_symbol_map().begin(); - i != get_undefined_var_symbol_map().end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); ++s) - priv_->sorted_undefined_var_symbols.push_back(*s); - - elf_symbol_comp_functor comp; - std::sort(priv_->sorted_undefined_var_symbols.begin(), - priv_->sorted_undefined_var_symbols.end(), - comp); - } - return priv_->sorted_undefined_var_symbols; -} - /// Look in the function symbols map for a symbol with a given name. /// /// @param n the name of the symbol to look for. diff --git a/src/abg-writer.cc b/src/abg-writer.cc index ce0bae2d5cfd..c5be11b26072 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -1693,26 +1693,42 @@ write_elf_symbol_visibility(elf_symbol::visibility v, ostream& o) /// /// @return true upon successful completion. static bool -write_elf_symbol_aliases(const elf_symbol& sym, ostream& o) +write_elf_symbol_aliases(const elf_symbol& sym, ostream& out) { if (!sym.is_main_symbol() || !sym.has_aliases()) return false; - bool emitted = false; - o << " alias='"; - for (elf_symbol_sptr s = sym.get_next_alias(); - !s->is_main_symbol(); + + std::vector aliases; + for (elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol(); s = s->get_next_alias()) { - if (s->get_next_alias()->is_main_symbol()) - o << s->get_id_string() << "'"; - else - o << s->get_id_string() << ","; + if (s->is_suppressed()) + continue; - emitted = true; + if (sym.is_in_ksymtab() != s->is_in_ksymtab()) + continue; + + aliases.push_back(s->get_id_string()); } - return emitted; + if (!aliases.empty()) + { + out << " alias='"; + std::string separator; + for (std::vector::const_iterator it = aliases.begin(), + end = aliases.end(); + it != end; ++it) + { + out << separator << *it; + separator = ","; + } + + out << "'"; + return true; + } + + return false; } /// Write an XML attribute for the reference to a symbol for the diff --git a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi index 755ea6dc433e..d5af7183095f 100644 --- a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi +++ b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi @@ -2,8 +2,6 @@ - - @@ -40,7 +38,6 @@ - From patchwork Fri Jul 3 16:46:39 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: 39892 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 303E1384242F; Fri, 3 Jul 2020 16:47:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 303E1384242F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794878; bh=NGMR45e9WnXms2tqaAPKrDI+pIjrfU0/0GVHbDJO1Mw=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=BReeCw1nOpmnVHvcQnQf4Uzi0Uhe6StIp7jt0k6CohX+esAqQW2Eg14hhN95uyVeG AIu+f78iedGfAvGovz867GnlQ1CAkdNRJvqvaG/Sm9NVMSu9mrIgBVynIMaiCxqckZ JOuHRWuLGKKQm5iIcpoPNOJ79/sl2AjqTc3kktnQ= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by sourceware.org (Postfix) with ESMTPS id 64A203844079 for ; Fri, 3 Jul 2020 16:47:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 64A203844079 Received: by mail-qv1-xf49.google.com with SMTP id g17so19171478qvw.0 for ; Fri, 03 Jul 2020 09:47:55 -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=NGMR45e9WnXms2tqaAPKrDI+pIjrfU0/0GVHbDJO1Mw=; b=gKn+5D6JOhJZze5zHnBjftyYNdCYa/DLacESmp5KG7JAXCEp4B9wP82olj+iA4A/iD kXmQK3ldtbGkznsk3YGXI81TeIrA09ih7I6zjB2ANzfmSgEIBP0Dbo+jr5xh5nnCUuC+ n8GkT7CDSBthyGmylP66OT8/bQkQL8AQkFenVQPf1xSXt83J8bd96xrkK2AezmWUdIyi PUS/wO7zjzxqvbcmKC5bOkSSxcvpj5iPL4ACVQ7ot0Eyu6k/FKRkLq0p9TMKRFTwKUZI h32jj6C9bdpClQKUdnBanSdRbnGksMe9f+ZFo3ac2KgybwdsVRuncdgtzF6fpLK8EGdb KaOg== X-Gm-Message-State: AOAM532gXrhJtkq0Z6GFRbodT5sbYXgPrGsweqMaj39ZKGJJ/sGJ6EFb ZXsSR72csoXw0os/5pBbuqQAjj8/IG0QqoLS3o6Y0AzeMyAryX5a8OLRRcRTnV3Fmh7KNK+TCOb EVbZLgbCQ7fNGP5V05+UCTOJP249tILxhzfoKatXjnsoBLzECdad7Qpgk8nYpxonhM1D72w8= X-Google-Smtp-Source: ABdhPJxl9FZGlRYA4x5K3ZCgIssrqm3MGsmLGdbpX73WM5s6mOvJqUNmTvA1ZpGHJGgS40DItWoyx4KeO4DONg== X-Received: by 2002:a0c:fcc9:: with SMTP id i9mr17303940qvq.152.1593794874877; Fri, 03 Jul 2020 09:47:54 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:39 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-10-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 09/21] corpus: make get_unreferenced_(function|variable)_symbols use the new symtab To: libabigail@sourceware.org X-Spam-Status: No, score=-22.3 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Make the corresponding members an implementation detail of corpus::priv. They get computed based on the new symtab whenever they are accessed first with an atomic instantiation. That simplifies the implementation and homogenizes the access to functions and variables. Sorting does not need to be done as the symtab already gives a guarantee for that. * src/abg-corpus-priv.h (corpus::priv::unrefed_var_symbols): make private, mutable and optional. (corpus::unrefed_fun_symbols): Likewise. (corpus::priv::get_unreferenced_function_symbols): New method declaration. (corpus::priv::get_unreferenced_variable_symbols): Likewise. * src/abg-corpus.cc (corpus::priv::build_unreferenced_symbols_tables): Delete method. (corpus::priv::get_unreferenced_function_symbols): New method implementation. (corpus::priv::get_unreferenced_variable_symbols): Likewise. (corpus::get_unreferenced_function_symbols): Proxy call to corpus::priv. (corpus::get_unreferenced_variable_symbols): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-corpus-priv.h | 13 ++- src/abg-corpus.cc | 261 ++++++++++++++++++++---------------------- 2 files changed, 131 insertions(+), 143 deletions(-) diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h index ad96f260aa89..f2e895bf1e7d 100644 --- a/src/abg-corpus-priv.h +++ b/src/abg-corpus-priv.h @@ -702,8 +702,6 @@ struct corpus::priv symtab_reader::symtab_sptr symtab_; string_elf_symbols_map_sptr fun_symbol_map; string_elf_symbols_map_sptr undefined_fun_symbol_map; - elf_symbols unrefed_fun_symbols; - elf_symbols unrefed_var_symbols; // The type maps contained in this data member are populated if the // corpus follows the One Definition Rule and thus if there is only // one copy of a type with a given name, per corpus. Otherwise, if @@ -725,8 +723,10 @@ private: mutable abg_compat::optional sorted_var_symbols; mutable abg_compat::optional sorted_undefined_var_symbols; + mutable abg_compat::optional unrefed_var_symbols; mutable abg_compat::optional sorted_fun_symbols; mutable abg_compat::optional sorted_undefined_fun_symbols; + mutable abg_compat::optional unrefed_fun_symbols; public: priv(const string & p, @@ -738,9 +738,6 @@ public: pub_type_pretty_reprs_() {} - void - build_unreferenced_symbols_tables(); - type_maps& get_types(); @@ -753,12 +750,18 @@ public: const elf_symbols& get_sorted_undefined_fun_symbols() const; + const elf_symbols& + get_unreferenced_function_symbols() const; + const elf_symbols& get_sorted_var_symbols() const; const elf_symbols& get_sorted_undefined_var_symbols() const; + const elf_symbols& + get_unreferenced_variable_symbols() const; + unordered_set* get_public_types_pretty_representations(); diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc index 6d4bedfd57b7..0f5d51820891 100644 --- a/src/abg-corpus.cc +++ b/src/abg-corpus.cc @@ -317,132 +317,6 @@ struct comp_elf_symbols_functor // - -/// Build the tables of symbols that are not referenced by any -/// function or variables of corpus::get_functions() or -/// corpus::get_variables(). -/// -/// Note that this function considers the list of function and -/// variable symbols to keep, that is provided by -/// corpus::get_sym_ids_of_fns_to_keep() and -/// corpus::get_sym_ids_of_vars_to_keep(). If a given unreferenced -/// function or variable symbol is not in the list of variable and -/// function symbols to keep, then that symbol is dropped and will not -/// be part of the resulting table of unreferenced symbol that is -/// built. -/// -/// The built tables are accessible from -/// corpus::get_unreferenced_function_symbols() and -/// corpus::get_unreferenced_variable_symbols(). -void -corpus::priv::build_unreferenced_symbols_tables() -{ - unordered_map refed_funs, refed_vars; - elf_symbol_sptr sym; - - for (vector::const_iterator f = fns.begin(); - f != fns.end(); - ++f) - if ((sym = (*f)->get_symbol())) - { - refed_funs[sym->get_id_string()] = true; - for (elf_symbol_sptr a = sym->get_next_alias(); - a && !a->is_main_symbol(); - a = a->get_next_alias()) - refed_funs[a->get_id_string()] = true; - } - - for (vector::const_iterator v = vars.begin(); - v != vars.end(); - ++v) - if ((sym = (*v)->get_symbol())) - { - refed_vars[sym->get_id_string()] = true; - for (elf_symbol_sptr a = sym->get_next_alias(); - a && !a->is_main_symbol(); - a = a->get_next_alias()) - refed_vars[a->get_id_string()] = true; - } - - if (fun_symbol_map) - { - // Let's assume that the size of the unreferenced symbols vector - // is roughly smaller than the size of the symbol table. - unrefed_fun_symbols.reserve(fun_symbol_map->size()); - for (string_elf_symbols_map_type::const_iterator i - = fun_symbol_map->begin(); - i != fun_symbol_map->end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - { - string sym_id = (*s)->get_id_string(); - if (refed_funs.find(sym_id) == refed_funs.end()) - { - bool keep = sym_id_fns_to_keep.empty(); - for (vector::const_iterator i = - sym_id_fns_to_keep.begin(); - i != sym_id_fns_to_keep.end(); - ++i) - { - if (*i == sym_id) - { - keep = true; - break; - } - } - if (keep) - unrefed_fun_symbols.push_back(*s); - } - } - - comp_elf_symbols_functor comp; - std::sort(unrefed_fun_symbols.begin(), - unrefed_fun_symbols.end(), - comp); - } - - if (var_symbol_map) - { - // Let's assume that the size of the unreferenced symbols vector - // is roughly smaller than the size of the symbol table. - unrefed_var_symbols.reserve(var_symbol_map->size()); - for (string_elf_symbols_map_type::const_iterator i - = var_symbol_map->begin(); - i != var_symbol_map->end(); - ++i) - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - { - string sym_id = (*s)->get_id_string(); - if (refed_vars.find(sym_id) == refed_vars.end()) - { - bool keep = sym_id_vars_to_keep.empty(); - for (vector::const_iterator i = - sym_id_vars_to_keep.begin(); - i != sym_id_vars_to_keep.end(); - ++i) - { - if (*i == sym_id) - { - keep = true; - break; - } - } - if (keep) - unrefed_var_symbols.push_back(*s); - } - } - - comp_elf_symbols_functor comp; - std::sort(unrefed_var_symbols.begin(), - unrefed_var_symbols.end(), - comp); - } -} - /// Get the maps that associate a name to a certain kind of type. type_maps& corpus::priv::get_types() @@ -494,6 +368,66 @@ corpus::priv::get_sorted_undefined_fun_symbols() const return *sorted_undefined_fun_symbols; } +/// Return a list of symbols that are not referenced by any function of +/// corpus::get_functions(). +/// +/// Note that this function considers the list of function symbols to keep, +/// that is provided by corpus::get_sym_ids_of_fns_to_keep(). If a given +/// unreferenced function symbol is not in the list of functions to keep, then +/// that symbol is dropped and will not be part of the resulting table of +/// unreferenced symbol that is built. +const elf_symbols& +corpus::priv::get_unreferenced_function_symbols() const +{ + if (!unrefed_fun_symbols) + { + unrefed_fun_symbols = elf_symbols(); + if (symtab_) + { + unordered_map refed_funs; + elf_symbol_sptr sym; + + for (vector::const_iterator f = fns.begin(); + f != fns.end(); ++f) + if ((sym = (*f)->get_symbol())) + { + refed_funs[sym->get_id_string()] = true; + for (elf_symbol_sptr a = sym->get_next_alias(); + a && !a->is_main_symbol(); a = a->get_next_alias()) + refed_funs[a->get_id_string()] = true; + } + + symtab_reader::symtab_filter filter = + symtab_->make_filter().functions(); + for (symtab_reader::symtab::const_iterator iter = + symtab_->begin(filter); + iter != symtab_->end(); iter++) + { + const elf_symbol_sptr& symbol = *iter; + const std::string sym_id = symbol->get_id_string(); + + if (refed_funs.find(sym_id) == refed_funs.end()) + { + bool keep = sym_id_fns_to_keep.empty(); + for (vector::const_iterator i = + sym_id_fns_to_keep.begin(); + i != sym_id_fns_to_keep.end(); ++i) + { + if (*i == sym_id) + { + keep = true; + break; + } + } + if (keep) + unrefed_fun_symbols->push_back(symbol); + } + } + } + } + return *unrefed_fun_symbols; +} + /// Getter for the sorted vector of variable symbols for this corpus. /// /// Note that the first time this function is called, it computes the @@ -535,6 +469,67 @@ corpus::priv::get_sorted_undefined_var_symbols() const return *sorted_undefined_var_symbols; } +/// Return a list of symbols that are not referenced by any variable of +/// corpus::get_variables(). +/// +/// Note that this function considers the list of variable symbols to keep, +/// that is provided by corpus::get_sym_ids_of_vars_to_keep(). If a given +/// unreferenced variable symbol is not in the list of variable to keep, then +/// that symbol is dropped and will not be part of the resulting table of +/// unreferenced symbol that is built. +const elf_symbols& +corpus::priv::get_unreferenced_variable_symbols() const +{ + if (!unrefed_var_symbols) + { + unrefed_var_symbols = elf_symbols(); + if (symtab_) + { + unordered_map refed_vars; + elf_symbol_sptr sym; + + for (vector::const_iterator f = vars.begin(); + f != vars.end(); ++f) + if ((sym = (*f)->get_symbol())) + { + refed_vars[sym->get_id_string()] = true; + for (elf_symbol_sptr a = sym->get_next_alias(); + a && !a->is_main_symbol(); a = a->get_next_alias()) + refed_vars[a->get_id_string()] = true; + } + + symtab_reader::symtab_filter filter = + symtab_->make_filter().variables(); + for (symtab_reader::symtab::const_iterator iter = + symtab_->begin(filter); + iter != symtab_->end(); iter++) + { + const elf_symbol_sptr& symbol = *iter; + const std::string sym_id = symbol->get_id_string(); + + if (refed_vars.find(sym_id) == refed_vars.end()) + { + bool keep = sym_id_vars_to_keep.empty(); + for (vector::const_iterator i = + sym_id_vars_to_keep.begin(); + i != sym_id_vars_to_keep.end(); ++i) + { + if (*i == sym_id) + { + keep = true; + break; + } + } + if (keep) + unrefed_var_symbols->push_back(symbol); + } + } + } + } + return *unrefed_var_symbols; +} + + /// Getter of the set of pretty representation of types that are /// reachable from public interfaces (global functions and variables). /// @@ -1366,12 +1361,7 @@ corpus::sort_variables() /// function exported by the current corpus. const elf_symbols& corpus::get_unreferenced_function_symbols() const -{ - if (priv_->unrefed_fun_symbols.empty() - && priv_->unrefed_var_symbols.empty()) - priv_->build_unreferenced_symbols_tables(); - return priv_->unrefed_fun_symbols; -} +{ return priv_->get_unreferenced_function_symbols(); } /// Getter of the set of variable symbols that are not referenced by /// any variable exported by the current corpus. @@ -1384,12 +1374,7 @@ corpus::get_unreferenced_function_symbols() const /// variable exported by the current corpus. const elf_symbols& corpus::get_unreferenced_variable_symbols() const -{ - if (priv_->unrefed_fun_symbols.empty() - && priv_->unrefed_var_symbols.empty()) - priv_->build_unreferenced_symbols_tables(); - return priv_->unrefed_var_symbols; -} +{ return priv_->get_unreferenced_variable_symbols(); } /// Accessor for the regex patterns describing the functions to drop /// from the public decl table. From patchwork Fri Jul 3 16:46:40 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: 39893 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 7539F3844079; Fri, 3 Jul 2020 16:47:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7539F3844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794879; bh=3P2d+fjupyx5VAwAb10QxExv7VixtlSu3Z8yoApKqdg=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=wJSMV1meKGorkMAMFnEDwDqpWXGDnmZt4S35JKyz2iNvxX1vPHLUQpSfUoTrU3W5z WrM3wPL+99ZdpfKCnwS4jbv7tPjBIhaLDNRkbyWIEZyLRQJkCb0EvSo88f+G/Cu/cY Et/heQUTicRpJHtRpi+TBVBYxtKpUBsu/bqlq9iE= 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 5DCCB3844079 for ; Fri, 3 Jul 2020 16:47:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5DCCB3844079 Received: by mail-qt1-x84a.google.com with SMTP id i5so22183185qtw.3 for ; Fri, 03 Jul 2020 09:47:57 -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=3P2d+fjupyx5VAwAb10QxExv7VixtlSu3Z8yoApKqdg=; b=EGc0Tj6FfuGYz6PGcZobCEv07/AmKEaeDkd618ijl2HJzQvO8QZgfef6ZYijhY3K+F ARPKdc6Fk/d/kJ+Kb+Nm9FVOs+bi3mTAye8Tg0ydumBlcFm5ULuzVYIlMZ/8gSDBZCCW 0J/ePoyhN7GiJzQ9OW2iz3RcvSGImmXl8CpLTyIqKZkaaXGpuintlYsQpqYf9uNJ+iN6 fRE/08K6NEpT9J/psbzKa7GRzyFrrm/BtXoafQNdSWmnXIxcZzj21MK/0cawj1sYOHoq DMguz6/VWjF+grxLMjSaEWfd5+Dh2l96RMwiFpRaHwFAKY2Q3buoLJkAvn5yCdUsvjFu RJOg== X-Gm-Message-State: AOAM532IISEKLHUUKARkDNcefyrn04OXRon0+71biTi034Z9e5dnmDsn rnnDaF+p07OhmDLof319GSFWMCZqEubykTWn08n01hMTDS0xTZXsg2EvuuplTVHGQiuDUMzJf2B xeYs8veXYPXBzArtIB3Vy7uSJxMQajdpUeVpTIBJrQGFtt26yp8NeppEZf8A99OW9oAkDCFI= X-Google-Smtp-Source: ABdhPJyyKQT99H5mppNF9TqP3G0dBpJK/3o9XOsEqwrbzALQVMyX9HplOYxTFRp8mwi1OPi9HJOtve8qO0hnEQ== X-Received: by 2002:a0c:db8a:: with SMTP id m10mr36181699qvk.21.1593794876899; Fri, 03 Jul 2020 09:47:56 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:40 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-11-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 10/21] abg-reader: avoid using the (var|function)_symbol_map To: libabigail@sourceware.org X-Spam-Status: No, score=-22.3 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Instead of using the corpus var|function_symbol_maps for symbol lookups, let build_elf_symbol_from_reference use the symtab::lookup_symbol method. That leads to a shorter implementation and we can drop the indicative parameter. * src/abg-reader.cc (build_elf_symbol_from_reference): drop last parameter indicating the lookup type and use corpus symtab for the lookup (build_function_decl): Adjust accordingly. (build_var_decl): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-reader.cc | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/abg-reader.cc b/src/abg-reader.cc index 188c23d2e5cd..313639fddff0 100644 --- a/src/abg-reader.cc +++ b/src/abg-reader.cc @@ -1150,8 +1150,7 @@ static elf_symbol_sptr build_elf_symbol(read_context&, const xmlNodePtr, bool); static elf_symbol_sptr -build_elf_symbol_from_reference(read_context&, const xmlNodePtr, - bool); +build_elf_symbol_from_reference(read_context&, const xmlNodePtr); static string_elf_symbols_map_sptr build_elf_symbol_db(read_context&, const xmlNodePtr, bool); @@ -2884,8 +2883,7 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node, /// /// @return a shared pointer the resutling elf_symbol. static elf_symbol_sptr -build_elf_symbol_from_reference(read_context& ctxt, const xmlNodePtr node, - bool function_symbol) +build_elf_symbol_from_reference(read_context& ctxt, const xmlNodePtr node) { elf_symbol_sptr nil; @@ -2904,20 +2902,13 @@ build_elf_symbol_from_reference(read_context& ctxt, const xmlNodePtr node, if (name.empty()) return nil; - string_elf_symbols_map_sptr sym_db = - (function_symbol) - ? ctxt.get_corpus()->get_fun_symbol_map_sptr() - : ctxt.get_corpus()->get_var_symbol_map_sptr(); + const elf_symbols& symbols = + ctxt.get_corpus()->get_symtab()->lookup_symbol(name); - string_elf_symbols_map_type::const_iterator i = sym_db->find(name); - if (i != sym_db->end()) - { - for (elf_symbols::const_iterator s = i->second.begin(); - s != i->second.end(); - ++s) - if ((*s)->get_id_string() == sym_id) - return *s; - } + for (elf_symbols::const_iterator symbol = symbols.begin(); + symbol != symbols.end(); ++symbol) + if ((*symbol)->get_id_string() == sym_id) + return *symbol; } return nil; @@ -3168,8 +3159,7 @@ build_function_decl(read_context& ctxt, ctxt.push_decl_to_current_scope(fn_decl, add_to_current_scope); - elf_symbol_sptr sym = build_elf_symbol_from_reference(ctxt, node, - /*function_sym=*/true); + elf_symbol_sptr sym = build_elf_symbol_from_reference(ctxt, node); if (sym) fn_decl->set_symbol(sym); @@ -3400,8 +3390,7 @@ build_var_decl(read_context& ctxt, locus, mangled_name, vis, bind)); - elf_symbol_sptr sym = build_elf_symbol_from_reference(ctxt, node, - /*function_sym=*/false); + elf_symbol_sptr sym = build_elf_symbol_from_reference(ctxt, node); if (sym) decl->set_symbol(sym); From patchwork Fri Jul 3 16:46:41 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: 39894 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 B9C6F3844079; Fri, 3 Jul 2020 16:48:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B9C6F3844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794881; bh=bjvevK4XRxlsEQarn4V+87rXypA7XXC5pAyzcLO0xvM=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ys/dPiWeWXvuIOrPxwNwPJO56CTlnnaHPgwwthfVa7d41JNWqMC+RIrQCFcAMFSRU 7nvVA77B9g5++N+0LaE/FCUeutxxo5m1Ek3DlnPOnYqDeICsD5HLh4+8I2jGMzfhY/ yusg1V9N6Rrj5xP14phpZFZJuozGnnuDJlHtYK0E= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by sourceware.org (Postfix) with ESMTPS id 964B63844038 for ; Fri, 3 Jul 2020 16:47:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 964B63844038 Received: by mail-yb1-xb4a.google.com with SMTP id j3so34223570yba.14 for ; Fri, 03 Jul 2020 09:47:59 -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=bjvevK4XRxlsEQarn4V+87rXypA7XXC5pAyzcLO0xvM=; b=sP86Wugxn0VabhgHORv4juYUAj3xbzR5jsWqsGPYGscbs8Oq596ST1ODtyMclBQV+O ACpr9rEkqw+nqQ5NYkQsWOsPVP4T2rQCMtoZUR5K+8yfaeqdHE0IleY85+aFC2joWT4V xnQFPillStOP5viQQQNSn04VHnYLyxUZV1M4XD/RueSqhM4wPJP7z59CaEjKvbJ3Y2H1 ledRIGJcohkwTP4c7dtLW5GvDpwY0fy7eDik81uWmm0GRUk5E4Kq96fQ5+jMQO+JI97J 09jnaH1O4WWtDUjxFfVztnaOShw6v70vA/hT90WKvhAynooiIj2ef7WHzKBKCer42Mjx Q+UQ== X-Gm-Message-State: AOAM532a7MZohyeha/NbkezYlrj2l70vU70olk2kuSMeLXg9qCnrBwxS xBzlwtw6J6YEHunB/FE3Lj+ip6cBd4YHx2BL0UNbaKcVWo0DY8dNsNJEm98bdjY2jjgJLYWnQeu yvTgCu77CQX6Y4PhUErDGN2dObQilrbTxA0dUGr0FhvqcmJJLg2EdWMMzFiY+OlNkjDAu3S4= X-Google-Smtp-Source: ABdhPJwG8ncR1At1tgNiEip0zsJ3k4yszVS1VyFuD25xdv2gD/Ie0YpMe5jep9MH5guLsBPqIpjxGLR/+CIR/A== X-Received: by 2002:a25:37ca:: with SMTP id e193mr59162145yba.505.1593794879036; Fri, 03 Jul 2020 09:47:59 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:41 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-12-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 11/21] dwarf-reader: read_context: use new symtab in *_symbols_is_exported To: libabigail@sourceware.org X-Spam-Status: No, score=-22.6 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Testing whether a symbol is exported can be simplified using the new symtab implementation. The same holds true for whether a symbol is exported via ksymtab in case of linux kernel binaries. So, do that. * src/abg-dwarf-reader.cc (function_symbol_is_exported): Use new symtab implementation. (variable_symbol_is_exported): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-dwarf-reader.cc | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index d9c1c03d273f..6f792a957076 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -5515,11 +5515,11 @@ public: elf_symbol_sptr function_symbol_is_exported(GElf_Addr symbol_address) const { - elf_symbol_sptr symbol = lookup_elf_fn_symbol_from_address(symbol_address); + elf_symbol_sptr symbol = symtab()->lookup_symbol(symbol_address); if (!symbol) return symbol; - if (!symbol->is_public()) + if (!symbol->is_function() || !symbol->is_public()) return elf_symbol_sptr(); address_set_sptr set; @@ -5528,16 +5528,8 @@ public: if (looking_at_linux_kernel_binary) { - if ((set = linux_exported_fn_syms())) - { - if (set->find(symbol_address) != set->end()) - return symbol; - } - if ((set = linux_exported_gpl_fn_syms())) - { - if (set->find(symbol_address) != set->end()) - return symbol; - } + if (symbol->is_in_ksymtab()) + return symbol; return elf_symbol_sptr(); } @@ -5555,11 +5547,11 @@ public: elf_symbol_sptr variable_symbol_is_exported(GElf_Addr symbol_address) const { - elf_symbol_sptr symbol = lookup_elf_var_symbol_from_address(symbol_address); + elf_symbol_sptr symbol = symtab()->lookup_symbol(symbol_address); if (!symbol) return symbol; - if (!symbol->is_public()) + if (!symbol->is_variable() || !symbol->is_public()) return elf_symbol_sptr(); address_set_sptr set; @@ -5568,16 +5560,8 @@ public: if (looking_at_linux_kernel_binary) { - if ((set = linux_exported_var_syms())) - { - if (set->find(symbol_address) != set->end()) - return symbol; - } - if ((set = linux_exported_gpl_var_syms())) - { - if (set->find(symbol_address) != set->end()) - return symbol; - } + if (symbol->is_in_ksymtab()) + return symbol; return elf_symbol_sptr(); } From patchwork Fri Jul 3 16:46:42 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: 39896 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 5523D386F028; Fri, 3 Jul 2020 16:48:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5523D386F028 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794888; bh=Io1lf7VPKpazf6eH5orO5SsNJp559pIPx72GzmIurRk=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Ce4S9iBguzpF4NhDQfiDpL4AxgbPy9/kqSY6kSb6vxq2QVl+poGc5Jo3SECEud8Jj h/l74C5e/1yC2ogLA6oJzREfCNtP8s2OMxL2sy2RYd7lsi01/D98u3NEgFQxNw/lak TFc07TcXcEyZjw2/H9ekzAHa1Z32+miq44rIM2Kk= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wr1-x44a.google.com (mail-wr1-x44a.google.com [IPv6:2a00:1450:4864:20::44a]) by sourceware.org (Postfix) with ESMTPS id 3307D384240C for ; Fri, 3 Jul 2020 16:48:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3307D384240C Received: by mail-wr1-x44a.google.com with SMTP id b8so18190907wro.19 for ; Fri, 03 Jul 2020 09:48:02 -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=Io1lf7VPKpazf6eH5orO5SsNJp559pIPx72GzmIurRk=; b=fiV79J3udWWMqzXiGrMrLFPFh7gcKqwtm5S5nVUoBCHtyptQ6BjB/Io9w5jxSa11Jm Mftax0JcJ3PcoEFB3Xi264RdOITbpOZ3v+THYCXtbJVmt8MFsZnmTqS76zch/QoswKMg vCb0GsBT6BLrGIl8VyBtqSofPHhyLUaKKx4sKhqY2llvbLNGcsr8h1eLgIoVCCDkHYH4 rsYLdstYOzYe3YsYQs90yeQnnOmPXFV9QcAbRDcD2zXVQL9hyEjxNYjfqQNwLiB4pK74 MhySCo0IXGuA4Ax6KaKWtPXzmO4MoYC+P0P3NYz0jB+N8DTYoeKfCxKT3DhXeZjxgQCZ 7WPg== X-Gm-Message-State: AOAM531lGljIj/JmWY8MICZkNn8/ogXY266W0DJkI1NIVhrpIIUjhNSU klE43in5FnGczkPHLBJmkpgTkaIguQrZ2CJB/qhAPhfW96AizdmTDib/2XLF53ISC1N6y394p1B Kpj9Gxod/UzJWH2iacgTvzeOcMqPgj5FNMrCF63+4BNagmU9ADEZRN9VdDdbTz7M1z9p/wSE= X-Google-Smtp-Source: ABdhPJxrmRm/ak4FqaqVVGKl7K8bXzl7ibXvszNB+m3OOHi74+yECBjhDS/6JXb85BEk5+QU5xE32tdE4lrqvA== X-Received: by 2002:a5d:518a:: with SMTP id k10mr36813215wrv.316.1593794881195; Fri, 03 Jul 2020 09:48:01 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:42 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-13-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 12/21] Switch kernel stuff over to new symtab and drop unused code To: libabigail@sourceware.org X-Spam-Status: No, score=-22.2 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, 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" Now that the new symtab implementation is capable of reading the ksymtab, we can switch over the implementation to gather information from there and delete all now-obsolete code. * src/abg-dwarf-reader.cc: (kernel_symbol_table_kind): Delete. (ksymtab_format): Likewise. (read_context::ksymtab_format_): Likewise. (read_context::ksymtab_entry_size_): Likewise. (read_context::nb_ksymtab_entries_): Likewise. (read_context::nb_ksymtab_gpl_entries_): Likewise. (read_context::ksymtab_section_): Likewise. (read_context::ksymtab_reloc_section_): Likewise. (read_context::ksymtab_gpl_section_): Likewise. (read_context::ksymtab_gpl_reloc_section_): Likewise. (read_context::ksymtab_strings_section_): Likewise. (read_context::linux_exported_fn_syms_): Likewise. (read_context::linux_exported_var_syms_): Likewise. (read_context::linux_exported_gpl_fn_syms_): Likewise. (read_context::linux_exported_gpl_var_syms_): Likewise. (read_context::initialize): Remove initializations accordingly. (read_context::find_ksymtab_section): Delete. (read_context::find_ksymtab_gpl_section): Likewise. (read_context::find_ksymtab_reloc_section): Likewise. (read_context::find_ksymtab_gpl_reloc_section): Likewise. (read_context::find_ksymtab_strings_section): Likewise. (read_context::find_any_ksymtab_section): Likewise. (read_context::find_any_ksymtab_reloc_section): Likewise. (read_context::lookup_elf_symbol_from_index): Adjust overload with main logic.. (read_context::linux_exported_fn_syms): Delete. (read_context::create_or_get_linux_exported_fn_syms): Likewise. (read_context::linux_exported_var_syms): Likewise. (read_context::create_or_get_linux_exported_var_syms): Likewise. (read_context::linux_exported_gpl_fn_syms): Delete. (read_context::create_or_get_linux_exported_gpl_fn_syms): Likewise. (read_context::linux_exported_gpl_var_syms): Likewise. (read_context::create_or_get_linux_exported_gpl_var_syms): Likewise. (read_context::try_reading_first_ksymtab_entry): Likewise. (read_context::try_reading_first_ksymtab_entry_using_pre_v4_19_format): Likewise. (read_context::try_reading_first_ksymtab_entry_using_v4_19_format): Likewise. (read_context::get_ksymtab_format_module): Likewise. (read_context::get_ksymtab_format): Likewise. (read_context::get_ksymtab_symbol_value_size): Likewise. (read_context::get_ksymtab_entry_size): Likewise. (read_context::get_nb_ksymtab_entries): Likewise. (read_context::get_nb_ksymtab_gpl_entries): Likewise. (read_context::populate_symbol_map_from_ksymtab): Likewise. (read_context::populate_symbol_map_from_ksymtab_reloc): Likewise. (read_context::load_kernel_symbol_table): Likewise. (read_context::load_ksymtab_symbols): Likewise. (read_context::load_ksymtab_gpl_symbols): Likewise. (read_context::load_linux_specific_exported_symbol_maps): Likewise. (read_context::load_symbol_maps): Do not load kernel symbol maps. (read_context::maybe_adjust_sym_address_from_v4_19_ksymtab): Delete. (read_context::add_fn_symbols_to_map): Likewise. (read_context::add_var_symbols_to_map): Likewise. (read_context::read_debug_info_into_corpus): Fill export maps from new symtab. (read_context::lookup_elf_fn_symbol_from_address): Delete. (read_context::lookup_elf_var_symbol_from_address): Likewise. (read_context::lookup_elf_symbol_from_address): Likewise. (read_context::lookup_public_function_symbol_from_elf): Likewise. (read_context::fun_entry_addr_sym_map_sptr): Likewise. (read_context::fun_entry_addr_sym_map): Likewise. (read_context::var_addr_sym_map): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-dwarf-reader.cc | 1280 +-------------------------------------- 1 file changed, 22 insertions(+), 1258 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 6f792a957076..d90c0a3fe56a 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -1922,92 +1922,6 @@ struct dwarf_expr_eval_context // // --------------------------------------- -/// An enum for the diffent kinds of linux kernel specific symbol -/// tables. -enum kernel_symbol_table_kind -{ - /// This is for an undefined kind of kernel symbol table. - KERNEL_SYMBOL_TABLE_KIND_UNDEFINED, - - /// The __ksymtab symbol table. - KERNEL_SYMBOL_TABLE_KIND_KSYMTAB, - - /// The __ksymtab_gpl symbol table. - KERNEL_SYMBOL_TABLE_KIND_KSYMTAB_GPL -}; - -/// An enum which specifies the format of the kernel symbol table -/// (__ksymtab or __ksymtab_gpl). -enum ksymtab_format -{ - /// This enumerator means that no __ksymtab format has been - /// determined yet. - UNDEFINED_KSYMTAB_FORMAT, - - /// Before Linux v4.19, the format of the __ksymtab (and the - /// __ksymtab_gpl) section was the following. - /// - /// It's an array of entries. Each entry describes a symbol. Each - /// entry is made of two words. each is of the word size of the - /// architecture. (8-bytes on a 64 bits arch and 4-bytes on a 32 - /// bits arch) The first word is the address of a symbol. The - /// second one is the address of a static global variable symbol - /// which value is the string representing the symbol name. That - /// string is in the __ksymtab_strings section. - /// - /// So we are mostly interested in the symbol address part of each - /// entry. - /// - /// Thus this enumerator means that we have the pre v4.19 __ksymtab - /// section format. - PRE_V4_19_KSYMTAB_FORMAT, - - /// Since, Linux v4.19, the format of the __ksymtab section has - /// changed. The commit that changed is - /// https://github.com/torvalds/linux/commit/7290d58095712a89f845e1bca05334796dd49ed2. - /// - /// The __ksymtab and __ksymtab_gpl sections each are an array of - /// entries. Each entry describes a symbol. Each entry is made of - /// two words. Each word is 4-bytes length. The first word is the - /// 'place-relative' address of a symbol. The second one is the - /// 'place-relative' address of a static global variable symbol - /// which value is the string representing the symbol name. That - /// string is in the __ksymtab_strings section. - /// - /// Below is the description of what a "place-relative address" - /// means. For that, we are going to define the meaning of four - /// values: 'N', 'S', 'O', and 'A'. - /// - /// *** 'N' and '0' *** - /// Suppose 'N' is the value of the number stored at offset 'O' (big - /// oh, not zero) in the __ksymtab section. - /// - /// *** 'S'*** - /// That N designates a symbol in the symtab section which value is - /// S. So S is the symbol value (in the .symtab symbol table) - /// referred to by the number N found at offset 'O'. - /// - /// *** 'A' *** - /// Also, suppose the __ksymtab section will be loaded at memory - /// address A, as indicated by the 'address' field of the section - /// header describing the __ksymtab section. - /// - /// So here is the formula that gives us S, from N: - /// - /// S = N + O + A. - /// - /// Storing addresses this way does away with the need to have - /// relocations for the __ksymtab section. So in effect, vmlinux - /// binaries implementing this new format of __ksymtab won't have - /// any .rela__ksymtab relocation section for the __ksymtab section - /// in particular (nor any relocation section at all). - /// - /// - /// Note that we are mostly interested in the symbol address part of - /// each entry. - V4_19_KSYMTAB_FORMAT -}; // end enum ksymtab_format - /// The context used to build ABI corpus from debug info in DWARF /// format. /// @@ -2165,26 +2079,6 @@ public: // ppc64 elf v1 binaries. This section contains the procedure // descriptors on that platform. mutable Elf_Scn* opd_section_; - /// The format of the special __ksymtab section from the linux - /// kernel binary. - mutable ksymtab_format ksymtab_format_; - /// The size of one entry of the __ksymtab section. - mutable size_t ksymtab_entry_size_; - /// The number of entries in the __ksymtab section. - mutable size_t nb_ksymtab_entries_; - /// The number of entries in the __ksymtab_gpl section. - mutable size_t nb_ksymtab_gpl_entries_; - /// The special __ksymtab and __ksymtab_gpl sections from linux - /// kernel or module binaries. The former is used to store - /// references to symbols exported using the EXPORT_SYMBOL macro - /// from the linux kernel. The latter is used to store references - /// to symbols exported using the EXPORT_SYMBOL_GPL macro from the - /// linux kernel. - mutable Elf_Scn* ksymtab_section_; - mutable Elf_Scn* ksymtab_reloc_section_; - mutable Elf_Scn* ksymtab_gpl_section_; - mutable Elf_Scn* ksymtab_gpl_reloc_section_; - mutable Elf_Scn* ksymtab_strings_section_; Dwarf_Die* cur_tu_die_; mutable dwarf_expr_eval_context dwarf_expr_eval_context_; // A set of maps (one per kind of die source) that associates a decl @@ -2267,10 +2161,6 @@ public: string_elf_symbols_map_sptr var_syms_; string_elf_symbols_map_sptr undefined_fun_syms_; string_elf_symbols_map_sptr undefined_var_syms_; - address_set_sptr linux_exported_fn_syms_; - address_set_sptr linux_exported_var_syms_; - address_set_sptr linux_exported_gpl_fn_syms_; - address_set_sptr linux_exported_gpl_var_syms_; vector dt_needed_; string dt_soname_; string elf_architecture_; @@ -2369,15 +2259,6 @@ public: elf_path_ = elf_path; symtab_section_ = 0; opd_section_ = 0; - ksymtab_format_ = UNDEFINED_KSYMTAB_FORMAT; - ksymtab_entry_size_ = 0; - nb_ksymtab_entries_ = 0; - nb_ksymtab_gpl_entries_ = 0; - ksymtab_section_ = 0; - ksymtab_reloc_section_ = 0; - ksymtab_gpl_section_ = 0; - ksymtab_gpl_reloc_section_ = 0; - ksymtab_strings_section_ = 0; cur_tu_die_ = 0; exported_decls_builder_ = 0; @@ -2423,10 +2304,6 @@ public: var_syms_.reset(); undefined_fun_syms_.reset(); undefined_var_syms_.reset(); - linux_exported_fn_syms_.reset(); - linux_exported_var_syms_.reset(); - linux_exported_gpl_fn_syms_.reset(); - linux_exported_gpl_var_syms_.reset(); dt_needed_.clear(); dt_soname_.clear(); elf_architecture_.clear(); @@ -5070,97 +4947,6 @@ public: return opd_section_; } - /// Return the __ksymtab section of a linux kernel ELF file (either - /// a vmlinux binary or a kernel module). - /// - /// @return the __ksymtab section if found, nil otherwise. - Elf_Scn* - find_ksymtab_section() const - { - if (!ksymtab_section_) - ksymtab_section_ = elf_helpers::find_ksymtab_section(elf_handle()); - return ksymtab_section_; - } - - /// Return the __ksymtab_gpl section of a linux kernel ELF file - /// (either a vmlinux binary or a kernel module). - /// - /// @return the __ksymtab_gpl section if found, nil otherwise. - Elf_Scn* - find_ksymtab_gpl_section() const - { - if (!ksymtab_gpl_section_) - ksymtab_gpl_section_ = - elf_helpers::find_ksymtab_gpl_section(elf_handle()); - return ksymtab_gpl_section_; - } - - /// Return the .rel{a,}__ksymtab section of a linux kernel ELF file (either - /// a vmlinux binary or a kernel module). - /// - /// @return the .rel{a,}__ksymtab section if found, nil otherwise. - Elf_Scn* - find_ksymtab_reloc_section() const - { - if (!ksymtab_reloc_section_) - ksymtab_reloc_section_ = - find_relocation_section(elf_handle(), find_ksymtab_section()); - return ksymtab_reloc_section_; - } - - /// Return the .rel{a,}__ksymtab_gpl section of a linux kernel ELF file - /// (either a vmlinux binary or a kernel module). - /// - /// @return the .rel{a,}__ksymtab_gpl section if found, nil otherwise. - Elf_Scn* - find_ksymtab_gpl_reloc_section() const - { - if (!ksymtab_gpl_reloc_section_) - ksymtab_gpl_reloc_section_ = - find_relocation_section(elf_handle(), find_ksymtab_gpl_section()); - return ksymtab_gpl_reloc_section_; - } - - /// Return the __ksymtab_strings section of a linux kernel ELF file - /// (either a vmlinux binary or a kernel module). - /// - /// @return the __ksymtab_strings section if found, nil otherwise. - Elf_Scn* - find_ksymtab_strings_section() const - { - if (!ksymtab_strings_section_) - ksymtab_strings_section_ = - dwarf_reader::find_ksymtab_strings_section(elf_handle()); - return ksymtab_strings_section_; - } - - /// Return either a __ksymtab or a __ksymtab_gpl section, in case - /// only the __ksymtab_gpl exists. - /// - /// @return the __ksymtab section if it exists, or the - /// __ksymtab_gpl; or NULL if neither is found. - Elf_Scn* - find_any_ksymtab_section() const - { - Elf_Scn *result = find_ksymtab_section(); - if (!result) - result = find_ksymtab_gpl_section(); - return result; - } - - /// Return either a .rel{a,}__ksymtab or a .rel{a,}__ksymtab_gpl section - /// - /// @return the .rel{a,}__ksymtab section if it exists, or the - /// .rel{a,}__ksymtab_gpl; or NULL if neither is found. - Elf_Scn* - find_any_ksymtab_reloc_section() const - { - Elf_Scn *result = find_ksymtab_reloc_section(); - if (!result) - result = find_ksymtab_gpl_reloc_section(); - return result; - } - /// Lookup an elf symbol, referred to by its index, from the .symtab /// section. /// @@ -5256,7 +5042,7 @@ public: elf_symbol::visibility vis = stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(native_sym.st_other)); - Elf_Scn *strings_section = find_ksymtab_strings_section(); + Elf_Scn* strings_section = find_ksymtab_strings_section(elf_handle()); size_t strings_ndx = strings_section ? elf_ndxscn(strings_section) : 0; @@ -5418,92 +5204,6 @@ public: return result; } - /// Given the address of the beginning of a function, lookup the - /// symbol of the function, build an instance of @ref elf_symbol out - /// of it and return it. - /// - /// @param symbol_start_addr the address of the beginning of the - /// function to consider. - /// - /// @param sym the resulting symbol. This is set iff the function - /// returns true. - /// - /// @return the elf symbol found at address @p symbol_start_addr, or - /// nil if none was found. - elf_symbol_sptr - lookup_elf_fn_symbol_from_address(GElf_Addr symbol_start_addr) const - { - addr_elf_symbol_sptr_map_type::const_iterator i, - nil = fun_entry_addr_sym_map().end(); - - if ((i = fun_entry_addr_sym_map().find(symbol_start_addr)) == nil) - return elf_symbol_sptr(); - - return i->second; - } - - /// Given the address of a global variable, lookup the symbol of the - /// variable, build an instance of @ref elf_symbol out of it and - /// return it. - /// - /// @param symbol_start_addr the address of the beginning of the - /// variable to consider. - /// - /// @param the symbol found, iff the function returns true. - /// - /// @return the elf symbol found or nil if none was found. - elf_symbol_sptr - lookup_elf_var_symbol_from_address(GElf_Addr symbol_start_addr) const - { - addr_elf_symbol_sptr_map_type::const_iterator i, - nil = var_addr_sym_map().end(); - - if ((i = var_addr_sym_map().find(symbol_start_addr)) == nil) - return elf_symbol_sptr(); - - return i->second; - } - - /// Lookup an elf symbol, knowing its address. - /// - /// This function first looks for a function symbol having this - /// address; if it doesn't find any, then it looks for a variable - /// symbol. - /// - /// @param symbol_addr the address of the symbol of the symbol we - /// are looking for. Note that the address is a relative offset - /// starting from the beginning of the .text section. Addresses - /// that are presen in the symbol table (the one named .symtab). - /// - /// @return the elf symbol if found, or nil otherwise. - elf_symbol_sptr - lookup_elf_symbol_from_address(GElf_Addr symbol_addr) const - { - elf_symbol_sptr result = lookup_elf_fn_symbol_from_address(symbol_addr); - if (!result) - result = lookup_elf_var_symbol_from_address(symbol_addr); - return result; - } - - /// Look in the symbol tables of the underying elf file and see if - /// we find a symbol of a given name of function type. - /// - /// @param sym_name the name of the symbol to look for. - /// - /// @param syms the public function symbols that were found, with - /// the name @p sym_name. - /// - /// @return true iff the symbol was found. - bool - lookup_public_function_symbol_from_elf(const string& sym_name, - vector& syms) - { - return dwarf_reader::lookup_public_function_symbol_from_elf(env(), - elf_handle(), - sym_name, - syms); - } - /// Test if a given function symbol has been exported. /// /// @param symbol_address the address of the symbol we are looking @@ -5603,20 +5303,6 @@ public: return fun_addr_sym_map_; } - /// Getter for a pointer to the map that associates the address of - /// an entry point of a function with the symbol of that function. - /// - /// Note that on non-"PPC64 ELFv1" binaries, this map is the same as - /// the one that assciates the address of a function with the symbol - /// of that function. - /// - /// @return a pointer to the map that associates the address of an - /// entry point of a function with the symbol of that function. - const addr_elf_symbol_sptr_map_sptr& - fun_entry_addr_sym_map_sptr() const - {return const_cast(this)->fun_entry_addr_sym_map_sptr();} - - /// Getter for the map that associates the address of an entry point /// of a function with the symbol of that function. /// @@ -5630,19 +5316,6 @@ public: fun_entry_addr_sym_map() {return *fun_entry_addr_sym_map_sptr();} - /// Getter for the map that associates the address of an entry point - /// of a function with the symbol of that function. - /// - /// Note that on non-"PPC64 ELFv1" binaries, this map is the same as - /// the one that assciates the address of a function with the symbol - /// of that function. - /// - /// @return the map that associates the address of an entry point of - /// a function with the symbol of that function. - const addr_elf_symbol_sptr_map_type& - fun_entry_addr_sym_map() const - { return *fun_entry_addr_sym_map_sptr();} - /// Getter for the map of function symbols (name -> sym). /// /// @return a shared pointer to the map of function symbols. @@ -5707,130 +5380,6 @@ public: return undefined_var_syms_; } - /// Getter for the set of addresses of function symbols that are - /// explicitely exported, for a linux kernel (module) binary. These - /// are the addresses of function symbols present in the __ksymtab - /// section - address_set_sptr& - linux_exported_fn_syms() - {return linux_exported_fn_syms_;} - - /// Getter for the set of addresses of functions that are - /// explicitely exported, for a linux kernel (module) binary. These - /// are the addresses of function symbols present in the __ksymtab - /// section. - /// - /// @return the set of addresses of exported function symbols. - const address_set_sptr& - linux_exported_fn_syms() const - {return const_cast(this)->linux_exported_fn_syms();} - - /// Create an empty set of addresses of functions exported from a - /// linux kernel (module) binary, or return the one that already - /// exists. - /// - /// @return the set of addresses of exported function symbols. - address_set_sptr& - create_or_get_linux_exported_fn_syms() - { - if (!linux_exported_fn_syms_) - linux_exported_fn_syms_.reset(new address_set_type); - return linux_exported_fn_syms_; - } - - /// Getter for the set of addresses of v ariables that are - /// explicitely exported, for a linux kernel (module) binary. These - /// are the addresses of variable symbols present in the __ksymtab - /// section. - /// - /// @return the set of addresses of exported variable symbols. - address_set_sptr& - linux_exported_var_syms() - {return linux_exported_var_syms_;} - - /// Getter for the set of addresses of variables that are - /// explicitely exported, for a linux kernel (module) binary. These - /// are the addresses of variable symbols present in the __ksymtab - /// section. - /// - /// @return the set of addresses of exported variable symbols. - const address_set_sptr& - linux_exported_var_syms() const - {return const_cast(this)->linux_exported_var_syms();} - - - /// Create an empty set of addresses of variables exported from a - /// linux kernel (module) binary, or return the one that already - /// exists. - /// - /// @return the set of addresses of exported variable symbols. - address_set_sptr& - create_or_get_linux_exported_var_syms() - { - if (!linux_exported_var_syms_) - linux_exported_var_syms_.reset(new address_set_type); - return linux_exported_var_syms_; - } - - - /// Getter for the set of addresses of function symbols that are - /// explicitely exported as GPL, for a linux kernel (module) binary. - /// These are the addresses of function symbols present in the - /// __ksymtab_gpl section. - address_set_sptr& - linux_exported_gpl_fn_syms() - {return linux_exported_gpl_fn_syms_;} - - /// Getter for the set of addresses of function symbols that are - /// explicitely exported as GPL, for a linux kernel (module) binary. - /// These are the addresses of function symbols present in the - /// __ksymtab_gpl section. - const address_set_sptr& - linux_exported_gpl_fn_syms() const - {return const_cast(this)->linux_exported_gpl_fn_syms();} - - /// Create an empty set of addresses of GPL functions exported from - /// a linux kernel (module) binary, or return the one that already - /// exists. - /// - /// @return the set of addresses of exported function symbols. - address_set_sptr& - create_or_get_linux_exported_gpl_fn_syms() - { - if (!linux_exported_gpl_fn_syms_) - linux_exported_gpl_fn_syms_.reset(new address_set_type); - return linux_exported_gpl_fn_syms_; - } - - /// Getter for the set of addresses of variable symbols that are - /// explicitely exported as GPL, for a linux kernel (module) binary. - /// These are the addresses of variable symbols present in the - /// __ksymtab_gpl section. - address_set_sptr& - linux_exported_gpl_var_syms() - {return linux_exported_gpl_var_syms_;} - - /// Getter for the set of addresses of variable symbols that are - /// explicitely exported as GPL, for a linux kernel (module) binary. - /// These are the addresses of variable symbols present in the - /// __ksymtab_gpl section. - const address_set_sptr& - linux_exported_gpl_var_syms() const - {return const_cast(this)->linux_exported_gpl_var_syms();} - - /// Create an empty set of addresses of GPL variables exported from - /// a linux kernel (module) binary, or return the one that already - /// exists. - /// - /// @return the set of addresses of exported variable symbols. - address_set_sptr& - create_or_get_linux_exported_gpl_var_syms() - { - if (!linux_exported_gpl_var_syms_) - linux_exported_gpl_var_syms_.reset(new address_set_type); - return linux_exported_gpl_var_syms_; - } - /// Getter for the ELF dt_needed tag. const vector& dt_needed() const @@ -5846,28 +5395,6 @@ public: elf_architecture() const {return elf_architecture_;} - /// Getter for the map of global variables symbol address -> global - /// variable symbol index. - /// - /// @return the map. Note that this initializes the map once when - /// its nedded. - const addr_elf_symbol_sptr_map_type& - var_addr_sym_map() const - {return const_cast(this)->var_addr_sym_map();} - - /// Getter for the map of global variables symbol address -> global - /// variable symbol index. - /// - /// @return the map. Note that this initializes the map once when - /// its nedded. - addr_elf_symbol_sptr_map_type& - var_addr_sym_map() - { - if (!var_addr_sym_map_) - maybe_load_symbol_maps(); - return *var_addr_sym_map_; - } - /// Load the maps address -> function symbol, address -> variable /// symbol and the maps of function and variable undefined symbols. /// @@ -6092,364 +5619,6 @@ public: return true; } - /// Try reading the first __ksymtab section entry. - /// - /// We lookup the symbol from the raw section passed as an argument. For - /// that, consider endianess and adjust for potential Elf relocations before - /// looking up the symbol in the .symtab section. - // - /// Optionally, support position relative relocations by considering the - /// ksymtab entry as 32 bit and applying the relocation relative to the - /// section header (i.e. the symbol position as we are reading the first - /// symbol). - /// - /// @param section the ksymtab section to consider. - /// - /// @param position_relative_relocations if true, then consider that - /// the section designated by @p section contains position-relative - /// relocated symbol addresses. - /// - /// @param symbol_offset if different from zero - /// If symbol_offset is != 0, adjust the position we consider the section - /// start. That is useful to read the ksymtab with a slight offset. - /// - /// Note, this function does not support relocatable ksymtab entries (as for - /// example in kernel modules). Using this function for ksymtabs where - /// relocations need to be applied for the entries we are reading here, will - /// yield wrong results. - /// - /// @return the symbol resulting from the lookup of the symbol address we - /// got from reading the first entry of the ksymtab or null if no such entry - /// could be found. - elf_symbol_sptr - try_reading_first_ksymtab_entry(Elf_Scn* section, - bool position_relative_relocations, - int symbol_offset = 0) const - { - Elf_Data* elf_data = elf_rawdata(section, 0); - uint8_t* bytes = reinterpret_cast(elf_data->d_buf); - bool is_big_endian = architecture_is_big_endian(elf_handle()); - elf_symbol_sptr symbol; - GElf_Addr symbol_address = 0; - - unsigned char symbol_value_size; - if (position_relative_relocations) - symbol_value_size = sizeof(int32_t); - else - symbol_value_size = get_architecture_word_size(elf_handle()); - - const int read_offset = (symbol_offset * symbol_value_size); - bytes += read_offset; - - if (position_relative_relocations) - { - int32_t offset = 0; - ABG_ASSERT(read_int_from_array_of_bytes(bytes, symbol_value_size, - is_big_endian, offset)); - GElf_Shdr section_header; - gelf_getshdr(section, §ion_header); - // the actual symbol address is relative to its position. Since we do - // not know the position, we take the beginning of the section, add the - // read_offset that we might have and finally apply the offset we - // read from the section. - symbol_address = section_header.sh_addr + read_offset + offset; - } - else - ABG_ASSERT(read_int_from_array_of_bytes(bytes, symbol_value_size, - is_big_endian, symbol_address)); - - symbol_address = maybe_adjust_fn_sym_address(symbol_address); - symbol = lookup_elf_symbol_from_address(symbol_address); - return symbol; - } - - /// Try reading the first __ksymtab section entry as if it is in the - /// pre-v4_19 format, that is without position relative relocations. - /// - /// @return the symbol resulting from the lookup of the symbol - /// address we got from reading the first entry of the ksymtab - /// section assuming the pre-v4.19 format. If null, it means the - /// __ksymtab section is not in the pre-v4.19 format. - elf_symbol_sptr - try_reading_first_ksymtab_entry_using_pre_v4_19_format() const - { - Elf_Scn *section = find_any_ksymtab_section(); - return try_reading_first_ksymtab_entry(section, false); - } - - /// Try reading the first __ksymtab section entry as if it is in the - /// v4_19 format, that is with position relative relocations. - /// - /// @return the symbol resulting from the lookup of the symbol - /// address we got from reading the first entry of the ksymtab - /// section assuming the v4.19 format. If null, it means the - /// __ksymtab section is not in the v4.19 format. - elf_symbol_sptr - try_reading_first_ksymtab_entry_using_v4_19_format() const - { - Elf_Scn *section = find_any_ksymtab_section(); - return try_reading_first_ksymtab_entry(section, true); - } - - /// Try to determine the format of the __ksymtab and __ksymtab_gpl - /// sections of Linux kernel modules. - /// - /// This is important because we need to know the format of these - /// sections to be able to read from them. - /// - /// @return the format the __ksymtab[_gpl] sections. - enum ksymtab_format - get_ksymtab_format_module() const - { - Elf_Scn *section = find_any_ksymtab_reloc_section(); - - ABG_ASSERT(section); - - // Libdwfl has a weird quirk where, in the process of obtaining an Elf - // descriptor via dwfl_module_getelf(), it will apply all relocations it - // knows how to and it will zero the relocation info after applying it. If - // the .rela__ksymtab* section contained only simple (absolute) relocations, - // they will have been all applied and sh_size will be 0. For arches that - // support relative ksymtabs, simple relocations only appear in pre-4.19 - // kernel modules. - GElf_Shdr section_mem; - GElf_Shdr *section_shdr = gelf_getshdr(section, §ion_mem); - if (section_shdr->sh_size == 0) - return PRE_V4_19_KSYMTAB_FORMAT; - - bool is_relasec = (section_shdr->sh_type == SHT_RELA); - - // If we still have a normal non-zeroed relocation section, we can guess - // what format the ksymtab is in depending on what types of relocs it - // contains. - - uint64_t type; - Elf_Data *section_data = elf_getdata(section, 0); - if (is_relasec) - { - GElf_Rela rela; - gelf_getrela(section_data, 0, &rela); - type = GELF_R_TYPE(rela.r_info); - } - else - { - GElf_Rel rel; - gelf_getrel(section_data, 0, &rel); - type = GELF_R_TYPE(rel.r_info); - } - - // Sigh, I dislike the arch-dependent code here, but this seems to be a - // reliable heuristic for kernel modules for now. Relative ksymtabs only - // supported on x86 and arm64 as of v4.19. - ksymtab_format format; - switch (type) - { - case R_X86_64_64: // Same as R_386_32, fallthrough -#ifdef HAVE_R_AARCH64_ABS64_MACRO - case R_AARCH64_ABS64: -#endif - format = PRE_V4_19_KSYMTAB_FORMAT; - break; - case R_X86_64_PC32: // Same as R_386_PC32, fallthrough -#ifdef HAVE_R_AARCH64_PREL32_MACRO - case R_AARCH64_PREL32: -#endif - format = V4_19_KSYMTAB_FORMAT; - break; - default: - // Fall back to other methods of determining the ksymtab format. - format = UNDEFINED_KSYMTAB_FORMAT; - break; - } - return format; - } - - /// Determine the format of the __ksymtab and __ksymtab_gpl - /// sections. - /// - /// This is important because we need the know the format of these - /// sections to be able to read from them. - /// - /// @return the format the __ksymtab[_gpl] sections. - enum ksymtab_format - get_ksymtab_format() const - { - if (!find_any_ksymtab_section()) - ksymtab_format_ = UNDEFINED_KSYMTAB_FORMAT; - else - { - if (ksymtab_format_ == UNDEFINED_KSYMTAB_FORMAT) - { - // Since Linux kernel modules are relocatable, we can first try - // using a heuristic based on relocations to guess the ksymtab format. - if (is_linux_kernel_module(elf_handle())) - { - ksymtab_format_ = get_ksymtab_format_module(); - if (ksymtab_format_ != UNDEFINED_KSYMTAB_FORMAT) - return ksymtab_format_; - } - - // If it's not a kernel module or we couldn't determine its format - // with relocations, fall back to the heuristics below. - - // OK this is a dirty little heuristic to determine the - // format of the ksymtab section. - // - // We try to read the first ksymtab entry assuming a - // pre-v4.19 format. If that succeeds then we are in the - // pr-v4.19 format. Otherwise, try reading it assuming a - // v4.19 format. For now, we just support - // PRE_V4_19_KSYMTAB_FORMAT and V4_19_KSYMTAB_FORMAT. - if (try_reading_first_ksymtab_entry_using_pre_v4_19_format()) - ksymtab_format_ = PRE_V4_19_KSYMTAB_FORMAT; - else if (try_reading_first_ksymtab_entry_using_v4_19_format()) - ksymtab_format_ = V4_19_KSYMTAB_FORMAT; - else - // If a new format emerges, then we need to add its - // support above. - ABG_ASSERT_NOT_REACHED; - } - } - return ksymtab_format_; - } - - /// Getter of the size of the symbol value part of an entry of the - /// ksymtab section. - /// - /// @return the size of the symbol value part of the entry of the - /// ksymtab section. - unsigned char - get_ksymtab_symbol_value_size() const - { - unsigned char result = 0; - ksymtab_format format = get_ksymtab_format(); - if (format == UNDEFINED_KSYMTAB_FORMAT) - ; - else if (format == PRE_V4_19_KSYMTAB_FORMAT) - result = get_architecture_word_size(elf_handle()); - else if (format == V4_19_KSYMTAB_FORMAT) - result = 4; - else - ABG_ASSERT_NOT_REACHED; - - return result; - } - - /// Getter of the size of one entry of the ksymtab section. - /// - /// @return the size of one entry of the ksymtab section. - unsigned char - get_ksymtab_entry_size() const - { - if (ksymtab_entry_size_ == 0) - { - const unsigned char symbol_size = get_ksymtab_symbol_value_size(); - Elf_Scn* ksymtab = find_any_ksymtab_section(); - if (ksymtab) - { - GElf_Shdr ksymtab_shdr; - gelf_getshdr(ksymtab, &ksymtab_shdr); - - // ksymtab entries have the following layout - // - // struct { - // T symbol_address; // .symtab entry - // T name_address; // .strtab entry - // } - // - // with T being a suitable type to represent the absolute, - // relocatable or position relative value of the address. T's size - // is determined by get_ksymtab_symbol_value_size(). - // - // Since Kernel v5.4, the entries have the following layout - // - // struct { - // T symbol_address; // .symtab entry - // T name_address; // .strtab entry - // T namespace; // .strtab entry - // } - // - // To determine the ksymtab entry size, find the next entry that - // refers to a valid .symtab entry. The offset to that one is what - // we are searching for. - for (unsigned entries = 2; entries <= 3; ++entries) - { - const unsigned candidate_size = entries * symbol_size; - - // if there is exactly one entry, section size == entry size - // (this looks like an optimization, but in fact it prevents - // from illegal reads if there is actually only one entry) - if (ksymtab_shdr.sh_size == candidate_size) - { - ksymtab_entry_size_ = candidate_size; - break; - } - - // otherwise check whether the symbol following the candidate - // number of entries is a valid ELF symbol. For that we read - // the ksymtab with the given offset and if the symbol is - // valid, we found our entry size. - const ksymtab_format format = get_ksymtab_format(); - if (try_reading_first_ksymtab_entry - (ksymtab, format == V4_19_KSYMTAB_FORMAT, entries)) - { - ksymtab_entry_size_ = candidate_size; - break; - } - } - ABG_ASSERT(ksymtab_entry_size_ != 0); - } - } - - return ksymtab_entry_size_; - } - - /// Getter of the number of entries that are present in the ksymtab - /// section. - /// - /// @return the number of entries that are present in the ksymtab - /// section. - size_t - get_nb_ksymtab_entries() const - { - if (nb_ksymtab_entries_ == 0) - { - Elf_Scn *section = find_ksymtab_section(); - if (section) - { - GElf_Shdr header_mem; - GElf_Shdr *section_header = gelf_getshdr(section, &header_mem); - size_t entry_size = get_ksymtab_entry_size(); - ABG_ASSERT(entry_size); - nb_ksymtab_entries_ = section_header->sh_size / entry_size; - } - } - return nb_ksymtab_entries_; - } - - /// Getter of the number of entries that are present in the - /// ksymtab_gpl section. - /// - /// @return the number of entries that are present in the - /// ksymtab_gpl section. - size_t - get_nb_ksymtab_gpl_entries() - { - if (nb_ksymtab_gpl_entries_ == 0) - { - Elf_Scn *section = find_ksymtab_gpl_section(); - if (section) - { - GElf_Shdr header_mem; - GElf_Shdr *section_header = gelf_getshdr(section, &header_mem); - size_t entry_size = get_ksymtab_entry_size(); - ABG_ASSERT(entry_size); - nb_ksymtab_gpl_entries_ = section_header->sh_size / entry_size; - } - } - return nb_ksymtab_gpl_entries_; - } - /// Test if a given ELF symbol was suppressed by a suppression /// specification. /// @@ -6465,328 +5634,6 @@ public: symbol->get_type())); } - /// Populate the symbol map by reading exported symbols from the - /// ksymtab directly. - /// - /// @param section the ksymtab section to read from - /// - /// @param exported_fns_set the set of exported functions - /// - /// @param exported_vars_set the set of exported variables - /// - /// @param nb_entries the number of ksymtab entries to read - /// - /// @return true upon successful completion, false otherwise. - bool - populate_symbol_map_from_ksymtab(Elf_Scn *section, - address_set_sptr exported_fns_set, - address_set_sptr exported_vars_set, - size_t nb_entries) - { - // The data of the section. - Elf_Data *elf_data = elf_rawdata(section, 0); - - // An array-of-bytes view of the elf data above. Something we can - // actually program with. Phew. - uint8_t *bytes = reinterpret_cast(elf_data->d_buf); - - // This is where to store an address of a symbol that we read from - // the section. - GElf_Addr symbol_address = 0, adjusted_symbol_address = 0; - - // So the section is an array of entries. Each entry describes a - // symbol. Each entry is made of two words. - // - // The first word is the address of a symbol. The second one is - // the address of a static global variable symbol which value is - // the string representing the symbol name. That string is in the - // __ksymtab_strings section. Here, we are only interested in the - // first entry. - // - // Lets thus walk the array of entries, and let's read just the - // symbol address part of each entry. - bool is_big_endian = architecture_is_big_endian(elf_handle()); - elf_symbol_sptr symbol; - unsigned char symbol_value_size = get_ksymtab_symbol_value_size(); - - for (size_t i = 0, entry_offset = 0; - i < nb_entries; - ++i, entry_offset = get_ksymtab_entry_size() * i) - { - symbol_address = 0; - ABG_ASSERT(read_int_from_array_of_bytes(&bytes[entry_offset], - symbol_value_size, - is_big_endian, - symbol_address)); - - // Starting from linux kernel v4.19, it can happen that the - // address value read from the ksymtab[_gpl] section might - // need some decoding to get the real symbol address that has - // a meaning in the .symbol section. - symbol_address = - maybe_adjust_sym_address_from_v4_19_ksymtab(symbol_address, - entry_offset, section); - - // We might also want to adjust the symbol address, depending - // on if we are looking at an ET_REL, an executable or a - // shared object binary. - adjusted_symbol_address = maybe_adjust_fn_sym_address(symbol_address); - - if (adjusted_symbol_address == 0) - // The resulting symbol address is zero, not sure this - // valid; ignore it. - continue; - - // OK now the symbol address should be in a suitable form to - // be used to look the symbol up in the usual .symbol section - // (aka ELF symbol table). - symbol = lookup_elf_symbol_from_address(adjusted_symbol_address); - if (!symbol) - { - adjusted_symbol_address = - maybe_adjust_var_sym_address(symbol_address); - symbol = lookup_elf_symbol_from_address(adjusted_symbol_address); - if (!symbol) - // This must be a symbol that is of type neither FUNC - // (function) nor OBJECT (variable). There are for intance, - // symbols of type 'NOTYPE' in the ksymtab symbol table. I - // am not sure what those are. - continue; - } - - // If the symbol was suppressed by a suppression - // specification then drop it on the floor. - if (is_elf_symbol_suppressed(symbol)) - continue; - - address_set_sptr set; - if (symbol->is_function()) - { - ABG_ASSERT(lookup_elf_fn_symbol_from_address - (adjusted_symbol_address)); - set = exported_fns_set; - } - else if (symbol->is_variable()) - { - ABG_ASSERT(lookup_elf_var_symbol_from_address - (adjusted_symbol_address)); - set = exported_vars_set; - } - else - ABG_ASSERT_NOT_REACHED; - set->insert(adjusted_symbol_address); - } - return true; - } - - /// Populate the symbol map by extracting the exported symbols from a - /// ksymtab rela section. - /// - /// @param section the ksymtab section to read from - /// - /// @param exported_fns_set the set of exported functions - /// - /// @param exported_vars_set the set of exported variables - /// - /// @return true upon successful completion, false otherwise. - bool - populate_symbol_map_from_ksymtab_reloc(Elf_Scn *reloc_section, - address_set_sptr exported_fns_set, - address_set_sptr exported_vars_set) - { - GElf_Shdr reloc_section_mem; - GElf_Shdr *reloc_section_shdr = gelf_getshdr(reloc_section, - &reloc_section_mem); - size_t reloc_count = - reloc_section_shdr->sh_size / reloc_section_shdr->sh_entsize; - - Elf_Data *reloc_section_data = elf_getdata(reloc_section, 0); - - bool is_relasec = (reloc_section_shdr->sh_type == SHT_RELA); - elf_symbol_sptr symbol; - GElf_Sym native_symbol; - for (unsigned int i = 0; i < reloc_count; i++) - { - if (is_relasec) - { - GElf_Rela rela; - gelf_getrela(reloc_section_data, i, &rela); - symbol = lookup_elf_symbol_from_index(GELF_R_SYM(rela.r_info), - native_symbol); - } - else - { - GElf_Rel rel; - gelf_getrel(reloc_section_data, i, &rel); - symbol = lookup_elf_symbol_from_index(GELF_R_SYM(rel.r_info), - native_symbol); - } - - ABG_ASSERT(symbol); - - // If the symbol is a linux string constant then ignore it. - if (symbol->get_is_linux_string_cst()) - continue; - - if (!symbol->is_function() && !symbol->is_variable()) - { - if (do_log()) - { - if (symbol->get_type() == elf_symbol::NOTYPE_TYPE) - cerr << "skipping NOTYPE symbol " - << symbol->get_name() - << " shndx: " - << symbol->get_index() - << " @" - << elf_path() - << "\n"; - else if (symbol->get_type() == elf_symbol::SECTION_TYPE) - cerr << "skipping SECTION symbol " - << "shndx: " - << symbol->get_index() - << " @" - << elf_path() - << "\n"; - } - continue; - } - - // If the symbol was suppressed by a suppression - // specification then drop it on the floor. - if (is_elf_symbol_suppressed(symbol)) - continue; - - // If we are looking at an ET_REL (relocatable) binary, then - // the symbol value of native_symbol is relative to the - // section that symbol is defined in. We need to translate it - // into an absolute (okay, binary-relative, rather) address. - GElf_Addr symbol_address = - maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle(), - &native_symbol); - - address_set_sptr set; - if (symbol->is_function()) - { - ABG_ASSERT(lookup_elf_fn_symbol_from_address(symbol_address)); - set = exported_fns_set; - } - else if (symbol->is_variable()) - { - ABG_ASSERT(lookup_elf_var_symbol_from_address(symbol_address)); - set = exported_vars_set; - } - else - ABG_ASSERT_NOT_REACHED; - set->insert(symbol_address); - } - return true; - } - - /// Load a given kernel symbol table. - /// - /// One can thus retrieve the resulting symbols by using the - /// accessors read_context::linux_exported_fn_syms(), - /// read_context::linux_exported_var_syms(), - /// read_context::linux_exported_gpl_fn_syms(), or - /// read_context::linux_exported_gpl_var_syms(). - /// - /// @param kind the kind of kernel symbol table to load. - /// - /// @return true upon successful completion, false otherwise. - bool - load_kernel_symbol_table(kernel_symbol_table_kind kind) - { - Elf_Scn *section = 0, *reloc_section = 0; - address_set_sptr linux_exported_fns_set, linux_exported_vars_set; - - switch (kind) - { - case KERNEL_SYMBOL_TABLE_KIND_UNDEFINED: - break; - case KERNEL_SYMBOL_TABLE_KIND_KSYMTAB: - section = find_ksymtab_section(); - reloc_section = find_ksymtab_reloc_section(); - linux_exported_fns_set = create_or_get_linux_exported_fn_syms(); - linux_exported_vars_set = create_or_get_linux_exported_var_syms(); - break; - case KERNEL_SYMBOL_TABLE_KIND_KSYMTAB_GPL: - section = find_ksymtab_gpl_section(); - reloc_section = find_ksymtab_gpl_reloc_section(); - linux_exported_fns_set = create_or_get_linux_exported_gpl_fn_syms(); - linux_exported_vars_set = create_or_get_linux_exported_gpl_var_syms(); - break; - } - - if (!linux_exported_vars_set || !linux_exported_fns_set || !section) - return false; - - ksymtab_format format = get_ksymtab_format(); - - // Although pre-v4.19 kernel modules can have a relocation section for the - // __ksymtab section, libdwfl zeroes the rela section after applying - // "simple" absolute relocations via dwfl_module_getelf(). For v4.19 and - // above, we get PC-relative relocations so dwfl_module_getelf() doesn't - // apply those relocations and we're safe to read the relocation section to - // determine which exported symbols are in the ksymtab. - if (!reloc_section || format == PRE_V4_19_KSYMTAB_FORMAT) - { - size_t nb_entries = 0; - if (kind == KERNEL_SYMBOL_TABLE_KIND_KSYMTAB) - nb_entries = get_nb_ksymtab_entries(); - else if (kind == KERNEL_SYMBOL_TABLE_KIND_KSYMTAB_GPL) - nb_entries = get_nb_ksymtab_gpl_entries(); - - if (!nb_entries) - return false; - - return populate_symbol_map_from_ksymtab( - section, linux_exported_fns_set, linux_exported_vars_set, - nb_entries); - } - else - return populate_symbol_map_from_ksymtab_reloc(reloc_section, - linux_exported_fns_set, - linux_exported_vars_set); - } - - /// Load the special __ksymtab section. This is for linux kernel - /// (module) files. - /// - /// @return true upon successful completion, false otherwise. - bool - load_ksymtab_symbols() - { - return load_kernel_symbol_table(KERNEL_SYMBOL_TABLE_KIND_KSYMTAB); - } - - /// Load the special __ksymtab_gpl section. This is for linux kernel - /// (module) files. - /// - /// @return true upon successful completion, false otherwise. - bool - load_ksymtab_gpl_symbols() - { - return load_kernel_symbol_table(KERNEL_SYMBOL_TABLE_KIND_KSYMTAB_GPL); - } - - /// Load linux kernel (module) specific exported symbol sections. - /// - /// @return true upon successful completion, false otherwise. - bool - load_linux_specific_exported_symbol_maps() - { - bool loaded = false; - if (!linux_exported_fn_syms_ - || !linux_exported_var_syms_) - loaded |= load_ksymtab_symbols(); - - if (!linux_exported_gpl_fn_syms_ - || !linux_exported_gpl_var_syms_) - loaded |= load_ksymtab_gpl_symbols(); - - return loaded; - } - /// Load the maps of function symbol address -> function symbol, /// global variable symbol address -> variable symbol and also the /// maps of function and variable undefined symbols. @@ -6829,11 +5676,7 @@ public: load_var_map, load_undefined_fun_map, load_undefined_var_map)) - { - if (load_in_linux_kernel_mode() && is_linux_kernel(elf_handle())) - return load_linux_specific_exported_symbol_maps(); return true; - } return false; } return true; @@ -6913,36 +5756,6 @@ public: load_elf_architecture(); } - /// Convert the value of the symbol address part of a post V4.19 - /// ksymtab entry (that contains place-relative addresses) into its - /// corresponding symbol value in the .symtab section. The value of - /// the symbol in .symtab equals to addr_offset + address-of-ksymtab - /// + addr. - /// - /// @param addr the address read from the ksymtab section. - /// - /// @param addr_offset the offset at which @p addr was read. - /// - /// @param ksymtab_section the kymstab section @p addr was read - /// from. - GElf_Addr - maybe_adjust_sym_address_from_v4_19_ksymtab(GElf_Addr addr, - size_t addr_offset, - Elf_Scn *ksymtab_section) const - { - GElf_Addr result = addr; - - if (get_ksymtab_format() == V4_19_KSYMTAB_FORMAT) - { - int32_t offset = addr; - GElf_Shdr mem; - GElf_Shdr *section_header = gelf_getshdr(ksymtab_section, &mem); - result = offset + section_header->sh_addr + addr_offset; - } - - return result; - } - /// This is a sub-routine of maybe_adjust_fn_sym_address and /// maybe_adjust_var_sym_address. /// @@ -15374,34 +14187,6 @@ build_function_decl(read_context& ctxt, return result; } -/// Add a set of addresses (representing function symbols) to a -/// function symbol name -> symbol map. -/// -/// For a given symbol address, the function retrieves the name of the -/// symbol as well as the symbol itself and inserts an entry {symbol -/// name, symbol} into a map of symbol name -> symbol map. -/// -/// @param syms the set of symbol addresses to consider. -/// -/// @param map the map to populate. -/// -/// @param ctxt the context in which we are loading a given ELF file. -static void -add_fn_symbols_to_map(address_set_type& syms, - string_elf_symbols_map_type& map, - read_context& ctxt) -{ - for (address_set_type::iterator i = syms.begin(); i != syms.end(); ++i) - { - elf_symbol_sptr sym = ctxt.lookup_elf_fn_symbol_from_address(*i); - ABG_ASSERT(sym); - string_elf_symbols_map_type::iterator it = - ctxt.fun_syms().find(sym->get_name()); - ABG_ASSERT(it != ctxt.fun_syms().end()); - map.insert(*it); - } -} - /// Add a symbol to a symbol map. /// /// @param sym the symbol to add. @@ -15425,34 +14210,6 @@ add_symbol_to_map(const elf_symbol_sptr& sym, it->second.push_back(sym); } -/// Add a set of addresses (representing variable symbols) to a -/// variable symbol name -> symbol map. -/// -/// For a given symbol address, the variable retrieves the name of the -/// symbol as well as the symbol itself and inserts an entry {symbol -/// name, symbol} into a map of symbol name -> symbol map. -/// -/// @param syms the set of symbol addresses to consider. -/// -/// @param map the map to populate. -/// -/// @param ctxt the context in which we are loading a given ELF file. -static void -add_var_symbols_to_map(address_set_type& syms, - string_elf_symbols_map_type& map, - read_context& ctxt) -{ - for (address_set_type::iterator i = syms.begin(); i != syms.end(); ++i) - { - elf_symbol_sptr sym = ctxt.lookup_elf_var_symbol_from_address(*i); - ABG_ASSERT(sym); - string_elf_symbols_map_type::iterator it = - ctxt.var_syms().find(sym->get_name()); - ABG_ASSERT(it != ctxt.var_syms().end()); - map.insert(*it); - } -} - /// Read all @ref abigail::translation_unit possible from the debug info /// accessible through a DWARF Front End Library handle, and stuff /// them into a libabigail ABI Corpus. @@ -15496,22 +14253,29 @@ read_debug_info_into_corpus(read_context& ctxt) { string_elf_symbols_map_sptr exported_fn_symbols_map (new string_elf_symbols_map_type); - add_fn_symbols_to_map(*ctxt.linux_exported_fn_syms(), - *exported_fn_symbols_map, - ctxt); - add_fn_symbols_to_map(*ctxt.linux_exported_gpl_fn_syms(), - *exported_fn_symbols_map, - ctxt); + symtab_reader::symtab_filter filter = + ctxt.symtab()->make_filter().functions(); + + for (symtab_reader::symtab::const_iterator + it = ctxt.symtab()->begin(filter), + end = ctxt.symtab()->end(); + it != end; ++it) + { + (*exported_fn_symbols_map)[(*it)->get_name()].push_back(*it); + } + ctxt.current_corpus()->set_fun_symbol_map(exported_fn_symbols_map); - string_elf_symbols_map_sptr exported_var_symbols_map - (new string_elf_symbols_map_type); - add_var_symbols_to_map(*ctxt.linux_exported_var_syms(), - *exported_var_symbols_map, - ctxt); - add_var_symbols_to_map(*ctxt.linux_exported_gpl_var_syms(), - *exported_var_symbols_map, - ctxt); + string_elf_symbols_map_sptr exported_var_symbols_map( + new string_elf_symbols_map_type); + filter = ctxt.symtab()->make_filter().variables(); + for (symtab_reader::symtab::const_iterator + it = ctxt.symtab()->begin(filter), + end = ctxt.symtab()->end(); + it != end; ++it) + { + (*exported_var_symbols_map)[(*it)->get_name()].push_back(*it); + } ctxt.current_corpus()->set_var_symbol_map(exported_var_symbols_map); } else From patchwork Fri Jul 3 16:46:43 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: 39895 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 0DF423844079; Fri, 3 Jul 2020 16:48:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0DF423844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794888; bh=upPfaD2EOgo1FwS31bYwquvGI92Oe046/3bxYQSNzsE=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=DUPg9LcjryO9ESVkpONXxV/WvQQYo5K1EuVMJCqja+QuXVu0Ml6wJeiCzg1Avi4lY df0YenHOQNMzTIKbeTC0L1JGngCQQ4VNm3q2CPy/pft+IjA3y3BZ7bStZ81VTohx1L WjidSWgqlbR0/1NEUoTSSKdhT929eODjqbJP0cp8= 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 734883844079 for ; Fri, 3 Jul 2020 16:48:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 734883844079 Received: by mail-wr1-x449.google.com with SMTP id y18so12590211wrq.4 for ; Fri, 03 Jul 2020 09:48:04 -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=upPfaD2EOgo1FwS31bYwquvGI92Oe046/3bxYQSNzsE=; b=Yn/0cjSO7Kbf7bHfoH5RLm9NagGAtkY663p40saEKrpR6MICAWJ/VasNDu0AhRnw/m qTE7NSOWbJsrcsJJvjIR5Xcys4/A2DAe1wG/mIquYtpDezJaQOkN2/CSOcuC76gh563U T9KmFJJyRxjwem80CyiMXlidyzoztay7oZtoqe9B4FODl3rKfMnU2RlMTDyBEDCSolcZ nsJ+X0az233fpXTpg8Yp/D3gwaAQjN11qArfY58RZbfjguFhzNZgvtXajKH4B5RFs9LV RvyefQZT+oukRqPNr4huThktUtJgCrwBnVWVhhVdDU3cBswuXEjiMF8ZfXqZ+tyV6oWH 2fQg== X-Gm-Message-State: AOAM530lddSUgj6BUextt13PdVFF/qigxQe4v38MBkQMNKGx9Y+6Xj+P iLW06tahPOODbsgq+zS2emOuuXKPigDXs4GbtSGmq8Q9tpSSg2Xka+jmf/R6nxC/V4NaHxJgm6j v5xbENm4BUhTDYe2LG51u6hnxhjKC8R2apzMqaCAMPlQvY2USjEnr5QcB/v5N/D8s9dNqTAU= X-Google-Smtp-Source: ABdhPJwqqbyLQ7WoOZxAtLOg8sZGoa6hLSRgWh0EICMqcLJ+/SBBnEiDCS6VJlb0McLDEE94zEo/95QJxsG1zA== X-Received: by 2002:a7b:c763:: with SMTP id x3mr28636839wmk.47.1593794883340; Fri, 03 Jul 2020 09:48:03 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:43 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-14-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 13/21] abg-elf-helpers: migrate ppc64 specific helpers To: libabigail@sourceware.org X-Spam-Status: No, score=-23.3 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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" This migrates more helpers to abg-elf-helpers: lookup_ppc64_elf_fn_entry_point_address with dependencies read_uint64_from_array_of_bytes read_int_from_array_of_bytes address_is_in_opd_section with dependency address_is_in_section read_context::find_opd_section and read_context::opd_section_ are obsolete. * src/abg-dwarf-reader.cc (read_context::opd_section_): Delete. (read_context::find_opd_section): Delete. (read_context::read_uint64_from_array_of_bytes): Delete. (read_context::read_int_from_array_of_bytes): Delete. (read_context::lookup_ppc64_elf_fn_entry_point_address): Delete. (read_context::address_is_in_opd_section): Delete. (read_context::address_is_in_section): Delete. (read_context::load_symbol_maps_from_symtab_section): Adjust. * src/abg-elf-helpers.cc (read_int_from_array_of_bytes): New. (read_uint64_from_array_of_bytes): New. (lookup_ppc64_elf_fn_entry_point_address): New. (address_is_in_section): New. (address_is_in_opd_section): New. * src/abg-elf-helpers.h (lookup_ppc64_elf_fn_entry_point_address): New declaration. (address_is_in_opd_section): New declaration. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-dwarf-reader.cc | 208 +--------------------------------------- src/abg-elf-helpers.cc | 186 +++++++++++++++++++++++++++++++++++ src/abg-elf-helpers.h | 8 ++ 3 files changed, 198 insertions(+), 204 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index d90c0a3fe56a..47d561452b05 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -2075,10 +2075,6 @@ public: mutable Elf* elf_handle_; string elf_path_; mutable Elf_Scn* symtab_section_; - // The "Official procedure descriptor section, aka .opd", used in - // ppc64 elf v1 binaries. This section contains the procedure - // descriptors on that platform. - mutable Elf_Scn* opd_section_; Dwarf_Die* cur_tu_die_; mutable dwarf_expr_eval_context dwarf_expr_eval_context_; // A set of maps (one per kind of die source) that associates a decl @@ -2258,7 +2254,6 @@ public: elf_handle_ = 0; elf_path_ = elf_path; symtab_section_ = 0; - opd_section_ = 0; cur_tu_die_ = 0; exported_decls_builder_ = 0; @@ -4934,19 +4929,6 @@ public: return symtab_section_; } - /// Return the "Official Procedure descriptors section." This - /// section is named .opd, and is usually present only on PPC64 - /// ELFv1 binaries. - /// - /// @return the .opd section, if found. Return nil otherwise. - Elf_Scn* - find_opd_section() const - { - if (!opd_section_) - opd_section_ = elf_helpers::find_opd_section(elf_handle()); - return opd_section_; - } - /// Lookup an elf symbol, referred to by its index, from the .symtab /// section. /// @@ -5058,152 +5040,6 @@ public: return sym; } - /// Read 8 bytes and convert their value into an uint64_t. - /// - /// @param bytes the array of bytes to read the next 8 bytes from. - /// Note that this array must be at least 8 bytes long. - /// - /// @param result where to store the resuting uint64_t that was read. - /// - /// @param is_big_endian if true, read the 8 bytes in Big Endian - /// mode, otherwise, read them in Little Endian. - /// - /// @param true if the 8 bytes could be read, false otherwise. - bool - read_uint64_from_array_of_bytes(const uint8_t *bytes, - bool is_big_endian, - uint64_t &result) const - { - return read_int_from_array_of_bytes(bytes, 8, is_big_endian, result); - } - - /// Read N bytes and convert their value into an integer type T. - /// - /// Note that N cannot be bigger than 8 for now. The type passed needs to be - /// at least of the size of number_of_bytes. - /// - /// @param bytes the array of bytes to read the next 8 bytes from. - /// Note that this array must be at least 8 bytes long. - /// - /// @param number_of_bytes the number of bytes to read. This number - /// cannot be bigger than 8. - /// - /// @param is_big_endian if true, read the 8 bytes in Big Endian - /// mode, otherwise, read them in Little Endian. - /// - /// @param result where to store the resuting integer that was read. - /// - /// - /// @param true if the 8 bytes could be read, false otherwise. - template - bool - read_int_from_array_of_bytes(const uint8_t *bytes, - unsigned char number_of_bytes, - bool is_big_endian, - T &result) const - { - if (!bytes) - return false; - - ABG_ASSERT(number_of_bytes <= 8); - ABG_ASSERT(number_of_bytes <= sizeof(T)); - - T res = 0; - - const uint8_t *cur = bytes; - if (is_big_endian) - { - // In Big Endian, the most significant byte is at the lowest - // address. - const uint8_t* msb = cur; - res = *msb; - - // Now read the remaining least significant bytes. - for (uint i = 1; i < number_of_bytes; ++i) - res = (res << 8) | ((T)msb[i]); - } - else - { - // In Little Endian, the least significant byte is at the - // lowest address. - const uint8_t* lsb = cur; - res = *lsb; - // Now read the remaining most significant bytes. - for (uint i = 1; i < number_of_bytes; ++i) - res = res | (((T)lsb[i]) << i * 8); - } - - result = res; - return true; - } - - /// Lookup the address of the function entry point that corresponds - /// to the address of a given function descriptor. - /// - /// On PPC64, a function pointer is the address of a function - /// descriptor. Function descriptors are located in the .opd - /// section. Each function descriptor is a triplet of three - /// addresses, each one on 64 bits. Among those three address only - /// the first one is of any interest to us: the address of the entry - /// point of the function. - /// - /// This function returns the address of the entry point of the - /// function whose descriptor's address is given. - /// - /// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUNC-DES - /// - /// https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/deeply_understand_64_bit_powerpc_elf_abi_function_descriptors?lang=en - /// - /// @param fn_desc_address the address of the function descriptor to - /// consider. - /// - /// @return the address of the entry point of the function whose - /// descriptor has the address @p fn_desc_address. If there is no - /// .opd section (e.g because we are not on ppc64) or more generally - /// if the function descriptor could not be found then this function - /// just returns the address of the fuction descriptor. - GElf_Addr - lookup_ppc64_elf_fn_entry_point_address(GElf_Addr fn_desc_address) const - { - if (!elf_handle()) - return fn_desc_address; - - if (!architecture_is_ppc64(elf_handle())) - return fn_desc_address; - - bool is_big_endian = architecture_is_big_endian(elf_handle()); - - Elf_Scn *opd_section = find_opd_section(); - if (!opd_section) - return fn_desc_address; - - GElf_Shdr header_mem; - // The section header of the .opd section. - GElf_Shdr *opd_sheader = gelf_getshdr(opd_section, &header_mem); - - // The offset of the function descriptor entry, in the .opd - // section. - size_t fn_desc_offset = fn_desc_address - opd_sheader->sh_addr; - Elf_Data *elf_data = elf_rawdata(opd_section, 0); - - // Ensure that the opd_section has at least 8 bytes, starting from - // the offset we want read the data from. - if (elf_data->d_size <= fn_desc_offset + 8) - return fn_desc_address; - - // A pointer to the data of the .opd section, that we can actually - // do something with. - uint8_t * bytes = (uint8_t*) elf_data->d_buf; - - // The resulting address we are looking for is going to be formed - // in this variable. - GElf_Addr result = 0; - ABG_ASSERT(read_uint64_from_array_of_bytes(bytes + fn_desc_offset, - is_big_endian, result)); - - return result; - } - /// Test if a given function symbol has been exported. /// /// @param symbol_address the address of the symbol we are looking @@ -5513,13 +5349,15 @@ public: // symbol that are in the .opd section. GElf_Addr fn_desc_addr = sym->st_value; GElf_Addr fn_entry_point_addr = - lookup_ppc64_elf_fn_entry_point_address(fn_desc_addr); + lookup_ppc64_elf_fn_entry_point_address( + elf_handle(), fn_desc_addr); addr_elf_symbol_sptr_map_type::const_iterator it2 = fun_entry_addr_sym_map().find(fn_entry_point_addr); if (it2 == fun_entry_addr_sym_map().end()) fun_entry_addr_sym_map()[fn_entry_point_addr] = symbol; - else if (address_is_in_opd_section(fn_desc_addr)) + else if (address_is_in_opd_section(elf_handle(), + fn_desc_addr)) { // Either // @@ -5682,24 +5520,6 @@ public: return true; } - /// Return true if an address is in the ".opd" section that is - /// present on the ppc64 platform. - /// - /// @param addr the address to consider. - /// - /// @return true iff @p addr is designates a word that is in the - /// ".opd" section. - bool - address_is_in_opd_section(Dwarf_Addr addr) - { - Elf_Scn * opd_section = find_opd_section(); - if (!opd_section) - return false; - if (address_is_in_section(addr, opd_section)) - return true; - return false; - } - /// Load the symbol maps if necessary. /// /// @return true iff the symbol maps has been loaded by this @@ -5850,26 +5670,6 @@ public: return addr; } - /// Test if a given address is in a given section. - /// - /// @param addr the address to consider. - /// - /// @param section the section to consider. - bool - address_is_in_section(Dwarf_Addr addr, Elf_Scn* section) const - { - if (!section) - return false; - - GElf_Shdr sheader_mem; - GElf_Shdr* sheader = gelf_getshdr(section, &sheader_mem); - - if (sheader->sh_addr <= addr && addr <= sheader->sh_addr + sheader->sh_size) - return true; - - return false; - } - /// For a relocatable (*.o) elf file, this function expects an /// absolute address, representing a global variable symbol. It /// then extracts the address of the {.data,.data1,.rodata,.bss} diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc index ed768d221d4f..6e2495af1ee0 100644 --- a/src/abg-elf-helpers.cc +++ b/src/abg-elf-helpers.cc @@ -863,6 +863,153 @@ architecture_is_big_endian(Elf* elf_handle) return is_big_endian; } +/// Read N bytes and convert their value into an integer type T. +/// +/// Note that N cannot be bigger than 8 for now. The type passed needs to be at +/// least of the size of number_of_bytes. +/// +/// @param bytes the array of bytes to read the next 8 bytes from. +/// Note that this array must be at least 8 bytes long. +/// +/// @param number_of_bytes the number of bytes to read. This number +/// cannot be bigger than 8. +/// +/// @param is_big_endian if true, read the 8 bytes in Big Endian +/// mode, otherwise, read them in Little Endian. +/// +/// @param result where to store the resuting integer that was read. +/// +/// +/// @param true if the 8 bytes could be read, false otherwise. +template +bool +read_int_from_array_of_bytes(const uint8_t* bytes, + unsigned char number_of_bytes, + bool is_big_endian, + T& result) +{ + if (!bytes) + return false; + + ABG_ASSERT(number_of_bytes <= 8); + ABG_ASSERT(number_of_bytes <= sizeof(T)); + + T res = 0; + + const uint8_t* cur = bytes; + if (is_big_endian) + { + // In Big Endian, the most significant byte is at the lowest + // address. + const uint8_t* msb = cur; + res = *msb; + + // Now read the remaining least significant bytes. + for (uint i = 1; i < number_of_bytes; ++i) + res = (res << 8) | ((T)msb[i]); + } + else + { + // In Little Endian, the least significant byte is at the + // lowest address. + const uint8_t* lsb = cur; + res = *lsb; + // Now read the remaining most significant bytes. + for (uint i = 1; i < number_of_bytes; ++i) + res = res | (((T)lsb[i]) << i * 8); + } + + result = res; + return true; +} + +/// Read 8 bytes and convert their value into an uint64_t. +/// +/// @param bytes the array of bytes to read the next 8 bytes from. +/// Note that this array must be at least 8 bytes long. +/// +/// @param result where to store the resuting uint64_t that was read. +/// +/// @param is_big_endian if true, read the 8 bytes in Big Endian +/// mode, otherwise, read them in Little Endian. +/// +/// @param true if the 8 bytes could be read, false otherwise. +bool +read_uint64_from_array_of_bytes(const uint8_t* bytes, + bool is_big_endian, + uint64_t& result) +{ + return read_int_from_array_of_bytes(bytes, 8, is_big_endian, result); +} + + +/// Lookup the address of the function entry point that corresponds +/// to the address of a given function descriptor. +/// +/// On PPC64, a function pointer is the address of a function +/// descriptor. Function descriptors are located in the .opd +/// section. Each function descriptor is a triplet of three +/// addresses, each one on 64 bits. Among those three address only +/// the first one is of any interest to us: the address of the entry +/// point of the function. +/// +/// This function returns the address of the entry point of the +/// function whose descriptor's address is given. +/// +/// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUNC-DES +/// +/// https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/deeply_understand_64_bit_powerpc_elf_abi_function_descriptors?lang=en +/// +/// @param fn_desc_address the address of the function descriptor to +/// consider. +/// +/// @return the address of the entry point of the function whose +/// descriptor has the address @p fn_desc_address. If there is no +/// .opd section (e.g because we are not on ppc64) or more generally +/// if the function descriptor could not be found then this function +/// just returns the address of the fuction descriptor. +GElf_Addr +lookup_ppc64_elf_fn_entry_point_address(Elf* elf_handle, GElf_Addr fn_desc_address) +{ + if (!elf_handle) + return fn_desc_address; + + if (!architecture_is_ppc64(elf_handle)) + return fn_desc_address; + + bool is_big_endian = architecture_is_big_endian(elf_handle); + + Elf_Scn* opd_section = find_opd_section(elf_handle); + if (!opd_section) + return fn_desc_address; + + GElf_Shdr header_mem; + // The section header of the .opd section. + GElf_Shdr* opd_sheader = gelf_getshdr(opd_section, &header_mem); + + // The offset of the function descriptor entry, in the .opd + // section. + size_t fn_desc_offset = fn_desc_address - opd_sheader->sh_addr; + Elf_Data* elf_data = elf_rawdata(opd_section, 0); + + // Ensure that the opd_section has at least 8 bytes, starting from + // the offset we want read the data from. + if (elf_data->d_size <= fn_desc_offset + 8) + return fn_desc_address; + + // A pointer to the data of the .opd section, that we can actually + // do something with. + uint8_t* bytes = (uint8_t*)elf_data->d_buf; + + // The resulting address we are looking for is going to be formed + // in this variable. + GElf_Addr result = 0; + ABG_ASSERT(read_uint64_from_array_of_bytes(bytes + fn_desc_offset, + is_big_endian, result)); + + return result; +} + /// Test if the ELF binary denoted by a given ELF handle is a Linux /// Kernel Module. /// @@ -1027,5 +1174,44 @@ maybe_adjust_et_rel_sym_addr_to_abs_addr(Elf* elf_handle, GElf_Sym* sym) return addr + section_header.sh_addr; } +/// Test if a given address is in a given section. +/// +/// @param addr the address to consider. +/// +/// @param section the section to consider. +bool +address_is_in_section(Dwarf_Addr addr, Elf_Scn* section) +{ + if (!section) + return false; + + GElf_Shdr sheader_mem; + GElf_Shdr* sheader = gelf_getshdr(section, &sheader_mem); + + if (sheader->sh_addr <= addr && addr <= sheader->sh_addr + sheader->sh_size) + return true; + + return false; +} + +/// Return true if an address is in the ".opd" section that is +/// present on the ppc64 platform. +/// +/// @param addr the address to consider. +/// +/// @return true iff @p addr is designates a word that is in the +/// ".opd" section. +bool +address_is_in_opd_section(Elf* elf_handle, Dwarf_Addr addr) +{ + Elf_Scn * opd_section = find_opd_section(elf_handle); + if (!opd_section) + return false; + if (address_is_in_section(addr, opd_section)) + return true; + return false; +} + + } // end namespace elf_helpers } // end namespace abigail diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h index 647c92703dfa..2046648569a7 100644 --- a/src/abg-elf-helpers.h +++ b/src/abg-elf-helpers.h @@ -27,6 +27,7 @@ #include "config.h" +#include #include #include @@ -148,6 +149,10 @@ architecture_is_ppc64(Elf* elf_handle); bool architecture_is_big_endian(Elf* elf_handle); +GElf_Addr +lookup_ppc64_elf_fn_entry_point_address(Elf* elf_handle, + GElf_Addr fn_desc_address); + // // Helpers for Linux Kernel Binaries // @@ -177,6 +182,9 @@ is_dso(Elf* elf_handle); GElf_Addr maybe_adjust_et_rel_sym_addr_to_abs_addr(Elf* elf_handle, GElf_Sym* sym); +bool +address_is_in_opd_section(Elf* elf_handle, Dwarf_Addr addr); + } // end namespace elf_helpers } // end namespace abigail From patchwork Fri Jul 3 16:46:44 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: 39897 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 A850D384242F; Fri, 3 Jul 2020 16:48:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A850D384242F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794888; bh=sEKLRqEGnH094ty91pPC6DssG3frGiZcSc7RT2J01Ic=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=dSECSq0NdG6vT8rfTA8cLlkxU3ou+P8QemOslTtmTWkU+6iEVWwuqSDN1YF0PInTk oFsusLaFTb9AbswL//7V+8N+goQnqgLVvOeAhlGzoivAo0QQ4m1gz+p4DW3xgXspys k5iuw0ZVO/n3elVkwjDj7GWTMsAV4r6Ou6C4x9zE= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by sourceware.org (Postfix) with ESMTPS id EAF99386F028 for ; Fri, 3 Jul 2020 16:48:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EAF99386F028 Received: by mail-qt1-x849.google.com with SMTP id u48so22114939qth.17 for ; Fri, 03 Jul 2020 09:48:05 -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=sEKLRqEGnH094ty91pPC6DssG3frGiZcSc7RT2J01Ic=; b=NFu2xtGYF3v8cB+AdeO60hSMuOcIAxNLQDD0pk5x7E3hTajHHQa8wY51YTUJuhFeK0 QHSnL9zc2cUloB2c5WDZAhqZKoJEyROuAUDZTf1Fesj6iI+Y6X8yOlJSs+UJuNUoRhN4 9zeUDOg3nXPL36QKDcK4wzIus9qfF0dLpWRGQUSRzPN4nl58LuPMF9FO5e4iqXH469wQ flekXxWC47n6D+YKytE4X4qLL1588GLwXthSpZlZ79w2OLrluN+xCZqP8o32fhI4l0Ks sUc9IZx6BYkAj/30oA5iQhV56NAW/2Pb9//1PyP1Q+HMBblHSOdp4HVacQRQeqND9DUu SFUQ== X-Gm-Message-State: AOAM530NyAe/327KLsGJt5tFurZEfh6Lq0TTD5aZ7krPxfT2PmDIyEiY +lmScZIimmP8CUUd9Ns1JpE5QbZAzWwAgGFp1iLuX+tYS0wOXmHb311wGhkOjz56IMEdm/H51wc DzlETs7O9ucpsegYo2hgaA97A97Gzb05hj6axadXu6iX0bvOpYa9bRq4iQgC20ZyWAVuMWFA= X-Google-Smtp-Source: ABdhPJwdkAElD7fSVxwOCCGTrozbkdxIX0JbdMEXzbCDC1U8FngC0Cg//j4Jz01skwQcu/OQbGR95r2FMBy1pA== X-Received: by 2002:a0c:b4da:: with SMTP id h26mr33976404qvf.155.1593794885479; Fri, 03 Jul 2020 09:48:05 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:44 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-15-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 14/21] symtab_reader: add support for ppc64 ELFv1 binaries To: libabigail@sourceware.org X-Spam-Status: No, score=-21.9 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" When loading the symtab from an ppc64 binary, also keep track of the function entry addresses as a key for the symbol lookup. That accommodates the differences in DWARF pointing to the function entry address while the symbol table points to the function pointer. The implementation is mostly copied and adopted from abg-dwarf-reader's read_context to add this functionality also to the new symtab reader. * src/abg-symtab-reader.cc (symtab::lookup_symbol): fall back to lookup the address in entry_addr_symbol_map_. (symtab::load): update the function entry address map for ppc64 targets. (symtab::update_function_entry_address_symbol_map): New function implementation. * src/abg-symtab-reader.h (symtab::entry_addr_symbol_map_): New data member. (symtab::update_function_entry_address_symbol_map): New function declaration. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-symtab-reader.h | 8 ++++ src/abg-symtab-reader.cc | 93 +++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/include/abg-symtab-reader.h b/include/abg-symtab-reader.h index 86335617d46a..06001b26ebeb 100644 --- a/include/abg-symtab-reader.h +++ b/include/abg-symtab-reader.h @@ -342,6 +342,9 @@ private: addr_symbol_map_type; addr_symbol_map_type addr_symbol_map_; + /// Lookup map function entry address -> symbol + addr_symbol_map_type entry_addr_symbol_map_; + /// Load the symtab representation from an Elf binary presented to us by an /// Elf* handle. /// @@ -366,6 +369,11 @@ private: bool load_(string_elf_symbols_map_sptr function_symbol_map, string_elf_symbols_map_sptr variables_symbol_map); + + void + update_function_entry_address_symbol_map(Elf* elf_handle, + GElf_Sym* native_symbol, + const elf_symbol_sptr& symbol_sptr); }; /// Helper class to allow range-for loops on symtabs for C++11 and later code. diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc index c98b9174490c..aefc8d6dcd86 100644 --- a/src/abg-symtab-reader.cc +++ b/src/abg-symtab-reader.cc @@ -91,11 +91,16 @@ const elf_symbol_sptr& symtab::lookup_symbol(GElf_Addr symbol_addr) const { static const elf_symbol_sptr empty_result; - const addr_symbol_map_type::const_iterator it = + const addr_symbol_map_type::const_iterator addr_it = addr_symbol_map_.find(symbol_addr); - if (it != addr_symbol_map_.end()) + if (addr_it != addr_symbol_map_.end()) + return addr_it->second; + else { - return it->second; + const addr_symbol_map_type::const_iterator entry_it = + entry_addr_symbol_map_.find(symbol_addr); + if (entry_it != entry_addr_symbol_map_.end()) + return entry_it->second; } return empty_result; } @@ -172,6 +177,8 @@ symtab::load_(Elf* elf_handle, const bool is_kernel = elf_helpers::is_linux_kernel(elf_handle); abg_compat::unordered_set exported_kernel_symbols; + const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle); + for (size_t i = 0; i < number_syms; ++i) { GElf_Sym *sym, sym_mem; @@ -277,6 +284,10 @@ symtab::load_(Elf* elf_handle, elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle, sym); + if (is_ppc64 && symbol_sptr->is_function()) + update_function_entry_address_symbol_map(elf_handle, sym, + symbol_sptr); + const std::pair result = addr_symbol_map_.insert( std::make_pair(symbol_value, symbol_sptr)); @@ -345,5 +356,81 @@ symtab::load_(string_elf_symbols_map_sptr function_symbol_map, return true; } +void +symtab::update_function_entry_address_symbol_map( + Elf* elf_handle, + GElf_Sym* native_symbol, + const elf_symbol_sptr& symbol_sptr) +{ + + // For ppc64 ELFv1 binaries, we need to build a function entry point address + // -> function symbol map. This is in addition to the function pointer -> + // symbol map. This is because on ppc64 ELFv1, a function pointer is + // different from a function entry point address. + // + // On ppc64 ELFv1, the DWARF DIE of a function references the address of the + // entry point of the function symbol; whereas the value of the function + // symbol is the function pointer. As these addresses are different, if I we + // want to get to the symbol of a function from its entry point address (as + // referenced by DWARF function DIEs) we must have the two maps I mentionned + // right above. + // + // In other words, we need a map that associates a function entry point + // address with the symbol of that function, to be able to get the function + // symbol that corresponds to a given function DIE, on ppc64. + // + // The value of the function pointer (the value of the symbol) usually refers + // to the offset of a table in the .opd section. But sometimes, for a symbol + // named "foo", the corresponding symbol named ".foo" (note the dot before + // foo) which value is the entry point address of the function; that entry + // point address refers to a region in the .text section. + // + // So we are only interested in values of the symbol that are in the .opd + // section. + const GElf_Addr fn_desc_addr = native_symbol->st_value; + const GElf_Addr fn_entry_point_addr = + elf_helpers::lookup_ppc64_elf_fn_entry_point_address(elf_handle, + fn_desc_addr); + + const std::pair& result = + entry_addr_symbol_map_.insert( + std::make_pair(fn_entry_point_addr, symbol_sptr)); + + const addr_symbol_map_type::const_iterator it = result.first; + const bool was_inserted = result.second; + if (!was_inserted + && elf_helpers::address_is_in_opd_section(elf_handle, fn_desc_addr)) + { + // Either + // + // 'symbol' must have been registered as an alias for + // it->second->get_main_symbol() + // + // Or + // + // if the name of 'symbol' is foo, then the name of it2->second is + // ".foo". That is, foo is the name of the symbol when it refers to the + // function descriptor in the .opd section and ".foo" is an internal name + // for the address of the entry point of foo. + // + // In the latter case, we just want to keep a reference to "foo" as .foo + // is an internal name. + + const bool two_symbols_alias = + it->second->get_main_symbol()->does_alias(*symbol_sptr); + const bool symbol_is_foo_and_prev_symbol_is_dot_foo = + (it->second->get_name() == std::string(".") + symbol_sptr->get_name()); + + ABG_ASSERT(two_symbols_alias + || symbol_is_foo_and_prev_symbol_is_dot_foo); + + if (symbol_is_foo_and_prev_symbol_is_dot_foo) + // Let's just keep a reference of the symbol that the user sees in the + // source code (the one named foo). The symbol which name is prefixed + // with a "dot" is an artificial one. + entry_addr_symbol_map_[fn_entry_point_addr] = symbol_sptr; + } +} + } // end namespace symtab_reader } // end namespace abigail From patchwork Fri Jul 3 16:46:45 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: 39898 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 4E3B4384240C; Fri, 3 Jul 2020 16:48:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4E3B4384240C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794891; bh=u/bGt6Kh54G1TFd9/tNfUnMTx3TINRti34QR26ojeB0=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=wnvYcMzl7TV1g1B2ZwqjN8Ma8ClQt8n57pEXZ7ZZ7zDb61gcVc6zuqYRt+NdJ/kxU SY6/NT42kv84Q8gaIpbx58StfaP+GwkobLexgIv9pxtpK6TUlRw4FxkIO9Q4oX3qxc 0evhzBifEXBV4ykx53IxoQOwyXFdF3Opdpnt5hM4= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by sourceware.org (Postfix) with ESMTPS id 32D3E384240C for ; Fri, 3 Jul 2020 16:48:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 32D3E384240C Received: by mail-qv1-xf4a.google.com with SMTP id em19so15203465qvb.14 for ; Fri, 03 Jul 2020 09:48:08 -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=u/bGt6Kh54G1TFd9/tNfUnMTx3TINRti34QR26ojeB0=; b=CLbIyahyl4S/d4Zo9XwM6WoOfCt6sM8tVOWV3rcwGFcPm+j1tbcQ33SNABIDnezBaU jPlACKimwbosrlDIP92YHTSUr0F4OW5acj4Ds55aTsy79z18e38Qmzc/qvWpTxlXUc8K Jv3iXtqJhvK9geIxVuB8IdilXOWSyQlWVOvjAh0Ts5ZE7in6G76oW9ze/8HtYS7XTkG/ Ggi7OqOMiNv3LPEAywCYZuyraLctEoIRxfHRQ4ly2uOWZZ5QXfu75grdRusvWl+XnuY1 apQ2ePuVoK0UIGMQJULtHiZxMOMKQ49AAmsyePLMyL9eRMs5Kt62ziZjhKCCG4+9JEmh JsAg== X-Gm-Message-State: AOAM5338upqZL2Hxw+6V5hGlqZqG2oQGNGt/iDFUHVuQpY8fu71KBEhv 4dfB734n002Wjkuw+BmAVhtBlUEwzOLZocjiSPMkckx5EXKTykSInvlAa9hfD2ADTNRc9dmaiMd gdKpu0I6sMQiX+45Loz/yWk+CQRJEQM5Qkh2pM9MaHKRBGP6T7veHYldQcdQQ9tC30fhxUcQ= X-Google-Smtp-Source: ABdhPJysjeeR32P883ogac/pNWxriYEe59QnGKRodm3cmseCHfcmED3p6ahYRKJs+d/m/HJEk+vT6UK481UKuA== X-Received: by 2002:a0c:b7ad:: with SMTP id l45mr32069702qve.132.1593794887662; Fri, 03 Jul 2020 09:48:07 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:45 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-16-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 15/21] abg-corpus: remove symbol maps and their setters To: libabigail@sourceware.org X-Spam-Status: No, score=-22.5 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" With the prework in previous commits, we are now able to drop the public symbols maps in corpus::priv and replace them by private members with access through getters. The getters use the new symtab implementation to generate the maps on the fly. Setters are not required anymore and are removed. Also remove redundant getters. We could also remove the getters for the symbol maps and the local caching variable and leave it all to lookup_symbol, but this is left for a later change. * include/abg-corpus.h (corpus::set_fun_symbol_map): Remove method declaration. (corpus::set_undefined_fun_symbol_map): Likewise. (corpus::set_var_symbol_map): Likewise. (corpus::set_undefined_var_symbol_map): Likewise. (corpus::get_fun_symbol_map_sptr): Likewise. (corpus::get_undefined_fun_symbol_map_sptr): Likewise. (corpus::get_var_symbol_map_sptr): Likewise. (corpus::get_undefined_var_symbol_map_sptr): Likewise. * src/abg-corpus-priv.h (corpus::priv::var_symbol_map): make private and mutable (corpus::priv::undefined_var_symbol_map): Likewise. (corpus::priv::fun_symbol_map): Likewise. (corpus::priv::undefined_fun_symbol_map): Likewise. (corpus::priv::get_fun_symbol_map): New method declaration. (corpus::priv::get_undefined_fun_symbol_map): Likewise. (corpus::priv::get_var_symbol_map): Likewise. (corpus::priv::get_undefined_var_symbol_map): Likewise. * src/abg-corpus.cc (corpus::priv::get_fun_symbol_map): New method implementation. (corpus::priv::get_undefined_fun_symbol_map): Likewise. (corpus::priv::get_var_symbol_map): Likewise. (corpus::priv::get_undefined_var_symbol_map): Likewise. (corpus::is_empty): depend on symtab only. (corpus::set_fun_symbol_map): Remove method. (corpus::set_undefined_fun_symbol_map): Likewise. (corpus::set_var_symbol_map): Likewise. (corpus::set_undefined_var_symbol_map): Likewise. (corpus::get_fun_symbol_map_sptr): Likewise. (corpus::get_undefined_fun_symbol_map_sptr): Likewise. (corpus::get_var_symbol_map_sptr): Likewise. (corpus::get_undefined_var_symbol_map_sptr): Likewise. (corpus::get_fun_symbol_map): Use corpus::priv proxy method. (corpus::get_undefined_fun_symbol_map): Likewise. (corpus::get_var_symbol_map): Likewise. (corpus::get_undefined_var_symbol_map): Likewise. * src/abg-dwarf-reader.cc (read_debug_info_into_corpus): Do not set corpus symbol maps anymore. * src/abg-reader.cc (read_corpus_from_input): Likewise. * tests/test-symtab.cc (assert_symbol_count): Do not access the corpus symbol maps through sptr anymore. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Adjust expected test output. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-corpus.h | 24 --- src/abg-corpus-priv.h | 21 ++- src/abg-corpus.cc | 159 ++++++++---------- src/abg-dwarf-reader.cc | 48 ------ src/abg-reader.cc | 11 -- .../data/test-read-dwarf/PR25007-sdhci.ko.abi | 2 - tests/test-symtab.cc | 15 +- 7 files changed, 99 insertions(+), 181 deletions(-) diff --git a/include/abg-corpus.h b/include/abg-corpus.h index b94926996cde..f517986d8aca 100644 --- a/include/abg-corpus.h +++ b/include/abg-corpus.h @@ -175,27 +175,9 @@ public: const symtab_reader::symtab_sptr& get_symtab() const; - void - set_fun_symbol_map(string_elf_symbols_map_sptr); - - void - set_undefined_fun_symbol_map(string_elf_symbols_map_sptr); - - void - set_var_symbol_map(string_elf_symbols_map_sptr); - - void - set_undefined_var_symbol_map(string_elf_symbols_map_sptr); - - const string_elf_symbols_map_sptr - get_fun_symbol_map_sptr() const; - virtual const string_elf_symbols_map_type& get_fun_symbol_map() const; - const string_elf_symbols_map_sptr - get_undefined_fun_symbol_map_sptr() const; - const string_elf_symbols_map_type& get_undefined_fun_symbol_map() const; @@ -205,15 +187,9 @@ public: const elf_symbols& get_sorted_undefined_fun_symbols() const; - const string_elf_symbols_map_sptr - get_var_symbol_map_sptr() const; - virtual const string_elf_symbols_map_type& get_var_symbol_map() const; - const string_elf_symbols_map_sptr - get_undefined_var_symbol_map_sptr() const; - const string_elf_symbols_map_type& get_undefined_var_symbol_map() const; diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h index f2e895bf1e7d..fcb6d7a66b8e 100644 --- a/src/abg-corpus-priv.h +++ b/src/abg-corpus-priv.h @@ -30,6 +30,7 @@ #define __ABG_CORPUS_PRIV_H__ #include "abg-internal.h" +#include "abg-ir.h" #include "abg-regex.h" #include "abg-sptr-utils.h" #include "abg-symtab-reader.h" @@ -697,11 +698,7 @@ struct corpus::priv string_tu_map_type path_tu_map; vector fns; vector vars; - string_elf_symbols_map_sptr var_symbol_map; - string_elf_symbols_map_sptr undefined_var_symbol_map; symtab_reader::symtab_sptr symtab_; - string_elf_symbols_map_sptr fun_symbol_map; - string_elf_symbols_map_sptr undefined_fun_symbol_map; // The type maps contained in this data member are populated if the // corpus follows the One Definition Rule and thus if there is only // one copy of a type with a given name, per corpus. Otherwise, if @@ -722,10 +719,14 @@ private: priv(); mutable abg_compat::optional sorted_var_symbols; + mutable abg_compat::optional var_symbol_map; mutable abg_compat::optional sorted_undefined_var_symbols; + mutable abg_compat::optional undefined_var_symbol_map; mutable abg_compat::optional unrefed_var_symbols; mutable abg_compat::optional sorted_fun_symbols; + mutable abg_compat::optional fun_symbol_map; mutable abg_compat::optional sorted_undefined_fun_symbols; + mutable abg_compat::optional undefined_fun_symbol_map; mutable abg_compat::optional unrefed_fun_symbols; public: @@ -747,18 +748,30 @@ public: const elf_symbols& get_sorted_fun_symbols() const; + const string_elf_symbols_map_type& + get_fun_symbol_map() const; + const elf_symbols& get_sorted_undefined_fun_symbols() const; + const string_elf_symbols_map_type& + get_undefined_fun_symbol_map() const; + const elf_symbols& get_unreferenced_function_symbols() const; const elf_symbols& get_sorted_var_symbols() const; + const string_elf_symbols_map_type& + get_var_symbol_map() const; + const elf_symbols& get_sorted_undefined_var_symbols() const; + const string_elf_symbols_map_type& + get_undefined_var_symbol_map() const; + const elf_symbols& get_unreferenced_variable_symbols() const; diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc index 0f5d51820891..1f72904d137f 100644 --- a/src/abg-corpus.cc +++ b/src/abg-corpus.cc @@ -347,6 +347,22 @@ corpus::priv::get_sorted_fun_symbols() const return *sorted_fun_symbols; } +const string_elf_symbols_map_type& +corpus::priv::get_fun_symbol_map() const +{ + if (!fun_symbol_map) + { + fun_symbol_map = string_elf_symbols_map_type(); + for (elf_symbols::const_iterator iter = get_sorted_fun_symbols().begin(), + end = get_sorted_fun_symbols().end(); + iter != end; ++iter) + { + (*fun_symbol_map)[(*iter)->get_name()].push_back(*iter); + } + } + return *fun_symbol_map; +} + /// Getter for a sorted vector of the function symbols undefined in /// this corpus. /// @@ -368,6 +384,25 @@ corpus::priv::get_sorted_undefined_fun_symbols() const return *sorted_undefined_fun_symbols; } +const string_elf_symbols_map_type& +corpus::priv::get_undefined_fun_symbol_map() const +{ + if (!undefined_fun_symbol_map) + { + undefined_fun_symbol_map = string_elf_symbols_map_type(); + for (elf_symbols::const_iterator + iter = get_sorted_undefined_fun_symbols().begin(), + end = get_sorted_undefined_fun_symbols().end(); + iter != end; ++iter) + { + (*undefined_fun_symbol_map)[(*iter)->get_name()].push_back(*iter); + } + } + return *undefined_fun_symbol_map; +} + + + /// Return a list of symbols that are not referenced by any function of /// corpus::get_functions(). /// @@ -448,6 +483,22 @@ corpus::priv::get_sorted_var_symbols() const return *sorted_var_symbols; } +const string_elf_symbols_map_type& +corpus::priv::get_var_symbol_map() const +{ + if (!var_symbol_map) + { + var_symbol_map = string_elf_symbols_map_type(); + for (elf_symbols::const_iterator iter = get_sorted_var_symbols().begin(), + end = get_sorted_var_symbols().end(); + iter != end; ++iter) + { + (*var_symbol_map)[(*iter)->get_name()].push_back(*iter); + } + } + return *var_symbol_map; +} + /// Getter for a sorted vector of the variable symbols undefined in /// this corpus. /// @@ -469,6 +520,23 @@ corpus::priv::get_sorted_undefined_var_symbols() const return *sorted_undefined_var_symbols; } +const string_elf_symbols_map_type& +corpus::priv::get_undefined_var_symbol_map() const +{ + if (!undefined_var_symbol_map) + { + undefined_var_symbol_map = string_elf_symbols_map_type(); + for (elf_symbols::const_iterator + iter = get_sorted_undefined_var_symbols().begin(), + end = get_sorted_undefined_var_symbols().end(); + iter != end; ++iter) + { + (*undefined_var_symbol_map)[(*iter)->get_name()].push_back(*iter); + } + } + return *undefined_var_symbol_map; +} + /// Return a list of symbols that are not referenced by any variable of /// corpus::get_variables(). /// @@ -954,10 +1022,7 @@ corpus::is_empty() const } } return (members_empty - && priv_->fun_symbol_map - && priv_->fun_symbol_map->empty() - && priv_->var_symbol_map - && priv_->var_symbol_map->empty() + && !get_symtab()->has_symbols() && priv_->soname.empty() && priv_->needed.empty()); } @@ -991,69 +1056,12 @@ const symtab_reader::symtab_sptr& corpus::get_symtab() const { return priv_->symtab_; } -/// Setter of the function symbols map. -/// -/// @param map a shared pointer to the new function symbols map. -void -corpus::set_fun_symbol_map(string_elf_symbols_map_sptr map) -{priv_->fun_symbol_map = map;} - -/// Setter for the map of function symbols that are undefined in this -/// corpus. -/// -/// @param map a new map for function symbols not defined in this -/// corpus. The key of the map is the name of the function symbol. -/// The value is a vector of all the function symbols that have the -/// same name. -void -corpus::set_undefined_fun_symbol_map(string_elf_symbols_map_sptr map) -{priv_->undefined_fun_symbol_map = map;} - -/// Setter of the variable symbols map. -/// -/// @param map a shared pointer to the new variable symbols map. -void -corpus::set_var_symbol_map(string_elf_symbols_map_sptr map) -{priv_->var_symbol_map = map;} - -/// Setter for the map of variable symbols that are undefined in this -/// corpus. -/// -/// @param map a new map for variable symbols not defined in this -/// corpus. The key of the map is the name of the variable symbol. -/// The value is a vector of all the variable symbols that have the -/// same name. -void -corpus::set_undefined_var_symbol_map(string_elf_symbols_map_sptr map) -{priv_->undefined_var_symbol_map = map;} - -/// Getter for the function symbols map. -/// -/// @return a shared pointer to the function symbols map. -const string_elf_symbols_map_sptr -corpus::get_fun_symbol_map_sptr() const -{ - if (!priv_->fun_symbol_map) - priv_->fun_symbol_map.reset(new string_elf_symbols_map_type); - return priv_->fun_symbol_map; -} - /// Getter for the function symbols map. /// /// @return a reference to the function symbols map. const string_elf_symbols_map_type& corpus::get_fun_symbol_map() const -{return *get_fun_symbol_map_sptr();} - -/// Getter for the map of function symbols that are undefined in this -/// corpus. -/// -/// @return the map of function symbols not defined in this corpus. -/// The key of the map is the name of the function symbol. The value -/// is a vector of all the function symbols that have the same name. -const string_elf_symbols_map_sptr -corpus::get_undefined_fun_symbol_map_sptr() const -{return priv_->undefined_fun_symbol_map;} +{return priv_->get_fun_symbol_map();} /// Getter for the map of function symbols that are undefined in this /// corpus. @@ -1063,7 +1071,7 @@ corpus::get_undefined_fun_symbol_map_sptr() const /// is a vector of all the function symbols that have the same name. const string_elf_symbols_map_type& corpus::get_undefined_fun_symbol_map() const -{return *get_undefined_fun_symbol_map_sptr();} +{return priv_->get_undefined_fun_symbol_map();} const elf_symbols& corpus::get_sorted_fun_symbols() const @@ -1081,33 +1089,12 @@ const elf_symbols& corpus::get_sorted_undefined_var_symbols() const { return priv_->get_sorted_undefined_var_symbols(); } -/// Getter for the variable symbols map. -/// -/// @return a shared pointer to the variable symbols map. -const string_elf_symbols_map_sptr -corpus::get_var_symbol_map_sptr() const -{ - if (!priv_->var_symbol_map) - priv_->var_symbol_map.reset(new string_elf_symbols_map_type); - return priv_->var_symbol_map; -} - /// Getter for the variable symbols map. /// /// @return a reference to the variabl symbols map. const string_elf_symbols_map_type& corpus::get_var_symbol_map() const -{return *get_var_symbol_map_sptr();} - -/// Getter for the map of variable symbols that are undefined in this -/// corpus. -/// -/// @return the map of variable symbols not defined in this corpus. -/// The key of the map is the name of the variable symbol. The value -/// is a vector of all the variable symbols that have the same name. -const string_elf_symbols_map_sptr -corpus::get_undefined_var_symbol_map_sptr() const -{return priv_->undefined_var_symbol_map;} +{return priv_->get_var_symbol_map();} /// Getter for the map of variable symbols that are undefined in this /// corpus. @@ -1117,7 +1104,7 @@ corpus::get_undefined_var_symbol_map_sptr() const /// is a vector of all the variable symbols that have the same name. const string_elf_symbols_map_type& corpus::get_undefined_var_symbol_map() const -{return *get_undefined_var_symbol_map_sptr();} +{return priv_->get_undefined_var_symbol_map();} /// Look in the function symbols map for a symbol with a given name. /// diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 47d561452b05..047f2cb7ab4e 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -14046,54 +14046,6 @@ read_debug_info_into_corpus(read_context& ctxt) // Set symbols information to the corpus. ctxt.current_corpus()->set_symtab(ctxt.symtab()); - if (!get_ignore_symbol_table(ctxt)) - { - if (ctxt.load_in_linux_kernel_mode() - && is_linux_kernel(ctxt.elf_handle())) - { - string_elf_symbols_map_sptr exported_fn_symbols_map - (new string_elf_symbols_map_type); - symtab_reader::symtab_filter filter = - ctxt.symtab()->make_filter().functions(); - - for (symtab_reader::symtab::const_iterator - it = ctxt.symtab()->begin(filter), - end = ctxt.symtab()->end(); - it != end; ++it) - { - (*exported_fn_symbols_map)[(*it)->get_name()].push_back(*it); - } - - ctxt.current_corpus()->set_fun_symbol_map(exported_fn_symbols_map); - - string_elf_symbols_map_sptr exported_var_symbols_map( - new string_elf_symbols_map_type); - filter = ctxt.symtab()->make_filter().variables(); - for (symtab_reader::symtab::const_iterator - it = ctxt.symtab()->begin(filter), - end = ctxt.symtab()->end(); - it != end; ++it) - { - (*exported_var_symbols_map)[(*it)->get_name()].push_back(*it); - } - ctxt.current_corpus()->set_var_symbol_map(exported_var_symbols_map); - } - else - { - ctxt.current_corpus()->set_fun_symbol_map(ctxt.fun_syms_sptr()); - ctxt.current_corpus()->set_var_symbol_map(ctxt.var_syms_sptr()); - } - - ctxt.current_corpus()->set_undefined_fun_symbol_map - (ctxt.undefined_fun_syms_sptr()); - ctxt.current_corpus()->set_undefined_var_symbol_map - (ctxt.undefined_var_syms_sptr()); - } - else - { - ctxt.current_corpus()->set_fun_symbol_map(ctxt.fun_syms_sptr()); - ctxt.current_corpus()->set_var_symbol_map(ctxt.var_syms_sptr()); - } // Get out now if no debug info is found. if (!ctxt.dwarf()) diff --git a/src/abg-reader.cc b/src/abg-reader.cc index 313639fddff0..fbdcce590bc3 100644 --- a/src/abg-reader.cc +++ b/src/abg-reader.cc @@ -1974,17 +1974,6 @@ read_corpus_from_input(read_context& ctxt) // are nil, due to potential suppression specifications. That's // fine. corp.set_symtab(symtab_reader::symtab::load(fn_sym_db, var_sym_db)); - - if (fn_sym_db) - { - corp.set_fun_symbol_map(fn_sym_db); - fn_sym_db.reset(); - } - if (var_sym_db) - { - corp.set_var_symbol_map(var_sym_db); - var_sym_db.reset(); - } } ctxt.get_environment()->canonicalization_is_done(false); diff --git a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi index d5af7183095f..24c25c06d61c 100644 --- a/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi +++ b/tests/data/test-read-dwarf/PR25007-sdhci.ko.abi @@ -37,8 +37,6 @@ - - diff --git a/tests/test-symtab.cc b/tests/test-symtab.cc index 905d8249a6e4..c144b1d080f6 100644 --- a/tests/test-symtab.cc +++ b/tests/test-symtab.cc @@ -104,17 +104,19 @@ assert_symbol_count(const std::string& path, REQUIRE((status & dwarf_reader::STATUS_OK)); const corpus& corpus = *corpus_ptr; + size_t total_symbols = 0; + if (function_symbols != N) { CHECK(corpus.get_sorted_fun_symbols().size() == function_symbols); CHECK(corpus.get_fun_symbol_map().size() == function_symbols); - CHECK(corpus.get_fun_symbol_map_sptr()->size() == function_symbols); + total_symbols += function_symbols; } if (variable_symbols != N) { CHECK(corpus.get_sorted_var_symbols().size() == variable_symbols); CHECK(corpus.get_var_symbol_map().size() == variable_symbols); - CHECK(corpus.get_var_symbol_map_sptr()->size() == variable_symbols); + total_symbols += variable_symbols; } if (undefined_variable_symbols != N) { @@ -122,8 +124,7 @@ assert_symbol_count(const std::string& path, == undefined_function_symbols); CHECK(corpus.get_undefined_fun_symbol_map().size() == undefined_function_symbols); - CHECK(corpus.get_undefined_fun_symbol_map_sptr()->size() - == undefined_function_symbols); + total_symbols += undefined_function_symbols; } if (undefined_function_symbols != N) { @@ -131,10 +132,12 @@ assert_symbol_count(const std::string& path, == undefined_variable_symbols); CHECK(corpus.get_undefined_var_symbol_map().size() == undefined_variable_symbols); - CHECK(corpus.get_undefined_var_symbol_map_sptr()->size() - == undefined_variable_symbols); + total_symbols += undefined_variable_symbols; } + // assert the corpus reports being empty consistently with the symbol count + CHECK(corpus.is_empty() == (total_symbols == 0)); + return corpus_ptr; } From patchwork Fri Jul 3 16:46:46 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: 39900 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 0BDCC384242C; Fri, 3 Jul 2020 16:48:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0BDCC384242C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794896; bh=Mv50xw2jLYc1GuXm2LQSpIsTlV1Fr3eOQNG6iHcluCw=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ueuqK+R3BA3cAwqYhXFAHx6JtHcTPMl0O/B9qpoOZicJE5MUroBKZUAUJEU+AtU9h 7JOH/9PEyZZRxHITSmY0cal9ysI5n6ZOhO4bRdBRDOEH3ndbk5Pxf56s8UVedVfeWg lXt5VYwIQaGMlu/+6Eu9pcoquMZGEezo7M+OS77U= 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 DD4793844079 for ; Fri, 3 Jul 2020 16:48:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org DD4793844079 Received: by mail-wr1-x449.google.com with SMTP id i14so32068384wru.17 for ; Fri, 03 Jul 2020 09:48:10 -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=Mv50xw2jLYc1GuXm2LQSpIsTlV1Fr3eOQNG6iHcluCw=; b=lLPe/VEfOu8+tc//dHZ672s4gD1gdFKWpkOkOk8i7DAvgSc4kT53WavVkB8pyyoJYF ZajD8g5kKdnEvozW0Yqzd3o5GMg2YeFhLGK6kfYMH9FUECGazUTIcsPmzv6dbdievVQh zeu5lleG54gn2RGND8TrX2cmNv51cjZH22v6wQ7sBK889D1nhybsrOYt0PR8pOiWzF3j OxTQgPU30KXiI/d9EqhoBmeNEHggaQRB07iOgM+vN2T7Z9fB0eS0LFyCwl3gYy0zv12x phwxL1YGylQ3NNt3Kgo2l2KQkiVly/ie4RwqK5IuQxrKuVtj+RG7LIOGsa7LXnK2Y2hC kvOQ== X-Gm-Message-State: AOAM530hRjFY6gKXZeVWD5rPTve0/6aF6IbBw1ECKUmsxqqgTQVRPaHi 7mrEJgfPO+YwHqTTS6RDsDNYD18VGnl51PRcqeZE8N0X62BL03ZkM5ehd7c1mZzGx8Hojh0bVdq HdhCiqMy+sXy7XpaB/NAOTzHhHIu4a46C64kfw1IQkG0heq8s5mW/SVz9BYeXuRvcuadXxwE= X-Google-Smtp-Source: ABdhPJwm1zB6daCXgMS2PuFGWbCtWXAd2bxgHrqNXPSqqs2RfKyF/WS9Qwig+LioibrGm9sjHKCgfwEuxuCKVA== X-Received: by 2002:adf:edc6:: with SMTP id v6mr37983969wro.413.1593794889830; Fri, 03 Jul 2020 09:48:09 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:46 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-17-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 16/21] dwarf reader: drop now-unused code related to symbol table reading To: libabigail@sourceware.org X-Spam-Status: No, score=-23.2 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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 introduction of the new symtab reader incorporated much of the existing functionality. Now that the most code parts are migrated to the new symtab reader, we can safely remove the old code paths. Ignoring the symbol table is not a thing anymore. The new symtab reader does read the symtab unconditionally for consistency reasons. Hence also remove all functionality around conditional symtab reading. * include/abg-dwarf-reader.h (set_ignore_symbol_table): Remove. (get_ignore_symbol_table): Likewise. * src/abg-dwarf-reader.cc (add_symbol_to_map): Likewise. (read_context::options_type::ignore_symbol_table): Likewise. (read_context::options_type): Adjust. (read_context::fun_addr_sym_map_): Remove. (read_context::fun_entry_addr_sym_map_): Likewise. (read_context::fun_syms_): Likewise. (read_context::var_addr_sym_map_): Likewise. (read_context::var_syms_): Likewise. (read_context::undefined_fun_syms_): Likewise. (read_context::undefined_var_syms_): Likewise. (read_context::initialize): Adjust. (read_context::lookup_elf_symbol_from_index): Remove. (read_context::fun_entry_addr_sym_map_sptr): Likewise. (read_context::fun_entry_addr_sym_map): Likewise. (read_context::fun_syms_sptr): Likewise. (read_context::fun_syms): Likewise. (read_context::var_syms_sptr): Likewise. (read_context::var_syms): Likewise. (read_context::undefined_fun_syms_sptr): Likewise. (read_context::undefined_var_syms_sptr): Likewise. (read_context::load_symbol_maps_from_symtab_section): Likewise. (read_context::load_symbol_maps): Likewise. (read_context::maybe_load_symbol_maps): Likewise. (set_ignore_symbol_table): Likewise. (get_ignore_symbol_table): Likewise. (create_default_var_sym): Likewise. (build_var_decl): Adjust. (function_is_suppressed): Likewise. (variable_is_suppressed): Likewise. (build_function_decl): Likewise. (add_symbol_to_map): Remove. (read_corpus_from_elf): Adjust. (build_corpus_group_from_kernel_dist_under): Likewise. * tools/abidw.cc (main): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-dwarf-reader.h | 6 - src/abg-dwarf-reader.cc | 656 +------------------------------------ src/abg-tools-utils.cc | 13 - tools/abidw.cc | 2 - 4 files changed, 12 insertions(+), 665 deletions(-) diff --git a/include/abg-dwarf-reader.h b/include/abg-dwarf-reader.h index d0329aed9ccf..3f062e04502d 100644 --- a/include/abg-dwarf-reader.h +++ b/include/abg-dwarf-reader.h @@ -195,12 +195,6 @@ set_drop_undefined_syms(read_context& ctxt, void set_do_log(read_context& ctxt, bool f); -void -set_ignore_symbol_table(read_context &ctxt, bool f); - -bool -get_ignore_symbol_table(const read_context &ctxt); - void set_environment(read_context& ctxt, ir::environment*); diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 047f2cb7ab4e..6ed316e19ac1 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -291,10 +291,6 @@ static bool operator<(const imported_unit_point& l, const imported_unit_point& r) {return l.offset_of_import < r.offset_of_import;} -static void -add_symbol_to_map(const elf_symbol_sptr& sym, - string_elf_symbols_map_type& map); - static bool get_parent_die(const read_context& ctxt, const Dwarf_Die* die, @@ -1940,7 +1936,6 @@ public: environment* env; bool load_in_linux_kernel_mode; bool load_all_types; - bool ignore_symbol_table; bool show_stats; bool do_log; @@ -1948,7 +1943,6 @@ public: : env(), load_in_linux_kernel_mode(), load_all_types(), - ignore_symbol_table(), show_stats(), do_log() {} @@ -2144,19 +2138,6 @@ public: offset_offset_map_type alternate_die_parent_map_; offset_offset_map_type type_section_die_parent_map_; list var_decls_to_add_; - addr_elf_symbol_sptr_map_sptr fun_addr_sym_map_; - // On PPC64, the function entry point address is different from the - // GElf_Sym::st_value value, which is the address of the descriptor - // of the function. The map below thus associates the address of - // the entry point to the function symbol. If we are not on ppc64, - // then this map ought to be empty. Only the fun_addr_sym_map_ is - // used in that case. On ppc64, though, both maps are used. - addr_elf_symbol_sptr_map_sptr fun_entry_addr_sym_map_; - string_elf_symbols_map_sptr fun_syms_; - addr_elf_symbol_sptr_map_sptr var_addr_sym_map_; - string_elf_symbols_map_sptr var_syms_; - string_elf_symbols_map_sptr undefined_fun_syms_; - string_elf_symbols_map_sptr undefined_var_syms_; vector dt_needed_; string dt_soname_; string elf_architecture_; @@ -2292,13 +2273,6 @@ public: alternate_die_parent_map_.clear(); type_section_die_parent_map_.clear(); var_decls_to_add_.clear(); - fun_addr_sym_map_.reset(); - fun_entry_addr_sym_map_.reset(); - fun_syms_.reset(); - var_addr_sym_map_.reset(); - var_syms_.reset(); - undefined_fun_syms_.reset(); - undefined_var_syms_.reset(); dt_needed_.clear(); dt_soname_.clear(); elf_architecture_.clear(); @@ -4958,88 +4932,6 @@ public: return true; } - /// Given the index of a symbol into the symbol table of an ELF - /// file, look the symbol up, build an instace of @ref elf_symbol - /// and return it. - /// - /// @param symbol_index the index of the symbol into the symbol - /// table of the current elf file. - /// - /// @return the elf symbol found or nil if none was found. - elf_symbol_sptr - lookup_elf_symbol_from_index(size_t symbol_index) - { - GElf_Sym s; - elf_symbol_sptr result = - lookup_elf_symbol_from_index(symbol_index, s); - return result; - } - - /// Lookup an ELF symbol given its index into the .symtab section. - /// - /// This function returns both the native symbol (from libelf) and - /// the @p abigail::ir::elf_symbol instance, which is the - /// libabigail-specific representation of the symbol. - /// - /// @param symbol_index the index of the symbol to look for. - /// - /// @param native_sym output parameter. This is set to the native - /// ELF symbol found iff the function returns a non-nil value. - /// - /// @return an instance of libabigail::ir::elf_symbol representing - /// the ELF symbol found, iff one was found. Otherwise, returns - /// nil. - elf_symbol_sptr - lookup_elf_symbol_from_index(size_t symbol_index, - GElf_Sym &native_sym) - { - if (!lookup_native_elf_symbol_from_index(symbol_index, native_sym)) - return elf_symbol_sptr(); - - Elf_Scn* symtab_section = find_symbol_table_section(); - if (!symtab_section) - return elf_symbol_sptr(); - - GElf_Shdr header_mem; - GElf_Shdr* symtab_sheader = gelf_getshdr(symtab_section, - &header_mem); - - Elf_Data* symtab = elf_getdata(symtab_section, 0); - ABG_ASSERT(symtab); - - bool sym_is_defined = native_sym.st_shndx != SHN_UNDEF; - bool sym_is_common = native_sym.st_shndx == SHN_COMMON; // this occurs in - // relocatable - // files. - const char* name_str = elf_strptr(elf_handle(), - symtab_sheader->sh_link, - native_sym.st_name); - if (name_str == 0) - name_str = ""; - - elf_symbol::version ver; - elf_helpers::get_version_for_symbol(elf_handle(), symbol_index, - sym_is_defined, ver); - - elf_symbol::visibility vis = - stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(native_sym.st_other)); - - Elf_Scn* strings_section = find_ksymtab_strings_section(elf_handle()); - size_t strings_ndx = strings_section - ? elf_ndxscn(strings_section) - : 0; - - elf_symbol_sptr sym = - elf_symbol::create(env(), symbol_index, native_sym.st_size, - name_str, stt_to_elf_symbol_type - (GELF_ST_TYPE(native_sym.st_info)), - stb_to_elf_symbol_binding - (GELF_ST_BIND(native_sym.st_info)), - sym_is_defined, sym_is_common, ver, vis, - native_sym.st_shndx == strings_ndx); - return sym; - } - /// Test if a given function symbol has been exported. /// /// @param symbol_address the address of the symbol we are looking @@ -5120,102 +5012,6 @@ public: return symtab_; } - /// Getter for a pointer to the map that associates the address of - /// an entry point of a function with the symbol of that function. - /// - /// Note that on non-"PPC64 ELFv1" binaries, this map is the same as - /// the one that assciates the address of a function with the symbol - /// of that function. - /// - /// @return a pointer to the map that associates the address of an - /// entry point of a function with the symbol of that function. - addr_elf_symbol_sptr_map_sptr& - fun_entry_addr_sym_map_sptr() - { - if (!fun_entry_addr_sym_map_ && !fun_addr_sym_map_) - maybe_load_symbol_maps(); - if (architecture_is_ppc64(elf_handle())) - return fun_entry_addr_sym_map_; - return fun_addr_sym_map_; - } - - /// Getter for the map that associates the address of an entry point - /// of a function with the symbol of that function. - /// - /// Note that on non-"PPC64 ELFv1" binaries, this map is the same as - /// the one that assciates the address of a function with the symbol - /// of that function. - /// - /// @return the map that associates the address of an entry point of - /// a function with the symbol of that function. - addr_elf_symbol_sptr_map_type& - fun_entry_addr_sym_map() - {return *fun_entry_addr_sym_map_sptr();} - - /// Getter for the map of function symbols (name -> sym). - /// - /// @return a shared pointer to the map of function symbols. - const string_elf_symbols_map_sptr& - fun_syms_sptr() const - { - maybe_load_symbol_maps(); - return fun_syms_; - } - - /// Getter for the map of function symbols (name -> sym). - /// - /// @return a reference to the map of function symbols. - string_elf_symbols_map_type& - fun_syms() - { - maybe_load_symbol_maps(); - return *fun_syms_; - } - - /// Getter for the map of variable symbols (name -> sym) - /// - /// @return a shared pointer to the map of variable symbols. - const string_elf_symbols_map_sptr - var_syms_sptr() const - { - maybe_load_symbol_maps(); - return var_syms_; - } - - /// Getter for the map of variable symbols (name -> sym) - /// - /// @return a reference to the map of variable symbols. - string_elf_symbols_map_type& - var_syms() - { - maybe_load_symbol_maps(); - return *var_syms_; - } - - /// Getter for the map of undefined function symbols (name -> vector - /// of symbols). - /// - /// @return a (smart) pointer to the map of undefined function - /// symbols. - const string_elf_symbols_map_sptr& - undefined_fun_syms_sptr() const - { - maybe_load_symbol_maps(); - return undefined_fun_syms_; - } - - /// Getter for the map of undefined variable symbols (name -> vector - /// of symbols). - /// - /// @return a (smart) pointer to the map of undefined variable - /// symbols. - const string_elf_symbols_map_sptr& - undefined_var_syms_sptr() const - { - maybe_load_symbol_maps(); - return undefined_var_syms_; - } - /// Getter for the ELF dt_needed tag. const vector& dt_needed() const @@ -5231,232 +5027,6 @@ public: elf_architecture() const {return elf_architecture_;} - /// Load the maps address -> function symbol, address -> variable - /// symbol and the maps of function and variable undefined symbols. - /// - /// @param load_fun_map whether to load the address to function map. - /// - /// @param load_var_map whether to laod the address to variable map. - /// - /// @param load_undefined_fun_map whether to load the undefined - /// function map. - /// - /// @param load_undefined_var_map whether to laod the undefined - /// variable map. - /// - /// @return return true iff the maps have be loaded. - bool - load_symbol_maps_from_symtab_section(bool load_fun_map, - bool load_var_map, - bool load_undefined_fun_map, - bool load_undefined_var_map) - { - Elf_Scn* symtab_section = find_symbol_table_section(); - if (!symtab_section) - return false; - - GElf_Shdr header_mem; - GElf_Shdr* symtab_sheader = gelf_getshdr(symtab_section, - &header_mem); - - // check for bogus section header - if (symtab_sheader->sh_entsize == 0) - return false; - - size_t nb_syms = symtab_sheader->sh_size / symtab_sheader->sh_entsize; - - Elf_Data* symtab = elf_getdata(symtab_section, 0); - if (!symtab) - return false; - - GElf_Ehdr elf_header; - ABG_ASSERT(gelf_getehdr(elf_handle(), &elf_header)); - - bool is_ppc64 = architecture_is_ppc64(elf_handle()); - - for (size_t i = 0; i < nb_syms; ++i) - { - GElf_Sym* sym, sym_mem; - sym = gelf_getsym(symtab, i, &sym_mem); - ABG_ASSERT(sym); - - if ((load_fun_map || load_undefined_fun_map) - && (GELF_ST_TYPE(sym->st_info) == STT_FUNC - || GELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC)) - { - elf_symbol_sptr symbol = lookup_elf_symbol_from_index(i); - ABG_ASSERT(symbol); - ABG_ASSERT(symbol->is_function()); - - // If the symbol was suppressed by a suppression - // specification then drop it on the floor. - if (is_elf_symbol_suppressed(symbol)) - continue; - - if (load_fun_map && symbol->is_public()) - { - (*fun_syms_)[symbol->get_name()].push_back(symbol); - - { - GElf_Addr symbol_value = - maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle(), - sym); - - addr_elf_symbol_sptr_map_type::const_iterator it = - fun_addr_sym_map_->find(symbol_value); - if (it == fun_addr_sym_map_->end()) - (*fun_addr_sym_map_)[symbol_value] = symbol; - else //if (sym->st_value != 0) - it->second->get_main_symbol()->add_alias(symbol); - - if (is_ppc64) - { - // For ppc64 ELFv1 binaries, we need to build a - // function entry point address -> function - // symbol map. This is in addition to the - // function pointer -> symbol map. This is - // because on ppc64 ELFv1, a function pointer is - // different from a function entry point - // address. - // - // On ppc64 ELFv1, the DWARF DIE of a function - // references the address of the entry point of - // the function symbol; whereas the value of the - // function symbol is the function pointer. As - // these addresses are different, if I we want - // to get to the symbol of a function from its - // entry point address (as referenced by DWARF - // function DIEs) we must have the two maps I - // mentionned right above. - // - // In other words, we need a map that associates - // a function enty point address with the symbol - // of that function, to be able to get the - // function symbol that corresponds to a given - // function DIE, on ppc64. - // - // The value of the function pointer (the value - // of the symbol) usually refers to the offset - // of a table in the .opd section. But - // sometimes, for a symbol named "foo", the - // corresponding symbol named ".foo" (note the - // dot before foo) which value is the entry - // point address of the function; that entry - // point address refers to a region in the .text - // section. - // - // So we are only interested in values of the - // symbol that are in the .opd section. - GElf_Addr fn_desc_addr = sym->st_value; - GElf_Addr fn_entry_point_addr = - lookup_ppc64_elf_fn_entry_point_address( - elf_handle(), fn_desc_addr); - addr_elf_symbol_sptr_map_type::const_iterator it2 = - fun_entry_addr_sym_map().find(fn_entry_point_addr); - - if (it2 == fun_entry_addr_sym_map().end()) - fun_entry_addr_sym_map()[fn_entry_point_addr] = symbol; - else if (address_is_in_opd_section(elf_handle(), - fn_desc_addr)) - { - // Either - // - // 'symbol' must have been registered as an - // alias for it2->second->get_main_symbol(), - // right before the "if (ppc64)" statement. - // - // Or - // - // if the name of 'symbol' is foo, then the - // name of it2->second is ".foo". That is, - // foo is the name of the symbol when it - // refers to the function descriptor in the - // .opd section and ".foo" is an internal - // name for the address of the entry point - // of foo. - // - // In the latter case, we just want to keep - // a refernce to "foo" as .foo is an - // internal name. - - bool two_symbols_alias = - it2->second->get_main_symbol()->does_alias(*symbol); - bool symbol_is_foo_and_prev_symbol_is_dot_foo = - (it2->second->get_name() - == string(".") + symbol->get_name()); - - ABG_ASSERT(two_symbols_alias - || symbol_is_foo_and_prev_symbol_is_dot_foo); - - if (symbol_is_foo_and_prev_symbol_is_dot_foo) - // Let's just keep a reference of the - // symbol that the user sees in the source - // code (the one named foo). The symbol - // which name is prefixed with a "dot" is - // an artificial one. - fun_entry_addr_sym_map()[fn_entry_point_addr] = symbol; - } - } - } - } - else if (load_undefined_fun_map && !symbol->is_defined()) - (*undefined_fun_syms_)[symbol->get_name()].push_back(symbol); - } - else if ((load_var_map || load_undefined_var_map) - && (GELF_ST_TYPE(sym->st_info) == STT_OBJECT - || GELF_ST_TYPE(sym->st_info) == STT_TLS) - // If the symbol is for an OBJECT, the index of the - // section it refers to cannot be absolute. - // Otherwise that OBJECT is not a variable. - && (sym->st_shndx != SHN_ABS - || GELF_ST_TYPE(sym->st_info) != STT_OBJECT )) - { - elf_symbol_sptr symbol = lookup_elf_symbol_from_index(i); - ABG_ASSERT(symbol); - ABG_ASSERT(symbol->is_variable()); - - if (load_var_map && symbol->is_public()) - { - (*var_syms_)[symbol->get_name()].push_back(symbol); - - if (symbol->is_common_symbol()) - { - string_elf_symbols_map_type::iterator it = - var_syms_->find(symbol->get_name()); - ABG_ASSERT(it != var_syms_->end()); - const elf_symbols& common_sym_instances = it->second; - ABG_ASSERT(!common_sym_instances.empty()); - if (common_sym_instances.size() > 1) - { - elf_symbol_sptr main_common_sym = - common_sym_instances[0]; - ABG_ASSERT(main_common_sym->get_name() - == symbol->get_name()); - ABG_ASSERT(main_common_sym->is_common_symbol()); - ABG_ASSERT(symbol.get() != main_common_sym.get()); - main_common_sym->add_common_instance(symbol); - } - } - else - { - GElf_Addr symbol_value = - maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle(), - sym); - addr_elf_symbol_sptr_map_type::const_iterator it = - var_addr_sym_map_->find(symbol_value); - if (it == var_addr_sym_map_->end()) - (*var_addr_sym_map_)[symbol_value] = symbol; - else - it->second->get_main_symbol()->add_alias(symbol); - } - } - else if (load_undefined_var_map && !symbol->is_defined()) - (*undefined_var_syms_)[symbol->get_name()].push_back(symbol); - } - } - return true; - } - /// Test if a given ELF symbol was suppressed by a suppression /// specification. /// @@ -5472,71 +5042,6 @@ public: symbol->get_type())); } - /// Load the maps of function symbol address -> function symbol, - /// global variable symbol address -> variable symbol and also the - /// maps of function and variable undefined symbols. - /// - /// All these maps are loaded only if they are not loaded already. - /// - /// @return true iff everything went fine. - bool - load_symbol_maps() - { - bool load_fun_map = !fun_addr_sym_map_ ; - bool load_var_map = !var_addr_sym_map_; - bool load_undefined_fun_map = !undefined_fun_syms_; - bool load_undefined_var_map = !undefined_var_syms_; - - if (!fun_syms_) - fun_syms_.reset(new string_elf_symbols_map_type); - - if (!fun_addr_sym_map_) - fun_addr_sym_map_.reset(new addr_elf_symbol_sptr_map_type); - - if (!fun_entry_addr_sym_map_ && architecture_is_ppc64(elf_handle())) - fun_entry_addr_sym_map_.reset(new addr_elf_symbol_sptr_map_type); - - if (!var_syms_) - var_syms_.reset(new string_elf_symbols_map_type); - - if (!var_addr_sym_map_) - var_addr_sym_map_.reset(new addr_elf_symbol_sptr_map_type); - - if (!undefined_fun_syms_) - undefined_fun_syms_.reset(new string_elf_symbols_map_type); - - if (!undefined_var_syms_) - undefined_var_syms_.reset(new string_elf_symbols_map_type); - - if (!options_.ignore_symbol_table) - { - if (load_symbol_maps_from_symtab_section(load_fun_map, - load_var_map, - load_undefined_fun_map, - load_undefined_var_map)) - return true; - return false; - } - return true; - } - - /// Load the symbol maps if necessary. - /// - /// @return true iff the symbol maps has been loaded by this - /// invocation. - bool - maybe_load_symbol_maps() const - { - if (!fun_addr_sym_map_ - || !var_addr_sym_map_ - || !fun_syms_ - || !var_syms_ - || !undefined_fun_syms_ - || !undefined_var_syms_) - return const_cast(this)->load_symbol_maps(); - return false; - } - /// Load the DT_NEEDED and DT_SONAME elf TAGS. /// void @@ -6408,46 +5913,6 @@ void set_do_log(read_context& ctxt, bool f) {ctxt.do_log(f);} -/// Setter of the "set_ignore_symbol_table" flag. -/// -/// This flag tells if we should load information about ELF symbol -/// tables. Not loading the symbol tables is a speed optimization -/// that is done when the set of symbols we care about is provided -/// off-hand. This is the case when we are supposed to analyze a -/// Linux kernel binary. In that case, because we have the white list -/// of functions/variable symbols we care about, we don't need to -/// analyze the symbol table; things are thus faster in that case. -/// -/// By default, the symbol table is analyzed so this boolean is set to -/// false. -/// -/// @param ctxt the read context to consider. -/// -/// @param f the new value of the flag. -void -set_ignore_symbol_table(read_context &ctxt, bool f) -{ctxt.options_.ignore_symbol_table = f;} - -/// Getter of the "set_ignore_symbol_table" flag. -/// -/// This flag tells if we should load information about ELF symbol -/// tables. Not loading the symbol tables is a speed optimization -/// that is done when the set of symbols we care about is provided -/// off-hand. This is the case when we are supposed to analyze a -/// Linux kernel binary. In that case, because we have the white list -/// of functions/variable symbols we care about, we don't need to -/// analyze the symbol table; things are thus faster in that case. -/// -/// By default, the symbol table is analyzed so this boolean is set to -/// false. -/// -/// @param ctxt the read context to consider. -/// -/// @return the value of the flag. -bool -get_ignore_symbol_table(const read_context& ctxt) -{return ctxt.options_.ignore_symbol_table;} - /// Test if a given DIE is anonymous /// /// @param die the DIE to consider. @@ -13396,33 +12861,6 @@ build_or_get_var_decl_if_not_suppressed(read_context& ctxt, return var; } -/// Create a variable symbol with a given name. -/// -/// @param sym_name the name of the variable symbol. -/// -/// @param env the environment to create the default symbol in. -/// -/// @return the newly created symbol. -static elf_symbol_sptr -create_default_var_sym(const string& sym_name, const environment *env) -{ - elf_symbol::version ver; - elf_symbol::visibility vis = elf_symbol::DEFAULT_VISIBILITY; - elf_symbol_sptr result = - elf_symbol::create(env, - /*symbol index=*/ 0, - /*symbol size=*/ 0, - sym_name, - /*symbol type=*/ elf_symbol::OBJECT_TYPE, - /*symbol binding=*/ elf_symbol::GLOBAL_BINDING, - /*symbol is defined=*/ true, - /*symbol is common=*/ false, - /*symbol version=*/ ver, - /*symbol_visibility=*/vis, - /*is_linux_string_cst=*/false); - return result; -} - /// Build a @ref var_decl out of a DW_TAG_variable DIE. /// /// @param ctxt the read context to use. @@ -13494,23 +12932,9 @@ build_var_decl(read_context& ctxt, if (!result->get_symbol()) { elf_symbol_sptr var_sym; - if (get_ignore_symbol_table(ctxt)) - { - string var_name = - result->get_linkage_name().empty() - ? result->get_name() - : result->get_linkage_name(); - - var_sym = create_default_var_sym(var_name, ctxt.env()); - ABG_ASSERT(var_sym); - add_symbol_to_map(var_sym, ctxt.var_syms()); - } - else - { - Dwarf_Addr var_addr; - if (ctxt.get_variable_address(die, var_addr)) - var_sym = var_sym = ctxt.variable_symbol_is_exported(var_addr); - } + Dwarf_Addr var_addr; + if (ctxt.get_variable_address(die, var_addr)) + var_sym = var_sym = ctxt.variable_symbol_is_exported(var_addr); if (var_sym) { @@ -13571,15 +12995,9 @@ function_is_suppressed(const read_context& ctxt, Dwarf_Addr fn_addr; if (!ctxt.get_function_address(function_die, fn_addr)) return true; - if (!get_ignore_symbol_table(ctxt)) - { - // We were not instructed to ignore (avoid loading) the - // symbol table, so we can rely on its presence to see if - // the address corresponds to the address of an exported - // function symbol. - if (!ctxt.function_symbol_is_exported(fn_addr)) - return true; - } + + if (!ctxt.function_symbol_is_exported(fn_addr)) + return true; } return suppr::function_is_suppressed(ctxt, qualified_name, @@ -13682,15 +13100,9 @@ variable_is_suppressed(const read_context& ctxt, Dwarf_Addr var_addr = 0; if (!ctxt.get_variable_address(variable_die, var_addr)) return true; - if (!get_ignore_symbol_table(ctxt)) - { - // We were not instructed to ignore (avoid loading) the - // symbol table, so we can rely on its presence to see if - // the address corresponds to the address of an exported - // variable symbol. - if (!ctxt.variable_symbol_is_exported(var_addr)) - return true; - } + + if (!ctxt.variable_symbol_is_exported(var_addr)) + return true; } return suppr::variable_is_suppressed(ctxt, qualified_name, @@ -13941,23 +13353,9 @@ build_function_decl(read_context& ctxt, if (!result->get_symbol()) { elf_symbol_sptr fn_sym; - if (get_ignore_symbol_table(ctxt)) - { - string fn_name = - result->get_linkage_name().empty() - ? result->get_name() - : result->get_linkage_name(); - - fn_sym = create_default_fn_sym(fn_name, ctxt.env()); - ABG_ASSERT(fn_sym); - add_symbol_to_map(fn_sym, ctxt.fun_syms()); - } - else - { - Dwarf_Addr fn_addr; - if (ctxt.get_function_address(die, fn_addr)) - fn_sym = ctxt.function_symbol_is_exported(fn_addr); - } + Dwarf_Addr fn_addr; + if (ctxt.get_function_address(die, fn_addr)) + fn_sym = ctxt.function_symbol_is_exported(fn_addr); if (fn_sym) { @@ -13987,29 +13385,6 @@ build_function_decl(read_context& ctxt, return result; } -/// Add a symbol to a symbol map. -/// -/// @param sym the symbol to add. -/// -/// @param map the symbol map to add the symbol into. -static void -add_symbol_to_map(const elf_symbol_sptr& sym, - string_elf_symbols_map_type& map) -{ - if (!sym) - return; - - string_elf_symbols_map_type::iterator it = map.find(sym->get_name()); - if (it == map.end()) - { - elf_symbols syms; - syms.push_back(sym); - map[sym->get_name()] = syms; - } - else - it->second.push_back(sym); -} - /// Read all @ref abigail::translation_unit possible from the debug info /// accessible through a DWARF Front End Library handle, and stuff /// them into a libabigail ABI Corpus. @@ -15254,13 +14629,6 @@ read_corpus_from_elf(read_context& ctxt, status& status) ctxt.load_elf_properties(); // DT_SONAME, DT_NEEDED, architecture - if (!get_ignore_symbol_table(ctxt)) - { - // Read the symbols for publicly defined decls - if (!ctxt.load_symbol_maps()) - status |= STATUS_NO_SYMBOLS_FOUND; - } - if (!ctxt.symtab() || !ctxt.symtab()->has_symbols()) status |= STATUS_NO_SYMBOLS_FOUND; diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index dfbec879de8d..9116a97a62e9 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -2563,12 +2563,6 @@ build_corpus_group_from_kernel_dist_under(const string& root, << t << "\n"; - // If we have been given a whitelist of functions and - // variable symbols to look at, then we can avoid loading - // and analyzing the ELF symbol table. - bool do_ignore_symbol_table = !kabi_wl_paths.empty(); - set_ignore_symbol_table(*ctxt, do_ignore_symbol_table); - group.reset(new corpus_group(env.get(), root)); set_read_context_corpus_group(*ctxt, group); @@ -2608,13 +2602,6 @@ build_corpus_group_from_kernel_dist_under(const string& root, /*read_all_types=*/false, /*linux_kernel_mode=*/true); - // If we have been given a whitelist of functions and - // variable symbols to look at, then we can avoid loading - // and analyzing the ELF symbol table. - bool do_ignore_symbol_table = !kabi_wl_paths.empty(); - - set_ignore_symbol_table(*ctxt, do_ignore_symbol_table); - load_generate_apply_suppressions(*ctxt, suppr_paths, kabi_wl_paths, supprs); diff --git a/tools/abidw.cc b/tools/abidw.cc index 2cd848df9fb8..58072e7072c4 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -828,8 +828,6 @@ main(int argc, char* argv[]) set_show_stats(ctxt, opts.show_stats); set_suppressions(ctxt, opts); abigail::dwarf_reader::set_do_log(ctxt, opts.do_log); - if (!opts.kabi_whitelist_supprs.empty()) - set_ignore_symbol_table(ctxt, true); if (opts.check_alt_debug_info_path) { From patchwork Fri Jul 3 16:46:47 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: 39899 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 BC6443844079; Fri, 3 Jul 2020 16:48:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BC6443844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794895; bh=ACW4NTs2rb1Hm2r6942mLHToSqbV3FL5hMaO186AlZE=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=pEsq3SSgdj3ltQ46wIOwddCWAgJapkzo5OrHW8eA1vQPqScfQ9MSNReksitSvM9rs RRIIiS19SXqFveCGmZYKYQneGwgENhiJ5EVWVda+DqEuZgDF8SgUK2j4tOI6dvylZr 4VeeuERs2ayOhUtwmppUp5H0joTBnSNYokTh/q+0= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by sourceware.org (Postfix) with ESMTPS id 5A038386F028 for ; Fri, 3 Jul 2020 16:48:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5A038386F028 Received: by mail-qk1-x749.google.com with SMTP id i145so3121206qke.2 for ; Fri, 03 Jul 2020 09:48:12 -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=ACW4NTs2rb1Hm2r6942mLHToSqbV3FL5hMaO186AlZE=; b=jVvM+V8XlhA0CPdRMEncg8Gwii7O36yi6kLpH2kjI7YwQMISyqf6NPxuTJ67QB24Kd b/sTFnFrEYeD7nxsZ1o6QWmKegIwxzEiU6tWwgxIb4+sARTH3dEl0nA+oulinYtPpsf3 k1LS4uFc8bPXRCFjAcfoPfryyUykWAGMVIY+hgasIkcG2hm5qnv/EpDSi1QFJDpyDXzN F8OwYP6kiQ7kVduCe50jc7fppmVt53shVQ1fhhgW3mHWfWT9JD4+wx9o3B4lCUjW5EsD nWe0v3HAE9RHs4yoOa7oOKBu0UB8TGOHdce0hMjms02vCCikuUYgx9swyLme4UZwq7JZ W0DA== X-Gm-Message-State: AOAM530uqKRt4G9DdA21njjFs+uhnUl+NS594Ng7oDjmLPP93I0bN5qF P8nkwYz18+8BUnLSKqFZ2Vrgu6lFQ9vHTp8RVImoRS9jh+LMIjvO57Hqgh2iiMs8GN/iXqyciqh BmExOSG6m7mKWMW/PIuY3P+H9S+rflL7HKMYxqRznGxaWa4lxLFmPRUs3RBbaP9nWvpbS2tw= X-Google-Smtp-Source: ABdhPJyQSgjNu4cRsYTycTlw/cmYcYNefw7qWE8QoK/tYWmZpyIPxZxTmdzIGuykRu6jw0V2xZe32l2R50n3jQ== X-Received: by 2002:a0c:bd2c:: with SMTP id m44mr36884517qvg.195.1593794891901; Fri, 03 Jul 2020 09:48:11 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:47 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-18-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 17/21] test-symtab: add tests for whitelisted functions To: libabigail@sourceware.org X-Spam-Status: No, score=-22.7 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" Extend the test functionality in test-symtab to allow processing of KMI whitelists and add additional test cases for whitelist handling. * tests/data/Makefile.am: add new test files * tests/data/test-symtab/basic/ofov_all.whitelist: New test file, * tests/data/test-symtab/basic/ofov_function.whitelist: Likewise. * tests/data/test-symtab/basic/ofov_irrelevant.whitelist: Likewise. * tests/data/test-symtab/basic/ofov_variable.whitelist: Likewise. * tests/test-symtab.cc (read_corpus): Add support for whitelists. (assert_symbol_count): Likewise. (Symtab::SymtabWithWhitelist): New testcase. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- tests/data/Makefile.am | 4 + .../one_function_one_variable_all.whitelist | 3 + ...e_function_one_variable_function.whitelist | 2 + ...function_one_variable_irrelevant.whitelist | 2 + ...e_function_one_variable_variable.whitelist | 2 + tests/test-symtab.cc | 103 ++++++++++++++++-- 6 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 tests/data/test-symtab/basic/one_function_one_variable_all.whitelist create mode 100644 tests/data/test-symtab/basic/one_function_one_variable_function.whitelist create mode 100644 tests/data/test-symtab/basic/one_function_one_variable_irrelevant.whitelist create mode 100644 tests/data/test-symtab/basic/one_function_one_variable_variable.whitelist diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 8ccd50a0d5bc..cf86fb51d492 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -1768,6 +1768,10 @@ test-symtab/basic/no_debug_info.c \ test-symtab/basic/no_debug_info.so \ test-symtab/basic/one_function_one_variable.c \ test-symtab/basic/one_function_one_variable.so \ +test-symtab/basic/one_function_one_variable_variable.whitelist \ +test-symtab/basic/one_function_one_variable_function.whitelist \ +test-symtab/basic/one_function_one_variable_irrelevant.whitelist \ +test-symtab/basic/one_function_one_variable_all.whitelist \ test-symtab/basic/one_function_one_variable_undefined.c \ test-symtab/basic/one_function_one_variable_undefined.so \ test-symtab/basic/single_function.c \ diff --git a/tests/data/test-symtab/basic/one_function_one_variable_all.whitelist b/tests/data/test-symtab/basic/one_function_one_variable_all.whitelist new file mode 100644 index 000000000000..02ea310960ff --- /dev/null +++ b/tests/data/test-symtab/basic/one_function_one_variable_all.whitelist @@ -0,0 +1,3 @@ +[abi_whitelist] + exported_function + exported_variable diff --git a/tests/data/test-symtab/basic/one_function_one_variable_function.whitelist b/tests/data/test-symtab/basic/one_function_one_variable_function.whitelist new file mode 100644 index 000000000000..893accc14118 --- /dev/null +++ b/tests/data/test-symtab/basic/one_function_one_variable_function.whitelist @@ -0,0 +1,2 @@ +[abi_whitelist] + exported_function diff --git a/tests/data/test-symtab/basic/one_function_one_variable_irrelevant.whitelist b/tests/data/test-symtab/basic/one_function_one_variable_irrelevant.whitelist new file mode 100644 index 000000000000..180ef9064e8f --- /dev/null +++ b/tests/data/test-symtab/basic/one_function_one_variable_irrelevant.whitelist @@ -0,0 +1,2 @@ +[abi_whitelist] + irrelevant diff --git a/tests/data/test-symtab/basic/one_function_one_variable_variable.whitelist b/tests/data/test-symtab/basic/one_function_one_variable_variable.whitelist new file mode 100644 index 000000000000..49d838f2c559 --- /dev/null +++ b/tests/data/test-symtab/basic/one_function_one_variable_variable.whitelist @@ -0,0 +1,2 @@ +[abi_whitelist] + exported_variable diff --git a/tests/test-symtab.cc b/tests/test-symtab.cc index c144b1d080f6..09e5193fa667 100644 --- a/tests/test-symtab.cc +++ b/tests/test-symtab.cc @@ -26,11 +26,14 @@ #include #include +#include #include #include "abg-corpus.h" #include "abg-dwarf-reader.h" +#include "abg-fwd.h" #include "abg-ir.h" +#include "abg-tools-utils.h" #include "lib/catch.hpp" #include "test-utils.h" @@ -41,12 +44,16 @@ using dwarf_reader::read_context_sptr; using dwarf_reader::read_corpus_from_elf; using ir::environment; using ir::environment_sptr; +using suppr::suppressions_type; static const std::string test_data_dir = std::string(abigail::tests::get_src_dir()) + "/tests/data/test-symtab/"; dwarf_reader::status -read_corpus(const std::string path, corpus_sptr& result) +read_corpus( + const std::string& path, + corpus_sptr& result, + const std::vector& whitelist_paths = std::vector()) { const std::string& absolute_path = test_data_dir + path; @@ -56,6 +63,15 @@ read_corpus(const std::string path, corpus_sptr& result) absolute_path, debug_info_root_paths, env.get(), /* load_all_type = */ true, /* linux_kernel_mode = */ true); + if (!whitelist_paths.empty()) + { + const suppressions_type& wl_suppr = + tools_utils::gen_suppr_spec_from_kernel_abi_whitelists( + whitelist_paths); + REQUIRE_FALSE(wl_suppr.empty()); + dwarf_reader::add_read_context_suppressions(*ctxt, wl_suppr); + } + dwarf_reader::status status = dwarf_reader::STATUS_UNKNOWN; result = read_corpus_from_elf(*ctxt, status); @@ -91,14 +107,17 @@ TEST_CASE("Symtab::NoDebugInfo", "[symtab, basic]") #define N std::numeric_limits::max() corpus_sptr -assert_symbol_count(const std::string& path, - size_t function_symbols = 0, - size_t variable_symbols = 0, - size_t undefined_function_symbols = 0, - size_t undefined_variable_symbols = 0) +assert_symbol_count( + const std::string& path, + size_t function_symbols = 0, + size_t variable_symbols = 0, + size_t undefined_function_symbols = 0, + size_t undefined_variable_symbols = 0, + const std::vector& whitelist_paths = std::vector()) { corpus_sptr corpus_ptr; - const dwarf_reader::status status = read_corpus(path, corpus_ptr); + const dwarf_reader::status status = + read_corpus(path, corpus_ptr, whitelist_paths); REQUIRE(corpus_ptr); REQUIRE((status & dwarf_reader::STATUS_OK)); @@ -203,6 +222,76 @@ TEST_CASE("Symtab::SimpleSymtabs", "[symtab, basic]") } } +TEST_CASE("Symtab::SymtabWithWhitelist", "[symtab, whitelist]") +{ + GIVEN("a binary with one function and one variable exported") + { + const std::string binary = "basic/one_function_one_variable.so"; + + GIVEN("we read the binary without any whitelists") + { + const corpus_sptr& corpus = assert_symbol_count(binary, 1, 1); + CHECK(corpus->lookup_function_symbol("exported_function")); + CHECK(!corpus->lookup_variable_symbol("exported_function")); + CHECK(corpus->lookup_variable_symbol("exported_variable")); + CHECK(!corpus->lookup_function_symbol("exported_variable")); + } + + GIVEN("we read the binary with all symbols on the whitelists") + { + std::vector whitelists; + whitelists.push_back(test_data_dir + + "basic/one_function_one_variable_all.whitelist"); + const corpus_sptr& corpus = + assert_symbol_count(binary, 1, 1, 0, 0, whitelists); + CHECK(corpus->lookup_function_symbol("exported_function")); + CHECK(!corpus->lookup_variable_symbol("exported_function")); + CHECK(corpus->lookup_variable_symbol("exported_variable")); + CHECK(!corpus->lookup_function_symbol("exported_variable")); + } + + GIVEN("we read the binary with only irrelevant symbols whitelisted") + { + std::vector whitelists; + whitelists.push_back( + test_data_dir + + "basic/one_function_one_variable_irrelevant.whitelist"); + + corpus_sptr corpus_ptr; + const dwarf_reader::status status = + read_corpus(binary, corpus_ptr, whitelists); + REQUIRE(!corpus_ptr); + REQUIRE((status & dwarf_reader::STATUS_NO_SYMBOLS_FOUND)); + } + + GIVEN("we read the binary with only the function whitelisted") + { + std::vector whitelists; + whitelists.push_back( + test_data_dir + "basic/one_function_one_variable_function.whitelist"); + const corpus_sptr& corpus = + assert_symbol_count(binary, 1, 0, 0, 0, whitelists); + CHECK(corpus->lookup_function_symbol("exported_function")); + CHECK(!corpus->lookup_variable_symbol("exported_function")); + CHECK(!corpus->lookup_variable_symbol("exported_variable")); + CHECK(!corpus->lookup_function_symbol("exported_variable")); + } + + GIVEN("we read the binary with only the variable whitelisted") + { + std::vector whitelists; + whitelists.push_back( + test_data_dir + "basic/one_function_one_variable_variable.whitelist"); + const corpus_sptr& corpus = + assert_symbol_count(binary, 0, 1, 0, 0, whitelists); + CHECK(!corpus->lookup_function_symbol("exported_function")); + CHECK(!corpus->lookup_variable_symbol("exported_function")); + CHECK(corpus->lookup_variable_symbol("exported_variable")); + CHECK(!corpus->lookup_function_symbol("exported_variable")); + } + } +} + static const char* kernel_versions[] = { "4.14", "4.19", "5.4", "5.6" }; static const size_t nr_kernel_versions = sizeof(kernel_versions) / sizeof(kernel_versions[0]); From patchwork Fri Jul 3 16:46:48 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: 39904 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 58D623844079; Fri, 3 Jul 2020 16:49:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 58D623844079 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794998; bh=Aul0d6JjJ9pbsfmkyyfCfy1GtrNrUwYn8km1mG17Iks=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=QhYkRuZoJUtbTFHUdviEohgY5F/arb0Omg4EPVfibL4io0YnTznG5yOGzRzMaSUDl QNsvQ3xxmV/mV+fxkJhcep8qeMPR1FeMbb+WOFZ0gzJMa5HeKnJ/ac6T1f6gHBsYWx XHw7b+4MLYMl6vmc5ql2FyoQGVBQXH/nXuo2kGNs= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wm1-x349.google.com (mail-wm1-x349.google.com [IPv6:2a00:1450:4864:20::349]) by sourceware.org (Postfix) with ESMTPS id CEA52384403B for ; Fri, 3 Jul 2020 16:48:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CEA52384403B Received: by mail-wm1-x349.google.com with SMTP id v6so33487587wmg.1 for ; Fri, 03 Jul 2020 09:48:15 -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:content-transfer-encoding; bh=Aul0d6JjJ9pbsfmkyyfCfy1GtrNrUwYn8km1mG17Iks=; b=KZ86GgZFzl0G45dhHW3DsgagXBeygdOGiw0G1ZBYVStMBmI2r723AbU39MFUgwZeZh gWXLr4If+2fcks7esYE2vPlt6pO1bYB6zUDFLkvH2hq16NJNvLk114yue6VOETzq9oDQ VymOBds6FWnfIEsHJtiUTQwgqX0g+dAMLZpecd14LkJMuU9u/rtec60TNdmbHzi9QT8x kc3IbtfaePx66Jne08uA8IqIbPE8dPhJoYIxSVDHPVru6o2ErkLzCe8wXkU0NtB9Nyxg SRPm4eqvwnwPSYwIoK+mjKVLsOiz96NOvQj8r5m6GIVIdRVyXaFYvqPZconoolT5wkDw 78sA== X-Gm-Message-State: AOAM5323DDS428WrsRQdN7wa44JvtYASUrqpZdb/mH9ghft9DhaINN52 C5xFlC9s+7bXcOkgj0kEMAAcn9SpwoItnjWZbeWWj2A2eOZJVaTSBSOceW5s8S9xu08sfbzMvuU UeutZseMPlF0vOfTmEQjU94W4PFcKKlX3Hu49lNqFDw3APhkjnGnfo29+EIJNa7QBCC6NKlo= X-Google-Smtp-Source: ABdhPJwlDzrleiWcn7+DjAXB/51yCSf2zICyrKCLTahuDef8JYCE73uACTb12txeY+Uem1OUXNNPdBZ0ARcnUA== X-Received: by 2002:a1c:a986:: with SMTP id s128mr39916407wme.121.1593794894278; Fri, 03 Jul 2020 09:48:14 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:48 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-19-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 18/21] symtab/dwarf-reader: allow hinting of main symbols for aliases To: libabigail@sourceware.org X-Spam-Status: No, score=-19.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TIME_LIMIT_EXCEEDED, USER_IN_DEF_DKIM_WL autolearn=unavailable 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" In case of aliased symbols, the "main symbol" cannot be deduced from the symtab as this solely contains a name->addr mapping and aliases are represented by multiple names resolving to the same address. Therefore the main symbol can only be picked rather randomly and unpredictable. Unlike DWARF, which contains a single symbol entry for only the main symbol. Hence we can (late) detect the main symbol. Exploiting that property allows to correct the addr->symbol lookup in the symtab to return the correct main symbol and it also allows to correct the aliased symbols to maintain the correct main symbol. This patch adds the `update_main_symbol` functionality to `elf_symbol` to update the main symbol by name (ELF symbols need unique names) and adds `update_main_symbol` to `symtab` that makes use of said new method. When we discover a main symbol during DWARF reading, we instruct the symtab to update the mapping. This creates consistent representations across different builds of the same binary with the same ABI by pinning down the main symbol to the defined one. Knowing the main symbol also helps to keep the correct dwarf information in the representation in the presence of symbol suppressions. A later patch will address that. Some test cases in tests/data need adjustment and they have all been verified to be valid changes. - main symbol changed for various elf symbols - test-annotate/test15-pr18892.so.abi - test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi - test-annotate/test3.so.abi - test-read-dwarf/test15-pr18892.so.abi - test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi - test-read-dwarf/test3.so.abi - test-read-dwarf/test3.so.hash.abi - due to main symbol changes, the symbol diff needs to be corrected - test-diff-dwarf/test12-report.txt - test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt - test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt - the test scenario needed adjustments as the main symbol changed - test-diff-suppr/test23-alias-filter-4.suppr - test-diff-suppr/test23-alias-filter-report-0.txt - test-diff-suppr/test23-alias-filter-report-2.txt As usual, the complete changelog follows. * include/abg-ir.h (elf_symbol::update_main_symbol): New method. * include/abg-symtab-reader.h (symtab::update_main_symbol): New method. * src/abg-dwarf-reader.cc (build_var_decl): Hint symtab about main symbol discovered in DWARF. (build_function_decl): Likewise. * src/abg-ir.cc (elf_symbol::get_main_symbol): Lock the weak_ptr on access in both overloads. (update_main_symbol): New method to allow updating the main symbol. * src/abg-symtab-reader.cc (symtab::update_main_symbol): New method. * data/Makefile.am: Add new test data files. * tests/data/test-annotate/test15-pr18892.so.abi: Updated test file. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test2.so.abi: Likewise. * tests/data/test-annotate/test3.so.abi: Likewise. * tests/data/test-diff-dwarf/test12-report.txt: Likewise. * tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt: Likewise. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Likewise. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-4.suppr: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-0.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-2.txt: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test3.so.abi: Likewise. * tests/data/test-read-dwarf/test3.so.hash.abi: Likewise. * tests/data/test-symtab/basic/aliases.c: New test source file. * tests/data/test-symtab/basic/aliases.so: Likewise. * tests/test-symtab.cc (Symtab::AliasedFunctionSymbols): New test case. (Symtab::AliasedVariableSymbols): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- include/abg-ir.h | 3 + include/abg-symtab-reader.h | 13 + src/abg-dwarf-reader.cc | 16 +- src/abg-ir.cc | 46 +- src/abg-symtab-reader.cc | 21 + tests/data/Makefile.am | 2 + .../data/test-annotate/test15-pr18892.so.abi | 918 ++++++++--------- ...19-pr19023-libtcmalloc_and_profiler.so.abi | 60 +- tests/data/test-annotate/test2.so.abi | 12 +- tests/data/test-annotate/test3.so.abi | 6 +- tests/data/test-diff-dwarf/test12-report.txt | 7 + .../test42-PR21296-clanggcc-report0.txt | 4 +- ...bb-4.3-3.20141204.fc23.x86_64-report-0.txt | 6 +- ...bb-4.3-3.20141204.fc23.x86_64-report-1.txt | 6 +- .../test23-alias-filter-4.suppr | 4 +- .../test23-alias-filter-report-0.txt | 4 +- .../test23-alias-filter-report-2.txt | 4 +- .../PR22015-libboost_iostreams.so.abi | 48 +- .../test-read-dwarf/PR22122-libftdc.so.abi | 6 +- .../test-read-dwarf/test10-pr18818-gcc.so.abi | 192 ++-- .../test-read-dwarf/test11-pr18828.so.abi | 516 +++++----- .../test-read-dwarf/test12-pr18844.so.abi | 60 +- .../test-read-dwarf/test15-pr18892.so.abi | 918 ++++++++--------- .../test-read-dwarf/test16-pr18904.so.abi | 964 +++++++++--------- ...19-pr19023-libtcmalloc_and_profiler.so.abi | 60 +- tests/data/test-read-dwarf/test2.so.abi | 12 +- tests/data/test-read-dwarf/test2.so.hash.abi | 12 +- .../test22-pr19097-libstdc++.so.6.0.17.so.abi | 878 ++++++++-------- tests/data/test-read-dwarf/test3.so.abi | 6 +- tests/data/test-read-dwarf/test3.so.hash.abi | 6 +- tests/data/test-symtab/basic/aliases.c | 13 + tests/data/test-symtab/basic/aliases.so | Bin 0 -> 17176 bytes tests/test-symtab.cc | 47 + 33 files changed, 2512 insertions(+), 2358 deletions(-) create mode 100644 tests/data/test-symtab/basic/aliases.c create mode 100755 tests/data/test-symtab/basic/aliases.so diff --git a/include/abg-ir.h b/include/abg-ir.h index 838d3f80695a..c150075df3b8 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -968,6 +968,9 @@ public: bool is_main_symbol() const; + elf_symbol_sptr + update_main_symbol(const std::string&); + elf_symbol_sptr get_next_alias() const; diff --git a/include/abg-symtab-reader.h b/include/abg-symtab-reader.h index 06001b26ebeb..9065b6ad4209 100644 --- a/include/abg-symtab-reader.h +++ b/include/abg-symtab-reader.h @@ -315,6 +315,19 @@ public: load(string_elf_symbols_map_sptr function_symbol_map, string_elf_symbols_map_sptr variables_symbol_map); + /// Notify the symtab about the name of the main symbol at a given address. + /// + /// From just alone the symtab we can't guess the main symbol of a bunch of + /// aliased symbols that all point to the same address. During processing of + /// additional information (such as DWARF), this information becomes apparent + /// and we can adjust the addr->symbol lookup map as well as the alias + /// reference of the symbol objects. + /// + /// @param addr the addr that we are updating the main symbol for + /// @param name the name of the main symbol + void + update_main_symbol(GElf_Addr addr, const std::string& name); + private: /// Default constructor. Private to enforce creation by factory methods. symtab(); diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 6ed316e19ac1..4120b03b8ac5 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -12934,7 +12934,13 @@ build_var_decl(read_context& ctxt, elf_symbol_sptr var_sym; Dwarf_Addr var_addr; if (ctxt.get_variable_address(die, var_addr)) - var_sym = var_sym = ctxt.variable_symbol_is_exported(var_addr); + { + ctxt.symtab()->update_main_symbol(var_addr, + result->get_linkage_name().empty() + ? result->get_name() + : result->get_linkage_name()); + var_sym = ctxt.variable_symbol_is_exported(var_addr); + } if (var_sym) { @@ -13355,7 +13361,13 @@ build_function_decl(read_context& ctxt, elf_symbol_sptr fn_sym; Dwarf_Addr fn_addr; if (ctxt.get_function_address(die, fn_addr)) - fn_sym = ctxt.function_symbol_is_exported(fn_addr); + { + ctxt.symtab()->update_main_symbol(fn_addr, + result->get_linkage_name().empty() + ? result->get_name() + : result->get_linkage_name()); + fn_sym = ctxt.function_symbol_is_exported(fn_addr); + } if (fn_sym) { diff --git a/src/abg-ir.cc b/src/abg-ir.cc index c69284f0946a..5a0f9f968034 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -1744,14 +1744,14 @@ elf_symbol::set_is_suppressed(bool is_suppressed) ///@return the main symbol. const elf_symbol_sptr elf_symbol::get_main_symbol() const -{return elf_symbol_sptr(priv_->main_symbol_);} +{return priv_->main_symbol_.lock();} /// Get the main symbol of an alias chain. /// ///@return the main symbol. elf_symbol_sptr elf_symbol::get_main_symbol() -{return elf_symbol_sptr(priv_->main_symbol_);} +{return priv_->main_symbol_.lock();} /// Tests whether this symbol is the main symbol. /// @@ -1828,6 +1828,48 @@ elf_symbol::add_alias(const elf_symbol_sptr& alias) alias->priv_->main_symbol_ = get_main_symbol(); } +/// Update the main symbol for a group of aliased symbols +/// +/// If after the construction of the symbols (in order of discovery), the +/// actual main symbol can be identified (e.g. as the symbol that actually is +/// defined in the code), this method offers a way of updating the main symbol +/// through one of the aliased symbols. +/// +/// For that, locate the new main symbol by name and update all references to +/// the main symbol among the group of aliased symbols. +/// +/// @param name the name of the main symbol +/// +/// @return the new main elf_symbol +elf_symbol_sptr +elf_symbol::update_main_symbol(const std::string& name) +{ + + if (!has_aliases() || (is_main_symbol() && get_name() == name)) + return get_main_symbol(); + + // find the new main symbol + elf_symbol_sptr new_main; + for (elf_symbol_sptr a = get_next_alias(); a.get() != this; + a = a->get_next_alias()) + if (a->get_name() == name) + { + new_main = a; + break; + } + + if (!new_main) + return get_main_symbol(); + + // now update all main symbol references + for (elf_symbol_sptr a = get_next_alias(); + a->get_main_symbol() != new_main; + a = a->get_next_alias()) + a->priv_->main_symbol_ = new_main; + + return new_main; +} + /// Return true if the symbol is a common one. /// /// @return true iff the symbol is common. diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc index aefc8d6dcd86..f84ed79dae17 100644 --- a/src/abg-symtab-reader.cc +++ b/src/abg-symtab-reader.cc @@ -356,6 +356,27 @@ symtab::load_(string_elf_symbols_map_sptr function_symbol_map, return true; } +void +symtab::update_main_symbol(GElf_Addr addr, const std::string& name) +{ + // get one symbol (i.e. the current main symbol) + elf_symbol_sptr symbol = lookup_symbol(addr); + + // The caller might not know whether the addr is associated to an ELF symbol + // that we care about. E.g. the addr could be associated to an ELF symbol, + // but not one in .dynsym when looking at a DSO. Hence, early exit if the + // lookup failed. + if (!symbol) + return; + + // determine the new main symbol by attempting an update + elf_symbol_sptr new_main = symbol->update_main_symbol(name); + + // also update the default symbol we return when looked up by address + if (new_main) + addr_symbol_map_[addr] = new_main; +} + void symtab::update_function_entry_address_symbol_map( Elf* elf_handle, diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index cf86fb51d492..054acb8c5376 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -1760,6 +1760,8 @@ test-kmi-whitelist/whitelist-with-duplicate-entry \ test-kmi-whitelist/whitelist-with-two-sections \ \ test-symtab/basic/Makefile \ +test-symtab/basic/aliases.c \ +test-symtab/basic/aliases.so \ test-symtab/basic/empty.c \ test-symtab/basic/empty.so \ test-symtab/basic/link_against_me.c \ diff --git a/tests/data/test-annotate/test15-pr18892.so.abi b/tests/data/test-annotate/test15-pr18892.so.abi index 4e93c02de863..cb593b418801 100644 --- a/tests/data/test-annotate/test15-pr18892.so.abi +++ b/tests/data/test-annotate/test15-pr18892.so.abi @@ -193,7 +193,7 @@ - + @@ -207,45 +207,45 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -253,7 +253,7 @@ - + @@ -261,69 +261,69 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -341,7 +341,7 @@ - + @@ -353,19 +353,19 @@ - + - + - + - + - + @@ -373,67 +373,67 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -441,25 +441,25 @@ - + - + - + - + - + - + - + - + @@ -467,39 +467,39 @@ - + - + - + - + - + - + - + - + - + - + @@ -509,43 +509,43 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -555,7 +555,7 @@ - + @@ -569,21 +569,21 @@ - + - + - + - + - + @@ -591,13 +591,13 @@ - + - + - + @@ -607,9 +607,9 @@ - + - + @@ -621,19 +621,19 @@ - + - + - + - + - + @@ -641,49 +641,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -695,19 +695,19 @@ - + - + - + - + @@ -719,23 +719,23 @@ - + - + - + - + - + @@ -745,7 +745,7 @@ - + @@ -761,93 +761,93 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2223,11 +2223,11 @@ - + - + @@ -2407,11 +2407,11 @@ - + - + @@ -2429,13 +2429,13 @@ - + - + - + @@ -2443,7 +2443,7 @@ - + @@ -2451,7 +2451,7 @@ - + @@ -2459,69 +2459,69 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2539,7 +2539,7 @@ - + @@ -2551,19 +2551,19 @@ - + - + - + - + - + @@ -2571,67 +2571,67 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2639,25 +2639,25 @@ - + - + - + - + - + - + - + - + @@ -2665,39 +2665,39 @@ - + - + - + - + - + - + - + - + - + - + @@ -2707,43 +2707,43 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -2753,7 +2753,7 @@ - + @@ -2767,21 +2767,21 @@ - + - + - + - + - + @@ -2789,13 +2789,13 @@ - + - + - + @@ -2805,9 +2805,9 @@ - + - + @@ -2819,19 +2819,19 @@ - + - + - + - + - + @@ -2839,49 +2839,49 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2893,19 +2893,19 @@ - + - + - + - + @@ -2917,23 +2917,23 @@ - + - + - + - + - + @@ -2943,7 +2943,7 @@ - + @@ -2959,73 +2959,73 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -12798,7 +12798,7 @@ - + @@ -12807,7 +12807,7 @@ - + @@ -12816,7 +12816,7 @@ - + @@ -19261,7 +19261,7 @@ - + @@ -19289,7 +19289,7 @@ - + @@ -19309,7 +19309,7 @@ - + @@ -19336,7 +19336,7 @@ - + @@ -19345,7 +19345,7 @@ - + @@ -19359,14 +19359,14 @@ - + - + @@ -19377,7 +19377,7 @@ - + @@ -19388,7 +19388,7 @@ - + @@ -19421,7 +19421,7 @@ - + @@ -19441,7 +19441,7 @@ - + @@ -19450,21 +19450,21 @@ - + - + - + @@ -19484,7 +19484,7 @@ - + @@ -19504,7 +19504,7 @@ - + @@ -19513,7 +19513,7 @@ - + @@ -19531,7 +19531,7 @@ - + @@ -19540,7 +19540,7 @@ - + @@ -19569,7 +19569,7 @@ - + @@ -19578,7 +19578,7 @@ - + @@ -19587,7 +19587,7 @@ - + @@ -19598,7 +19598,7 @@ - + @@ -19607,7 +19607,7 @@ - + @@ -19630,7 +19630,7 @@ - + @@ -19639,7 +19639,7 @@ - + @@ -19648,7 +19648,7 @@ - + @@ -19675,7 +19675,7 @@ - + @@ -19711,7 +19711,7 @@ - + @@ -19738,7 +19738,7 @@ - + @@ -19770,14 +19770,14 @@ - + - + @@ -19813,14 +19813,14 @@ - + - + @@ -19845,7 +19845,7 @@ - + @@ -19874,7 +19874,7 @@ - + @@ -19887,7 +19887,7 @@ - + @@ -19933,7 +19933,7 @@ - + @@ -19944,7 +19944,7 @@ - + @@ -19962,7 +19962,7 @@ - + @@ -19973,7 +19973,7 @@ - + @@ -19984,7 +19984,7 @@ - + @@ -20015,7 +20015,7 @@ - + @@ -20039,7 +20039,7 @@ - + @@ -20054,7 +20054,7 @@ - + @@ -20067,7 +20067,7 @@ - + @@ -20078,7 +20078,7 @@ - + @@ -20089,7 +20089,7 @@ - + @@ -20100,14 +20100,14 @@ - + - + @@ -20156,7 +20156,7 @@ - + @@ -20174,14 +20174,14 @@ - + - + @@ -20203,7 +20203,7 @@ - + @@ -20212,7 +20212,7 @@ - + @@ -20288,7 +20288,7 @@ - + @@ -20305,7 +20305,7 @@ - + @@ -20368,7 +20368,7 @@ - + @@ -20397,7 +20397,7 @@ - + @@ -20430,7 +20430,7 @@ - + @@ -20443,7 +20443,7 @@ - + @@ -20465,7 +20465,7 @@ - + @@ -20496,7 +20496,7 @@ - + @@ -20505,7 +20505,7 @@ - + @@ -20514,7 +20514,7 @@ - + @@ -20532,7 +20532,7 @@ - + @@ -20543,7 +20543,7 @@ - + @@ -20554,7 +20554,7 @@ - + @@ -20564,7 +20564,7 @@ - + @@ -20575,7 +20575,7 @@ - + @@ -20585,7 +20585,7 @@ - + @@ -20594,7 +20594,7 @@ - + @@ -20602,7 +20602,7 @@ - + @@ -20634,7 +20634,7 @@ - + @@ -20644,7 +20644,7 @@ - + @@ -20653,7 +20653,7 @@ - + @@ -20672,7 +20672,7 @@ - + @@ -20688,7 +20688,7 @@ - + @@ -20697,7 +20697,7 @@ - + @@ -20713,14 +20713,14 @@ - + - + @@ -20736,14 +20736,14 @@ - + - + @@ -20758,7 +20758,7 @@ - + @@ -20771,7 +20771,7 @@ - + @@ -20795,7 +20795,7 @@ - + @@ -20808,7 +20808,7 @@ - + @@ -20821,7 +20821,7 @@ - + @@ -20832,7 +20832,7 @@ - + @@ -20845,7 +20845,7 @@ - + @@ -20858,7 +20858,7 @@ - + @@ -20895,7 +20895,7 @@ - + @@ -20915,7 +20915,7 @@ - + @@ -20933,7 +20933,7 @@ - + @@ -20973,7 +20973,7 @@ - + @@ -21000,7 +21000,7 @@ - + @@ -21009,7 +21009,7 @@ - + @@ -21041,7 +21041,7 @@ - + @@ -21061,7 +21061,7 @@ - + @@ -21074,7 +21074,7 @@ - + @@ -21094,7 +21094,7 @@ - + @@ -21108,7 +21108,7 @@ - + @@ -21122,7 +21122,7 @@ - + @@ -21175,14 +21175,14 @@ - + - + @@ -21206,7 +21206,7 @@ - + @@ -21251,14 +21251,14 @@ - + - + @@ -21281,7 +21281,7 @@ - + @@ -21292,7 +21292,7 @@ - + @@ -21327,7 +21327,7 @@ - + @@ -21341,7 +21341,7 @@ - + @@ -21352,7 +21352,7 @@ - + @@ -21372,7 +21372,7 @@ - + @@ -21381,7 +21381,7 @@ - + @@ -21417,7 +21417,7 @@ - + @@ -21468,7 +21468,7 @@ - + @@ -21477,7 +21477,7 @@ - + @@ -21497,7 +21497,7 @@ - + @@ -21517,7 +21517,7 @@ - + @@ -21528,7 +21528,7 @@ - + @@ -21564,7 +21564,7 @@ - + @@ -21587,14 +21587,14 @@ - + - + @@ -21605,7 +21605,7 @@ - + @@ -21628,7 +21628,7 @@ - + @@ -21673,7 +21673,7 @@ - + @@ -21687,7 +21687,7 @@ - + @@ -21696,7 +21696,7 @@ - + @@ -21740,7 +21740,7 @@ - + @@ -21754,7 +21754,7 @@ - + @@ -21772,7 +21772,7 @@ - + @@ -21786,7 +21786,7 @@ - + @@ -21905,7 +21905,7 @@ - + @@ -21938,7 +21938,7 @@ - + @@ -21958,7 +21958,7 @@ - + @@ -21985,7 +21985,7 @@ - + @@ -22029,7 +22029,7 @@ - + @@ -22122,14 +22122,14 @@ - + - + @@ -22143,7 +22143,7 @@ - + @@ -22152,7 +22152,7 @@ - + @@ -22170,14 +22170,14 @@ - + - + @@ -22195,7 +22195,7 @@ - + @@ -22204,7 +22204,7 @@ - + @@ -22247,7 +22247,7 @@ - + @@ -22263,7 +22263,7 @@ - + @@ -26271,7 +26271,7 @@ - + @@ -26289,7 +26289,7 @@ - + diff --git a/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi b/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi index 5b1f71346175..c2c233760f4e 100644 --- a/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi +++ b/tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi @@ -1098,15 +1098,15 @@ - + - + - + - + @@ -1124,11 +1124,11 @@ - + - + @@ -1138,19 +1138,19 @@ - + - + - + @@ -1164,7 +1164,7 @@ - + @@ -1174,23 +1174,23 @@ - + - + - + - + - + - + @@ -1204,19 +1204,19 @@ - + - + - + - + @@ -41638,7 +41638,7 @@ - + @@ -41655,7 +41655,7 @@ - + @@ -41666,14 +41666,14 @@ - + - + @@ -41698,7 +41698,7 @@ - + @@ -41721,7 +41721,7 @@ - + @@ -41751,14 +41751,14 @@ - + - + @@ -41774,14 +41774,14 @@ - + - + diff --git a/tests/data/test-annotate/test2.so.abi b/tests/data/test-annotate/test2.so.abi index cc40ccd0e3c5..072834a187b5 100644 --- a/tests/data/test-annotate/test2.so.abi +++ b/tests/data/test-annotate/test2.so.abi @@ -7,13 +7,13 @@ - + - + - + - + @@ -55,7 +55,7 @@ - + @@ -96,7 +96,7 @@ - + diff --git a/tests/data/test-annotate/test3.so.abi b/tests/data/test-annotate/test3.so.abi index cbcb456d97c8..ca3790742779 100644 --- a/tests/data/test-annotate/test3.so.abi +++ b/tests/data/test-annotate/test3.so.abi @@ -4,7 +4,7 @@ - + @@ -12,7 +12,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/tests/data/test-diff-dwarf/test12-report.txt b/tests/data/test-diff-dwarf/test12-report.txt index e69de29bb2d1..62dd8337d694 100644 --- a/tests/data/test-diff-dwarf/test12-report.txt +++ b/tests/data/test-diff-dwarf/test12-report.txt @@ -0,0 +1,7 @@ +Functions changes summary: 0 Removed, 0 Changed, 1 Added function +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 Added function: + + [A] 'function int _foo3(int, int)' + diff --git a/tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt b/tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt index 087cfd4edb89..47250ac7d02a 100644 --- a/tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt +++ b/tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt @@ -9,9 +9,7 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable [C] 'method STR::~STR(int)' has some indirect sub-type changes: linkage names of method STR::~STR(int) - changed from '_ZN3STRD1Ev, _ZN3STRD2Ev' to '_ZN3STRD2Ev' - - name of symbol changed from _ZN3STRD1Ev to _ZN3STRD2Ev + changed from '_ZN3STRD2Ev, _ZN3STRD1Ev' to '_ZN3STRD2Ev' parameter 1 of type 'int' was removed [C] 'function std::tuple my_forward_as_tuple(STR&&)' has some indirect sub-type changes: diff --git a/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt b/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt index 62785044d808..00e19379b88e 100644 --- a/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt +++ b/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt @@ -266,20 +266,18 @@ ================ end of changes of 'libtbbmalloc.so.2'=============== ================ changes of 'libtbbmalloc_proxy.so.2'=============== - Functions changes summary: 1 Removed, 0 Changed, 5 Added functions + Functions changes summary: 1 Removed, 0 Changed, 3 Added functions Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 Removed function: [D] 'function bool __TBB_internal_find_original_malloc(int, const char**, void**)' {__TBB_internal_find_original_malloc} - 5 Added functions: + 3 Added functions: [A] 'function void __libc_free(void*)' {__libc_free} [A] 'function void* __libc_realloc(void*, size_t)' {__libc_realloc} - [A] 'function void* calloc(size_t, size_t)' {__libc_calloc, aliases calloc} [A] 'function size_t malloc_usable_size(void*)' {malloc_usable_size} - [A] 'function void* valloc(size_t)' {__libc_valloc, aliases valloc} ================ end of changes of 'libtbbmalloc_proxy.so.2'=============== diff --git a/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt b/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt index bef715b6feca..b201cb46d6b1 100644 --- a/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt +++ b/tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt @@ -140,20 +140,18 @@ ================ end of changes of 'libtbbmalloc.so.2'=============== ================ changes of 'libtbbmalloc_proxy.so.2'=============== - Functions changes summary: 1 Removed, 0 Changed, 5 Added functions + Functions changes summary: 1 Removed, 0 Changed, 3 Added functions Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 Removed function: [D] 'function bool __TBB_internal_find_original_malloc(int, const char**, void**)' {__TBB_internal_find_original_malloc} - 5 Added functions: + 3 Added functions: [A] 'function void __libc_free(void*)' {__libc_free} [A] 'function void* __libc_realloc(void*, size_t)' {__libc_realloc} - [A] 'function void* calloc(size_t, size_t)' {__libc_calloc, aliases calloc} [A] 'function size_t malloc_usable_size(void*)' {malloc_usable_size} - [A] 'function void* valloc(size_t)' {__libc_valloc, aliases valloc} ================ end of changes of 'libtbbmalloc_proxy.so.2'=============== diff --git a/tests/data/test-diff-suppr/test23-alias-filter-4.suppr b/tests/data/test-diff-suppr/test23-alias-filter-4.suppr index 2a7e5893eb43..16edb095bbbf 100644 --- a/tests/data/test-diff-suppr/test23-alias-filter-4.suppr +++ b/tests/data/test-diff-suppr/test23-alias-filter-4.suppr @@ -1,3 +1,3 @@ [suppress_function] - symbol_name_regexp = function1 - allow_other_aliases = no \ No newline at end of file + symbol_name_regexp = __private_function + allow_other_aliases = no diff --git a/tests/data/test-diff-suppr/test23-alias-filter-report-0.txt b/tests/data/test-diff-suppr/test23-alias-filter-report-0.txt index 0788d48931f7..8b06f3151b63 100644 --- a/tests/data/test-diff-suppr/test23-alias-filter-report-0.txt +++ b/tests/data/test-diff-suppr/test23-alias-filter-report-0.txt @@ -4,8 +4,8 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 function with some indirect sub-type change: [C] 'function void __private_function(S*)' has some indirect sub-type changes: - Please note that the symbol of this function is function1@VERSION_1.0 - and it aliases symbols: __private_function@PRIVATE_1.0, function2@VERSION_1.0 + Please note that the symbol of this function is __private_function@PRIVATE_1.0 + and it aliases symbols: function2@VERSION_1.0, function1@VERSION_1.0 parameter 1 of type 'S*' has sub-type changes: in pointed to type 'typedef S': underlying type 'struct S' changed: diff --git a/tests/data/test-diff-suppr/test23-alias-filter-report-2.txt b/tests/data/test-diff-suppr/test23-alias-filter-report-2.txt index 0788d48931f7..8b06f3151b63 100644 --- a/tests/data/test-diff-suppr/test23-alias-filter-report-2.txt +++ b/tests/data/test-diff-suppr/test23-alias-filter-report-2.txt @@ -4,8 +4,8 @@ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 function with some indirect sub-type change: [C] 'function void __private_function(S*)' has some indirect sub-type changes: - Please note that the symbol of this function is function1@VERSION_1.0 - and it aliases symbols: __private_function@PRIVATE_1.0, function2@VERSION_1.0 + Please note that the symbol of this function is __private_function@PRIVATE_1.0 + and it aliases symbols: function2@VERSION_1.0, function1@VERSION_1.0 parameter 1 of type 'S*' has sub-type changes: in pointed to type 'typedef S': underlying type 'struct S' changed: diff --git a/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi b/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi index e7cd4c9a0b81..60086b1e5e3b 100644 --- a/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi +++ b/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi @@ -36,13 +36,13 @@ - - + + - - + + @@ -50,31 +50,31 @@ - + - + - - + + - - + + - + - + @@ -90,8 +90,8 @@ - - + + @@ -100,8 +100,8 @@ - - + + @@ -532,7 +532,7 @@ - + @@ -665,13 +665,13 @@ - + - + @@ -816,7 +816,7 @@ - + @@ -884,7 +884,7 @@ - + @@ -908,7 +908,7 @@ - + @@ -1685,7 +1685,7 @@ - + @@ -1849,7 +1849,7 @@ - + diff --git a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi index 28df268d52a5..e5b2fbbaa610 100644 --- a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi +++ b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi @@ -151,8 +151,8 @@ - - + + @@ -7133,7 +7133,7 @@ - + diff --git a/tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi b/tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi index bc8d8ae212e6..d3ac0757f79e 100644 --- a/tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi +++ b/tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi @@ -36,8 +36,8 @@ - - + + @@ -45,24 +45,24 @@ - + - + - - + + - - - - - - + + + + + + @@ -88,16 +88,16 @@ - - + + - + - - + + - + @@ -109,10 +109,10 @@ - - - - + + + + @@ -167,30 +167,30 @@ - + - + - + - + - - + + - - + + - - + + @@ -213,27 +213,27 @@ - - + + - - + + - - + + - - + + - - + + @@ -254,24 +254,24 @@ - - - - + + + + - + - + - - + + - - + + @@ -282,8 +282,8 @@ - - + + @@ -362,9 +362,9 @@ - + - + @@ -2205,7 +2205,7 @@ - + @@ -2728,7 +2728,7 @@ - + @@ -3029,7 +3029,7 @@ - + @@ -3113,7 +3113,7 @@ - + @@ -3283,13 +3283,13 @@ - + - + @@ -3297,7 +3297,7 @@ - + @@ -3305,7 +3305,7 @@ - + @@ -6260,13 +6260,13 @@ - + - + @@ -6280,7 +6280,7 @@ - + @@ -6351,7 +6351,7 @@ - + @@ -6640,7 +6640,7 @@ - + @@ -6808,7 +6808,7 @@ - + @@ -6991,7 +6991,7 @@ - + @@ -7549,20 +7549,20 @@ - + - + - + @@ -7591,20 +7591,20 @@ - + - + - + @@ -7627,7 +7627,7 @@ - + @@ -7968,13 +7968,13 @@ - + - + @@ -8059,20 +8059,20 @@ - + - + - + @@ -8247,7 +8247,7 @@ - + @@ -8288,7 +8288,7 @@ - + @@ -8470,7 +8470,7 @@ - + @@ -8479,7 +8479,7 @@ - + @@ -8530,35 +8530,35 @@ - + - + - + - + - + @@ -8813,7 +8813,7 @@ - + @@ -8971,7 +8971,7 @@ - + @@ -8985,7 +8985,7 @@ - + @@ -9936,7 +9936,7 @@ - + diff --git a/tests/data/test-read-dwarf/test11-pr18828.so.abi b/tests/data/test-read-dwarf/test11-pr18828.so.abi index 6789be55ab44..f3c07f9bf34d 100644 --- a/tests/data/test-read-dwarf/test11-pr18828.so.abi +++ b/tests/data/test-read-dwarf/test11-pr18828.so.abi @@ -40,24 +40,24 @@ - - - - + + + + - + - - + + - + - - + + @@ -71,22 +71,22 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -97,16 +97,16 @@ - - - - + + + + - - + + @@ -115,8 +115,8 @@ - - + + @@ -130,11 +130,11 @@ - - + + - - + + @@ -145,20 +145,20 @@ - - + + - - + + - - + + - - + + @@ -171,8 +171,8 @@ - - + + @@ -183,11 +183,11 @@ - + - - - + + + @@ -205,8 +205,8 @@ - - + + @@ -232,44 +232,44 @@ - - - - - - - - + + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - + + - - + + @@ -326,25 +326,25 @@ - + - - - + + + - - - - - - - - - - + + + + + + + + + + @@ -352,30 +352,30 @@ - - + + - - - - - - + + + + + + - - - - + + + + @@ -383,12 +383,12 @@ - - - - - - + + + + + + @@ -398,31 +398,31 @@ - - - - + + + + - - - - - - + + + + + + - - - - + + + + - - + + @@ -431,34 +431,34 @@ - - - - - - + + + + + + - - + + - - + + - - + + - - + + @@ -469,12 +469,12 @@ - - + + - - + + @@ -494,20 +494,20 @@ - - - - - - + + + + + + - - + + - - + + @@ -518,33 +518,33 @@ - - - - - - + + + + + + - - - - - - - - + + + + + + + + - - - - + + + + @@ -568,12 +568,12 @@ - + - + - - + + @@ -7054,7 +7054,7 @@ - + @@ -7089,7 +7089,7 @@ - + @@ -7188,14 +7188,14 @@ - + - + @@ -7840,7 +7840,7 @@ - + @@ -7939,14 +7939,14 @@ - + - + @@ -7975,14 +7975,14 @@ - + - + @@ -8538,20 +8538,20 @@ - + - + - + @@ -8600,13 +8600,13 @@ - + - + @@ -8727,20 +8727,20 @@ - + - + - + @@ -8800,7 +8800,7 @@ - + @@ -8814,7 +8814,7 @@ - + @@ -8967,7 +8967,7 @@ - + @@ -8975,7 +8975,7 @@ - + @@ -8990,7 +8990,7 @@ - + @@ -9500,7 +9500,7 @@ - + @@ -9549,7 +9549,7 @@ - + @@ -10200,14 +10200,14 @@ - + - + @@ -10248,14 +10248,14 @@ - + - + @@ -10708,7 +10708,7 @@ - + @@ -11458,7 +11458,7 @@ - + @@ -11621,7 +11621,7 @@ - + @@ -11672,7 +11672,7 @@ - + @@ -11837,7 +11837,7 @@ - + @@ -16506,7 +16506,7 @@ - + @@ -20088,7 +20088,7 @@ - + @@ -20155,7 +20155,7 @@ - + @@ -20443,11 +20443,11 @@ - + - + @@ -20507,7 +20507,7 @@ - + @@ -20771,7 +20771,7 @@ - + @@ -20841,7 +20841,7 @@ - + @@ -20934,7 +20934,7 @@ - + @@ -21067,7 +21067,7 @@ - + @@ -21109,7 +21109,7 @@ - + @@ -21267,7 +21267,7 @@ - + @@ -21280,7 +21280,7 @@ - + @@ -21463,13 +21463,13 @@ - + - + @@ -23168,7 +23168,7 @@ - + @@ -25095,7 +25095,7 @@ - + @@ -25220,7 +25220,7 @@ - + @@ -25764,14 +25764,14 @@ - + - + @@ -25940,14 +25940,14 @@ - + - + @@ -26031,7 +26031,7 @@ - + @@ -26046,21 +26046,21 @@ - + - + - + @@ -26309,14 +26309,14 @@ - + - + @@ -30237,13 +30237,13 @@ - + - + @@ -30454,14 +30454,14 @@ - + - + @@ -30848,7 +30848,7 @@ - + @@ -31418,7 +31418,7 @@ - + @@ -31605,7 +31605,7 @@ - + @@ -31854,14 +31854,14 @@ - + - + @@ -33194,7 +33194,7 @@ - + @@ -33225,7 +33225,7 @@ - + @@ -34445,14 +34445,14 @@ - + - + @@ -34854,7 +34854,7 @@ - + @@ -34894,7 +34894,7 @@ - + @@ -34953,7 +34953,7 @@ - + @@ -34975,7 +34975,7 @@ - + @@ -35035,7 +35035,7 @@ - + @@ -35050,7 +35050,7 @@ - + @@ -35201,7 +35201,7 @@ - + @@ -35226,7 +35226,7 @@ - + @@ -35293,7 +35293,7 @@ - + @@ -35318,7 +35318,7 @@ - + @@ -36146,13 +36146,13 @@ - + - + diff --git a/tests/data/test-read-dwarf/test12-pr18844.so.abi b/tests/data/test-read-dwarf/test12-pr18844.so.abi index e5bf9c0cd26f..57e1da3f401a 100644 --- a/tests/data/test-read-dwarf/test12-pr18844.so.abi +++ b/tests/data/test-read-dwarf/test12-pr18844.so.abi @@ -231,47 +231,47 @@ - - + + - - + + - - + + - - - + + + - + - - + + - - + + - - - - + + + + - - + + @@ -27045,7 +27045,7 @@ - + @@ -27072,7 +27072,7 @@ - + @@ -27086,7 +27086,7 @@ - + @@ -27139,7 +27139,7 @@ - + @@ -27149,7 +27149,7 @@ - + @@ -27243,7 +27243,7 @@ - + @@ -27376,7 +27376,7 @@ - + @@ -36822,7 +36822,7 @@ - + @@ -40693,14 +40693,14 @@ - + - + diff --git a/tests/data/test-read-dwarf/test15-pr18892.so.abi b/tests/data/test-read-dwarf/test15-pr18892.so.abi index 6dc283718846..c7e5f575986a 100644 --- a/tests/data/test-read-dwarf/test15-pr18892.so.abi +++ b/tests/data/test-read-dwarf/test15-pr18892.so.abi @@ -101,72 +101,72 @@ - + - + - - - - - - + + + + + + - - + + - + - - + + - + - + - - - - + + + + - - - - - + + + + + - - + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -175,209 +175,209 @@ - + - + - - - + + + - + - - + + - + - - + + - - + + - - + + - - + + - + - - + + - - + + - + - - + + - - - - - - + + + + + + - - + + - - - + + + - - - + + + - + - + - + - - + + - - - - - + + + + + - - - + + + - + - + - + - - + + - + - + - + - - + + - - + + - - - - + + + + - + - - - - - + + + + + - - - - + + + + - - - + + + - + - + - + - + - + - - + + - - + + - + - - + + - + @@ -385,50 +385,50 @@ - + - + - + - + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - + - + - - - - - - + + + + + + - - + + @@ -1116,9 +1116,9 @@ - + - + @@ -1208,9 +1208,9 @@ - + - + @@ -1219,53 +1219,53 @@ - + - - + + - + - + - - - - + + + + - - - - - + + + + + - - + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -1274,209 +1274,209 @@ - + - + - - - + + + - + - - + + - + - - + + - - + + - - + + - - + + - + - - + + - - + + - + - - + + - - - - - - + + + + + + - - + + - - - + + + - - - + + + - + - + - + - - + + - - - - - + + + + + - - - + + + - + - + - + - - + + - + - + - + - - + + - - + + - - - - + + + + - + - - - - - + + + + + - - - - + + + + - - - + + + - + - + - + - + - + - - + + - - + + - + - - + + - + @@ -1484,40 +1484,40 @@ - + - + - + - + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - + - + @@ -7414,17 +7414,17 @@ - + - + - + @@ -10937,7 +10937,7 @@ - + @@ -10952,7 +10952,7 @@ - + @@ -10963,7 +10963,7 @@ - + @@ -10978,12 +10978,12 @@ - + - + @@ -10991,23 +10991,23 @@ - + - + - + - + @@ -11025,7 +11025,7 @@ - + @@ -11036,20 +11036,20 @@ - + - + - + - + @@ -11060,7 +11060,7 @@ - + @@ -11071,12 +11071,12 @@ - + - + @@ -11086,12 +11086,12 @@ - + - + @@ -11107,28 +11107,28 @@ - + - + - + - + - + @@ -11141,17 +11141,17 @@ - + - + - + @@ -11166,7 +11166,7 @@ - + @@ -11186,7 +11186,7 @@ - + @@ -11201,7 +11201,7 @@ - + @@ -11219,11 +11219,11 @@ - + - + @@ -11243,11 +11243,11 @@ - + - + @@ -11261,7 +11261,7 @@ - + @@ -11277,14 +11277,14 @@ - + - + @@ -11309,13 +11309,13 @@ - + - + @@ -11325,19 +11325,19 @@ - + - + - + @@ -11354,7 +11354,7 @@ - + @@ -11367,7 +11367,7 @@ - + @@ -11375,36 +11375,36 @@ - + - + - + - + - + - + @@ -11431,7 +11431,7 @@ - + @@ -11441,11 +11441,11 @@ - + - + @@ -11457,12 +11457,12 @@ - + - + @@ -11503,7 +11503,7 @@ - + @@ -11512,7 +11512,7 @@ - + @@ -11546,7 +11546,7 @@ - + @@ -11562,7 +11562,7 @@ - + @@ -11580,14 +11580,14 @@ - + - + @@ -11599,7 +11599,7 @@ - + @@ -11616,17 +11616,17 @@ - + - + - + @@ -11636,47 +11636,47 @@ - + - + - + - + - + - + - + - + @@ -11694,18 +11694,18 @@ - + - + - + @@ -11716,7 +11716,7 @@ - + @@ -11725,12 +11725,12 @@ - + - + @@ -11739,11 +11739,11 @@ - + - + @@ -11752,11 +11752,11 @@ - + - + @@ -11764,14 +11764,14 @@ - + - + @@ -11784,41 +11784,41 @@ - + - + - + - + - + - + @@ -11838,7 +11838,7 @@ - + @@ -11849,7 +11849,7 @@ - + @@ -11859,7 +11859,7 @@ - + @@ -11881,7 +11881,7 @@ - + @@ -11896,12 +11896,12 @@ - + - + @@ -11919,7 +11919,7 @@ - + @@ -11930,14 +11930,14 @@ - + - + @@ -11948,7 +11948,7 @@ - + @@ -11956,7 +11956,7 @@ - + @@ -11964,7 +11964,7 @@ - + @@ -11993,11 +11993,11 @@ - + - + @@ -12010,7 +12010,7 @@ - + @@ -12035,11 +12035,11 @@ - + - + @@ -12052,13 +12052,13 @@ - + - + @@ -12077,7 +12077,7 @@ - + @@ -12085,13 +12085,13 @@ - + - + @@ -12102,12 +12102,12 @@ - + - + @@ -12127,7 +12127,7 @@ - + @@ -12155,12 +12155,12 @@ - + - + @@ -12171,7 +12171,7 @@ - + @@ -12182,13 +12182,13 @@ - + - + @@ -12208,7 +12208,7 @@ - + @@ -12221,17 +12221,17 @@ - + - + - + @@ -12244,7 +12244,7 @@ - + @@ -12269,7 +12269,7 @@ - + @@ -12277,12 +12277,12 @@ - + - + @@ -12307,7 +12307,7 @@ - + @@ -12315,7 +12315,7 @@ - + @@ -12325,7 +12325,7 @@ - + @@ -12333,7 +12333,7 @@ - + @@ -12399,7 +12399,7 @@ - + @@ -12417,7 +12417,7 @@ - + @@ -12428,7 +12428,7 @@ - + @@ -12443,7 +12443,7 @@ - + @@ -12467,7 +12467,7 @@ - + @@ -12519,11 +12519,11 @@ - + - + @@ -12531,12 +12531,12 @@ - + - + @@ -12546,11 +12546,11 @@ - + - + @@ -12560,12 +12560,12 @@ - + - + @@ -12589,7 +12589,7 @@ - + @@ -12598,7 +12598,7 @@ - + @@ -14768,7 +14768,7 @@ - + @@ -14778,7 +14778,7 @@ - + diff --git a/tests/data/test-read-dwarf/test16-pr18904.so.abi b/tests/data/test-read-dwarf/test16-pr18904.so.abi index 8706ed606c56..49262964fd08 100644 --- a/tests/data/test-read-dwarf/test16-pr18904.so.abi +++ b/tests/data/test-read-dwarf/test16-pr18904.so.abi @@ -41,16 +41,16 @@ - - - - + + + + - - - - + + + + @@ -58,8 +58,8 @@ - - + + @@ -67,16 +67,16 @@ - - + + - - + + @@ -95,11 +95,11 @@ - - + + - - + + @@ -123,10 +123,10 @@ - - - - + + + + @@ -156,10 +156,10 @@ - - - - + + + + @@ -180,18 +180,18 @@ - - - - + + + + - - + + @@ -199,14 +199,14 @@ - + - + - - + + @@ -215,20 +215,20 @@ - - + + - - + + - - + + @@ -242,30 +242,30 @@ - + - + - - + + - - + + - + - + - - + + @@ -273,35 +273,35 @@ - - - - + + + + - - - - - - + + + + + + - - - - + + + + - - - - + + + + @@ -316,8 +316,8 @@ - - + + @@ -329,30 +329,30 @@ - - + + - - - - + + + + - + - + - - + + @@ -386,20 +386,20 @@ - - - - + + + + - - + + - - + + @@ -584,57 +584,57 @@ - - - - + + + + - - + + - - - - + + + + - - + + - - - - + + + + - - + + - - + + - - - - - - + + + + + + - - + + @@ -647,7 +647,7 @@ - + @@ -655,17 +655,17 @@ - + - + - + @@ -687,10 +687,10 @@ - - - - + + + + @@ -706,17 +706,17 @@ - - - - + + + + - - + + - - + + @@ -725,73 +725,73 @@ - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + @@ -819,28 +819,28 @@ - - + + - - + + - - + + - - + + - - + + @@ -859,20 +859,20 @@ - + - + - + - + - - + + @@ -881,8 +881,8 @@ - - + + @@ -892,40 +892,40 @@ - - + + - + - + - + - + - + - + - - + + - - + + @@ -934,18 +934,18 @@ - - - - + + + + - - + + @@ -956,63 +956,63 @@ - + - + - + - + - + - + - + - + - + - - - + + + - - - - - - - - - + + + + + + + + + - - + + - - + + - - - + + + @@ -1025,13 +1025,13 @@ - - - - + + + + - - + + @@ -1040,10 +1040,10 @@ - - - - + + + + @@ -1056,8 +1056,8 @@ - - + + @@ -1069,8 +1069,8 @@ - - + + @@ -1100,10 +1100,10 @@ - - - - + + + + @@ -1119,8 +1119,8 @@ - - + + @@ -1134,8 +1134,8 @@ - - + + @@ -1145,45 +1145,45 @@ - - + + - - + + - - + + - + - + - + - + - - + + - - + + @@ -1194,8 +1194,8 @@ - - + + @@ -1207,8 +1207,8 @@ - - + + @@ -1218,23 +1218,23 @@ - - + + - - + + - - + + - - + + @@ -1255,8 +1255,8 @@ - - + + @@ -1281,13 +1281,13 @@ - - - - + + + + - - + + @@ -1296,8 +1296,8 @@ - - + + @@ -1341,16 +1341,16 @@ - - + + - - + + @@ -1371,8 +1371,8 @@ - - + + @@ -1382,16 +1382,16 @@ - + - + - - - - + + + + @@ -1400,8 +1400,8 @@ - - + + @@ -1423,11 +1423,11 @@ - + - - - + + + @@ -1479,9 +1479,9 @@ - + - + @@ -1525,12 +1525,12 @@ - + - - + + - + @@ -2577,14 +2577,14 @@ - + - + @@ -2656,7 +2656,7 @@ - + @@ -2735,14 +2735,14 @@ - + - + @@ -2750,14 +2750,14 @@ - + - + @@ -2880,7 +2880,7 @@ - + @@ -2984,7 +2984,7 @@ - + @@ -3035,7 +3035,7 @@ - + @@ -3436,7 +3436,7 @@ - + @@ -3454,7 +3454,7 @@ - + @@ -4853,7 +4853,7 @@ - + @@ -5720,13 +5720,13 @@ - + - + @@ -6265,7 +6265,7 @@ - + @@ -6798,14 +6798,14 @@ - + - + @@ -6852,7 +6852,7 @@ - + @@ -6996,7 +6996,7 @@ - + @@ -7521,7 +7521,7 @@ - + @@ -7543,7 +7543,7 @@ - + @@ -7551,7 +7551,7 @@ - + @@ -7728,7 +7728,7 @@ - + @@ -8259,7 +8259,7 @@ - + @@ -8616,7 +8616,7 @@ - + @@ -8624,7 +8624,7 @@ - + @@ -8679,14 +8679,14 @@ - + - + @@ -8981,14 +8981,14 @@ - + - + @@ -9331,7 +9331,7 @@ - + @@ -9488,7 +9488,7 @@ - + @@ -9707,7 +9707,7 @@ - + @@ -9840,14 +9840,14 @@ - + - + @@ -10003,7 +10003,7 @@ - + @@ -10223,7 +10223,7 @@ - + @@ -10247,7 +10247,7 @@ - + @@ -10365,14 +10365,14 @@ - + - + @@ -10736,7 +10736,7 @@ - + @@ -11486,7 +11486,7 @@ - + @@ -11510,13 +11510,13 @@ - + - + @@ -11554,7 +11554,7 @@ - + @@ -11852,14 +11852,14 @@ - + - + @@ -11973,7 +11973,7 @@ - + @@ -11987,7 +11987,7 @@ - + @@ -12055,7 +12055,7 @@ - + @@ -12127,7 +12127,7 @@ - + @@ -12135,7 +12135,7 @@ - + @@ -12151,7 +12151,7 @@ - + @@ -12218,7 +12218,7 @@ - + @@ -12330,7 +12330,7 @@ - + @@ -12338,7 +12338,7 @@ - + @@ -12750,7 +12750,7 @@ - + @@ -13466,7 +13466,7 @@ - + @@ -13475,7 +13475,7 @@ - + @@ -13529,7 +13529,7 @@ - + @@ -13626,7 +13626,7 @@ - + @@ -13975,7 +13975,7 @@ - + @@ -14392,19 +14392,19 @@ - + - + - + @@ -14433,7 +14433,7 @@ - + @@ -14501,7 +14501,7 @@ - + @@ -15154,13 +15154,13 @@ - + - + @@ -15175,7 +15175,7 @@ - + @@ -15209,7 +15209,7 @@ - + @@ -15218,7 +15218,7 @@ - + @@ -15228,7 +15228,7 @@ - + @@ -15241,7 +15241,7 @@ - + @@ -15279,33 +15279,33 @@ - + - + - + - + - + @@ -15396,7 +15396,7 @@ - + @@ -16172,14 +16172,14 @@ - + - + @@ -16401,7 +16401,7 @@ - + @@ -16747,7 +16747,7 @@ - + @@ -16853,7 +16853,7 @@ - + @@ -17244,7 +17244,7 @@ - + @@ -17300,7 +17300,7 @@ - + @@ -18388,7 +18388,7 @@ - + @@ -18455,7 +18455,7 @@ - + @@ -18567,7 +18567,7 @@ - + @@ -18699,7 +18699,7 @@ - + @@ -18712,7 +18712,7 @@ - + @@ -18847,7 +18847,7 @@ - + @@ -18860,7 +18860,7 @@ - + @@ -19378,7 +19378,7 @@ - + @@ -19399,7 +19399,7 @@ - + @@ -19729,7 +19729,7 @@ - + @@ -19737,7 +19737,7 @@ - + @@ -20058,7 +20058,7 @@ - + @@ -20351,7 +20351,7 @@ - + @@ -20361,7 +20361,7 @@ - + @@ -20639,14 +20639,14 @@ - + - + @@ -20677,7 +20677,7 @@ - + @@ -20951,13 +20951,13 @@ - + - + @@ -21285,7 +21285,7 @@ - + @@ -21710,7 +21710,7 @@ - + @@ -21724,7 +21724,7 @@ - + @@ -21738,7 +21738,7 @@ - + @@ -21807,7 +21807,7 @@ - + @@ -22362,7 +22362,7 @@ - + @@ -22972,7 +22972,7 @@ - + @@ -22980,7 +22980,7 @@ - + @@ -23193,14 +23193,14 @@ - + - + @@ -23265,7 +23265,7 @@ - + @@ -23834,7 +23834,7 @@ - + @@ -23868,7 +23868,7 @@ - + @@ -24105,7 +24105,7 @@ - + @@ -24113,7 +24113,7 @@ - + @@ -24306,7 +24306,7 @@ - + @@ -24374,7 +24374,7 @@ - + @@ -24490,7 +24490,7 @@ - + @@ -24797,14 +24797,14 @@ - + - + @@ -24909,7 +24909,7 @@ - + @@ -26938,7 +26938,7 @@ - + @@ -27080,7 +27080,7 @@ - + @@ -27611,14 +27611,14 @@ - + - + @@ -27671,7 +27671,7 @@ - + @@ -28818,7 +28818,7 @@ - + @@ -28939,7 +28939,7 @@ - + @@ -28947,7 +28947,7 @@ - + @@ -29062,7 +29062,7 @@ - + @@ -30401,14 +30401,14 @@ - + - + @@ -30627,14 +30627,14 @@ - + - + @@ -30704,7 +30704,7 @@ - + @@ -30770,7 +30770,7 @@ - + @@ -30850,14 +30850,14 @@ - + - + @@ -30934,7 +30934,7 @@ - + @@ -31000,7 +31000,7 @@ - + @@ -31192,7 +31192,7 @@ - + @@ -31202,7 +31202,7 @@ - + @@ -31297,7 +31297,7 @@ - + @@ -31472,7 +31472,7 @@ - + @@ -31544,7 +31544,7 @@ - + @@ -31717,7 +31717,7 @@ - + @@ -31978,7 +31978,7 @@ - + @@ -31986,7 +31986,7 @@ - + @@ -32436,7 +32436,7 @@ - + @@ -32732,7 +32732,7 @@ - + @@ -33369,7 +33369,7 @@ - + @@ -33561,14 +33561,14 @@ - + - + @@ -33613,7 +33613,7 @@ - + @@ -34162,14 +34162,14 @@ - + - + @@ -34259,7 +34259,7 @@ - + @@ -34274,13 +34274,13 @@ - + - + @@ -35207,7 +35207,7 @@ - + @@ -35220,7 +35220,7 @@ - + @@ -35233,7 +35233,7 @@ - + @@ -35246,7 +35246,7 @@ - + @@ -35259,7 +35259,7 @@ - + @@ -35319,7 +35319,7 @@ - + @@ -35373,7 +35373,7 @@ - + @@ -35508,7 +35508,7 @@ - + @@ -35554,7 +35554,7 @@ - + @@ -35607,7 +35607,7 @@ - + diff --git a/tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi b/tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi index 391968ebbc51..9110d9c7f2ef 100644 --- a/tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi +++ b/tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi @@ -553,11 +553,11 @@ - - - + + + - + @@ -566,53 +566,53 @@ - + - + - + - + - + - + - - + + - - + + - - + + - + - - + + - + @@ -26358,7 +26358,7 @@ - + @@ -26368,17 +26368,17 @@ - + - + - + @@ -26392,7 +26392,7 @@ - + @@ -26405,7 +26405,7 @@ - + @@ -26422,11 +26422,11 @@ - + - + @@ -26435,11 +26435,11 @@ - + - + diff --git a/tests/data/test-read-dwarf/test2.so.abi b/tests/data/test-read-dwarf/test2.so.abi index 98dd9a607266..e3cee34c5826 100644 --- a/tests/data/test-read-dwarf/test2.so.abi +++ b/tests/data/test-read-dwarf/test2.so.abi @@ -6,10 +6,10 @@ - - - - + + + + @@ -35,7 +35,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/tests/data/test-read-dwarf/test2.so.hash.abi b/tests/data/test-read-dwarf/test2.so.hash.abi index bb814f733f1d..5e1ae6d13ba7 100644 --- a/tests/data/test-read-dwarf/test2.so.hash.abi +++ b/tests/data/test-read-dwarf/test2.so.hash.abi @@ -6,10 +6,10 @@ - - - - + + + + @@ -35,7 +35,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi b/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi index 438d712fb477..5b141a06c073 100644 --- a/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi +++ b/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi @@ -7,32 +7,32 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -736,14 +736,14 @@ - + - + - + - + @@ -837,32 +837,32 @@ - - + + - + - + - - + + - - - + + + - + - + - - + + - + @@ -949,8 +949,8 @@ - - + + @@ -985,8 +985,8 @@ - - + + @@ -1075,33 +1075,33 @@ - - - + + + - + - - + + - - - + + + - + - - + + - - + + @@ -1130,45 +1130,45 @@ - + - - + + - + - - + + - + - + - + - - + + - + - - - - - - + + + + + + - - + + @@ -1179,25 +1179,25 @@ - - + + - - + + - - - - - - + + + + + + - - + + @@ -1205,16 +1205,16 @@ - - - - + + + + - - + + - - + + @@ -1229,16 +1229,16 @@ - - + + - - + + @@ -1257,11 +1257,11 @@ - - + + - - + + @@ -1273,25 +1273,25 @@ - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - + + @@ -1304,8 +1304,8 @@ - - + + @@ -1360,8 +1360,8 @@ - - + + @@ -1420,8 +1420,8 @@ - - + + @@ -1456,8 +1456,8 @@ - - + + @@ -1493,8 +1493,8 @@ - - + + @@ -1557,36 +1557,36 @@ - - + + - - + + - - + + - - + + - - + + - - + + @@ -1597,12 +1597,12 @@ - + - - + + - + @@ -1646,8 +1646,8 @@ - - + + @@ -1683,9 +1683,9 @@ - + - + @@ -1703,9 +1703,9 @@ - + - + @@ -1721,59 +1721,59 @@ - + - + - - + + - - + + - - + + - - - - + + + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + @@ -1781,61 +1781,61 @@ - - + + - - + + - - - - + + + + - - - - + + + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + @@ -1869,8 +1869,8 @@ - - + + @@ -1909,24 +1909,24 @@ - - + + - + - + - - + + - - - - + + + + - - + + @@ -1947,37 +1947,37 @@ - + - + - - + + - - + + - - - - + + + + - - - - + + + + - - + + @@ -1995,24 +1995,24 @@ - - + + - - + + - + - + - - - - + + + + @@ -2021,16 +2021,16 @@ - - + + - - + + - - + + @@ -2044,23 +2044,23 @@ - - - - + + + + - - + + - - + + - - + + @@ -2068,33 +2068,33 @@ - - - - + + + + - - + + - - + + - - - - - - + + + + + + - - + + @@ -2108,19 +2108,19 @@ - - + + - + - + - - + + @@ -2148,12 +2148,12 @@ - + - + - - + + @@ -2173,20 +2173,20 @@ - - + + - - - - + + + + - - + + @@ -3698,7 +3698,7 @@ - + @@ -3776,7 +3776,7 @@ - + @@ -4004,7 +4004,7 @@ - + @@ -4833,13 +4833,13 @@ - + - + @@ -4996,7 +4996,7 @@ - + @@ -5036,7 +5036,7 @@ - + @@ -5080,7 +5080,7 @@ - + @@ -5223,7 +5223,7 @@ - + @@ -5473,7 +5473,7 @@ - + @@ -5815,7 +5815,7 @@ - + @@ -6685,7 +6685,7 @@ - + @@ -6779,7 +6779,7 @@ - + @@ -8715,7 +8715,7 @@ - + @@ -10155,7 +10155,7 @@ - + @@ -10182,7 +10182,7 @@ - + @@ -10470,7 +10470,7 @@ - + @@ -10728,7 +10728,7 @@ - + @@ -10749,7 +10749,7 @@ - + @@ -10803,13 +10803,13 @@ - + - + @@ -11178,7 +11178,7 @@ - + @@ -11701,7 +11701,7 @@ - + @@ -12080,7 +12080,7 @@ - + @@ -13468,14 +13468,14 @@ - + - + @@ -13489,7 +13489,7 @@ - + @@ -13498,7 +13498,7 @@ - + @@ -13526,7 +13526,7 @@ - + @@ -13534,7 +13534,7 @@ - + @@ -13543,7 +13543,7 @@ - + @@ -13608,7 +13608,7 @@ - + @@ -15376,14 +15376,14 @@ - + - + @@ -15398,7 +15398,7 @@ - + @@ -15419,7 +15419,7 @@ - + @@ -15437,7 +15437,7 @@ - + @@ -15446,7 +15446,7 @@ - + @@ -15482,7 +15482,7 @@ - + @@ -15544,7 +15544,7 @@ - + @@ -16362,7 +16362,7 @@ - + @@ -17565,7 +17565,7 @@ - + @@ -19545,7 +19545,7 @@ - + @@ -19605,7 +19605,7 @@ - + @@ -22174,7 +22174,7 @@ - + @@ -26389,7 +26389,7 @@ - + @@ -28444,7 +28444,7 @@ - + @@ -28598,14 +28598,14 @@ - + - + @@ -29017,21 +29017,21 @@ - + - + - + @@ -29044,7 +29044,7 @@ - + @@ -29060,7 +29060,7 @@ - + @@ -29635,7 +29635,7 @@ - + @@ -29884,14 +29884,14 @@ - + - + @@ -29913,7 +29913,7 @@ - + @@ -30597,7 +30597,7 @@ - + @@ -31008,7 +31008,7 @@ - + @@ -31767,7 +31767,7 @@ - + @@ -32051,7 +32051,7 @@ - + @@ -33322,7 +33322,7 @@ - + @@ -33345,7 +33345,7 @@ - + @@ -36349,7 +36349,7 @@ - + @@ -36371,7 +36371,7 @@ - + @@ -36389,7 +36389,7 @@ - + @@ -36429,7 +36429,7 @@ - + @@ -36469,7 +36469,7 @@ - + @@ -36491,7 +36491,7 @@ - + @@ -36534,7 +36534,7 @@ - + @@ -36577,7 +36577,7 @@ - + @@ -36595,7 +36595,7 @@ - + @@ -36635,7 +36635,7 @@ - + @@ -36657,7 +36657,7 @@ - + @@ -36993,7 +36993,7 @@ - + @@ -37249,7 +37249,7 @@ - + @@ -37599,7 +37599,7 @@ - + @@ -37620,7 +37620,7 @@ - + @@ -37799,7 +37799,7 @@ - + @@ -37897,7 +37897,7 @@ - + @@ -38237,7 +38237,7 @@ - + @@ -38344,7 +38344,7 @@ - + @@ -38950,7 +38950,7 @@ - + @@ -39108,7 +39108,7 @@ - + @@ -39667,14 +39667,14 @@ - + - + @@ -39841,7 +39841,7 @@ - + @@ -39985,7 +39985,7 @@ - + @@ -40000,7 +40000,7 @@ - + @@ -40023,7 +40023,7 @@ - + @@ -40163,7 +40163,7 @@ - + @@ -40184,7 +40184,7 @@ - + @@ -40317,7 +40317,7 @@ - + @@ -40480,7 +40480,7 @@ - + @@ -40501,7 +40501,7 @@ - + @@ -40638,7 +40638,7 @@ - + @@ -40646,7 +40646,7 @@ - + @@ -40900,14 +40900,14 @@ - + - + @@ -40915,7 +40915,7 @@ - + @@ -40937,7 +40937,7 @@ - + @@ -41045,7 +41045,7 @@ - + @@ -41074,7 +41074,7 @@ - + @@ -41218,7 +41218,7 @@ - + @@ -41233,7 +41233,7 @@ - + @@ -41535,14 +41535,14 @@ - + - + @@ -41550,7 +41550,7 @@ - + @@ -41573,7 +41573,7 @@ - + @@ -41864,14 +41864,14 @@ - + - + @@ -41879,7 +41879,7 @@ - + @@ -41902,7 +41902,7 @@ - + @@ -41990,14 +41990,14 @@ - + - + @@ -42230,7 +42230,7 @@ - + @@ -42251,7 +42251,7 @@ - + @@ -42436,7 +42436,7 @@ - + @@ -44632,7 +44632,7 @@ - + @@ -44658,7 +44658,7 @@ - + @@ -44702,7 +44702,7 @@ - + @@ -44723,7 +44723,7 @@ - + @@ -44799,7 +44799,7 @@ - + @@ -44854,7 +44854,7 @@ - + @@ -44913,7 +44913,7 @@ - + @@ -44930,7 +44930,7 @@ - + @@ -44951,7 +44951,7 @@ - + @@ -45250,7 +45250,7 @@ - + @@ -45265,7 +45265,7 @@ - + @@ -45273,7 +45273,7 @@ - + @@ -45281,7 +45281,7 @@ - + @@ -45289,7 +45289,7 @@ - + @@ -45298,7 +45298,7 @@ - + @@ -45307,7 +45307,7 @@ - + @@ -45330,7 +45330,7 @@ - + @@ -46537,14 +46537,14 @@ - + - + @@ -48115,7 +48115,7 @@ - + @@ -48155,7 +48155,7 @@ - + @@ -48195,7 +48195,7 @@ - + @@ -48238,7 +48238,7 @@ - + @@ -48303,7 +48303,7 @@ - + @@ -48321,7 +48321,7 @@ - + @@ -48361,7 +48361,7 @@ - + @@ -48766,7 +48766,7 @@ - + @@ -49243,7 +49243,7 @@ - + diff --git a/tests/data/test-read-dwarf/test3.so.abi b/tests/data/test-read-dwarf/test3.so.abi index 7357a7401c6e..96d8cc310237 100644 --- a/tests/data/test-read-dwarf/test3.so.abi +++ b/tests/data/test-read-dwarf/test3.so.abi @@ -3,16 +3,16 @@ - + - + - + diff --git a/tests/data/test-read-dwarf/test3.so.hash.abi b/tests/data/test-read-dwarf/test3.so.hash.abi index e01f395983fa..22540639c41d 100644 --- a/tests/data/test-read-dwarf/test3.so.hash.abi +++ b/tests/data/test-read-dwarf/test3.so.hash.abi @@ -3,16 +3,16 @@ - + - + - + diff --git a/tests/data/test-symtab/basic/aliases.c b/tests/data/test-symtab/basic/aliases.c new file mode 100644 index 000000000000..319f463249dc --- /dev/null +++ b/tests/data/test-symtab/basic/aliases.c @@ -0,0 +1,13 @@ +void exported_function(){} + +void exported_function_alias() __attribute__((alias("exported_function"))); +void exported_function_another_alias() __attribute__((alias("exported_function"))); +void exported_function_weak_alias() __attribute__((weak, alias("exported_function"))); +void exported_function_another_weak_alias() __attribute__((weak, alias("exported_function"))); + +int exported_variable = 42; + +extern int exported_variable_alias __attribute__((alias("exported_variable"))); +extern int exported_variable_another_alias __attribute__((alias("exported_variable"))); +extern int exported_variable_weak_alias __attribute__((weak, alias("exported_variable"))); +extern int exported_variable_another_weak_alias __attribute__((weak, alias("exported_variable"))); diff --git a/tests/data/test-symtab/basic/aliases.so b/tests/data/test-symtab/basic/aliases.so new file mode 100755 index 0000000000000000000000000000000000000000..95a5c058e95d5f7027b767e1200bf2cef5d5bead GIT binary patch literal 17176 zcmeHOYiJzT6~42hwN_qf^>EV2v0IJJ1{}A$QW8I8yRt@4uZ-llsss&*JDS}c?JnJ& z6+5$$loTp32@Y;R{n1xQAQV&F&{7xLA1$TCI1O$7^hJvaZE;FM9Ga#I#l?Mjd(O-~ zv$M0aD)dL8VJ_^PbHDSr_nx_P=Z~W>9*BHP2A898zRcMUu+|cB3}2>Fz*skk|S)jC!sME$+|l960Z_<+hJEWlD5Le z$wqpKw|ALSvI~J4+HG>XO>Rf@EY~L*vE5pI#C{H=10Ncv{X5^CNw$-}+7G z;M-qikNo7f*aMW~eMUR%UtB(Tb)PIPA%?N)gx{xU#$WsH*^bViz1i`~$s@+2@yOt% z_wIS^+^<)ku1$8g&zSMt;^I347eTdUnFfjEBmGzl9LMjckNxz+7eUa=`j{kx0u+jS z4*31>G~D6=ZMUS1eFJEp5B}2@_~%>rIozV%zkvQepZ@fNz90Su===45u|7r)K{3S|eO;wf)x>_tep)qZ3rCc$! ztg>9yGiITzHzSIwm(9FZQC2neGYXighL6&=Lh{hc*n>Z=RtnZIoZb<#ZC@NEzrHxa z7JaG9tpUP4p!JB>k1al*F7Wk+@GBhem%#`M;Z(mdYUB82qF+fAc#N^fgl1w1pa>`kUIZvBy}`^q4Zn`$*lqJ}aQ7wT!Cgn~M)$x5>R#g% z^uJ^2A4Wf^`|qTl*-Bk~Z!~rFwwMxLP5t7Ic^5dC;|?OV8_V4TlXd%zkrIelb#O6t ze&i#_rk;7r>`Yx8ISrMY=W4au%{*LQ4NpN`I7jUgedkFKE`rVGxog(g8%B#g4N4G! zAOb-If(Qf=2qF+fAc#N^fgl1w1cC?z5%}OmK-eRmh{Le(e?QVzttJB<0-6VU3+M(= zEcm}(EW#7>Ojzp?_H?#KHsK#kXuB7F*Z*9rS^t`f^-Rb5Pj^RGBO7e=-V+BOitk4| zw1>}l_A=L?DPj5P={9 zK?H&b1Q7@#@PUW`opYpfjd&i|D*T*d7q9-4*LU+eotNCh>-4R7FR#*z6!PQE(z^*XsAhKp8 zGav;QyIDtwIwypM(;*SG>pFw0#$cwbo0UR(uvkc|=|WB|6cuB=WUA>wQ!`9sFsquX z#U?nMR*gcYet_CJcf8%9WjxO>O+0YazQaRi}3Uv@Ws2F^XP6Xk;NFTtBrU!^IJzm7%ZJfZ`AK)Om-tSFG4;8tvhb1 z$aX>Ah#Mh&`m1E4Ok{UA0=y=&54FJIf%hq*v&uILMMiI-It~vstZVPr>WIzZ`WC`$ zDbM|iaeT#t@8dYV4{a}u9R)^k#R1#Hf_X23&wVKYj_q!F{I6U3&G+{!fcy2o)wsT9 z`RQaYO2BxEpPwtBBe3Rq@_h^MV+Z6$C)VQbGar5lY9Y)d@{H@cW!^l`|7htqKNs%< zEF$u)*^fQ9wVBEbqfo&i!9m0KHVxZT+uh#)At=w`ku3t;lkZf zm8F0~-(*kwIii=jrnmpp{yfOhC%mcbLhmb1y*mzX{9Xbpx4p#eh?2V&?%Ah2_Oy>A zO7S9lsuNW`_OyQ?`a?40)Z3q&$Da13MCm)2+<3>2`xhKP#h*!BlhZh_67kwU2?Do0 z?Q@BKmJB(iaTEL$Ft|sf`%8aspgd`>KGlihcW$@Kp7zZbcpf?Ffr?eAPV@ypaqdw2 zw7;f2bjmlUag!b0hsVGc$4~aO55EDY;;~59wSFOcqF)D*+n&i>cgUtR&pGNme`Nn{ z5V-AWU*FH|t?zy^21<4WeUD?*|F~>R;@qCbP5RiDyZituh;emCMD}|f#Ae8z=rw?e zcdN?Wq1Ufh7x$@N4E?Nd!!Np>`sn`N2Sbza19)ZZQJXkdZ(Hwz#EYTw61SJJ;woO< z+aN>CJI)um{UMJ5Ro&Eic3tgUf6%VbI*RX^1pMg!)4amlookup_function_symbol("exported_function")->get_main_symbol(); + REQUIRE(main_symbol); + + // But since we know that 'exported_function' is the main symbol and this + // can be discovered from DWARF + CHECK(corpus->lookup_function_symbol("exported_function")->is_main_symbol()); + + CHECK(corpus->lookup_function_symbol("exported_function") + ->get_number_of_aliases() == 4); + + CHECK(main_symbol->has_aliases()); + CHECK(main_symbol->get_number_of_aliases() == 4); + CHECK(main_symbol->get_main_symbol() == main_symbol); +} + +TEST_CASE("Symtab::AliasedVariableSymbols", "[symtab, variables, aliases]") +{ + const std::string binary = "basic/aliases.so"; + const corpus_sptr& corpus = assert_symbol_count(binary, 5, 5); + // The main symbol is not necessarily the one that is aliased to in the + // code So, this can't be decided by just looking at ELF. Hence acquire the + // main symbol. + const elf_symbol_sptr& main_symbol = + corpus->lookup_variable_symbol("exported_variable")->get_main_symbol(); + REQUIRE(main_symbol); + + // But since we know that 'exported_function' is the main symbol and this + // can be discovered from DWARF + CHECK(corpus->lookup_variable_symbol("exported_variable")->is_main_symbol()); + + CHECK(corpus->lookup_variable_symbol("exported_variable") + ->get_number_of_aliases() == 4); + + CHECK(main_symbol->has_aliases()); + CHECK(main_symbol->get_number_of_aliases() == 4); + CHECK(main_symbol->get_main_symbol() == main_symbol); +} + static const char* kernel_versions[] = { "4.14", "4.19", "5.4", "5.6" }; static const size_t nr_kernel_versions = sizeof(kernel_versions) / sizeof(kernel_versions[0]); From patchwork Fri Jul 3 16:46:49 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: 39901 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 84578384402F; Fri, 3 Jul 2020 16:48:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 84578384402F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794900; bh=DRIp3LWrjInvhX1c5Kmup81ElgrSUFnBpWtliwwxUmk=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=KQsiZJQES/RJ2eyXm2IR58RE2kLi+XZEUiveqqOezvRY+r39pJnwP7zaeBjupOZpe wJv19tUzkq+4thhNQrq4KPEp/9PQntou4EwWoZCJPEFIgNwi7iuwR7cMR6HmCTYfmj kK3nrQ+wPYVa0yiEb5QLAMeK7irjknFfzLBkBX10= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wm1-x34a.google.com (mail-wm1-x34a.google.com [IPv6:2a00:1450:4864:20::34a]) by sourceware.org (Postfix) with ESMTPS id 8F45A3844079 for ; Fri, 3 Jul 2020 16:48:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8F45A3844079 Received: by mail-wm1-x34a.google.com with SMTP id t145so35789550wmt.2 for ; Fri, 03 Jul 2020 09:48:17 -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=DRIp3LWrjInvhX1c5Kmup81ElgrSUFnBpWtliwwxUmk=; b=nTtxjLBPmvbqztZjouL2lpSpDonAoex9xo1pxGMFQR7SzhgsDvCL4wNrkzDWuPQY3S pC/2UH24deDcdhHsGB8gAB4x0hFfG5osH0zKfRH4veNlKU5hk7AUvgnLYsGGMHFo3WDe gD/rX0c5jE/EvW8EE1iWloi6O9p6yTiS8aEJxNQi8NRyzgvehFoW6g42rUJN38YO1ZdR LxJk2MQqyM/mRcmKBre7VxolifS1XB7NbhlHjNnmHIPWvU8GIV5S492dt6776KUAF3Ib NukGHib/Dp11suhzZdT2JSYsMSKmHICyCQVEoPlX/JJG9v+ZF5YX0b0w3k575zTEpGN2 geFQ== X-Gm-Message-State: AOAM531B3zAPmMWS4OWlX5JuHZpg2vI1fihQdwHDfzcRa0Tkkyb0TvdQ VWztOxzDmqRTrApzMW+WXLPRV7dtRt/2WDp/iYswrwsWqf3RAcbdxKnlkiIRir0vLH1lW7FSz+q Edp0q+ZdY42rLbXBIBfg2msyQ+xxZo4pAOlU/UdULp+TqTkOtpCnrtv4yIp6OsdSrZ/TZNwY= X-Google-Smtp-Source: ABdhPJyn6ABl9tN1xEjEv58bKM6LF7JLmwRg975qCgtpDZp7rbTtUgJpm303CnAyhBvnvKbZdY8E0THKia9p7A== X-Received: by 2002:a05:600c:294a:: with SMTP id n10mr35929088wmd.38.1593794896656; Fri, 03 Jul 2020 09:48:16 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:49 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-20-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 19/21] dwarf-reader/writer: consider aliases when dealing with suppressions To: libabigail@sourceware.org X-Spam-Status: No, score=-23.4 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" When a symbol is suppressed and it happens to be the main symbol of a group of aliased symbols where another symbol is not suppressed, the dwarf reader discards the DWARF information upon reading and the writer will not be able to connect dwarf information to the aliased elf symbol. In order to address this, ensure we are not suppressing symbols (actually functions and variables) for which an alias is not suppressed. We therefore keep the DWARF information even if only a non-main symbol is asked for. Likewise, when the abg-writer is having to attach an elf-symbol-id to the DWARF collected information (for functions and variables), instead of omitting the symbol altogether, rather make use of the property of aliases and connect the dwarf information to an alias instead. This way the function dwarf information stays connected to the elf symbol that we want to track. * src/abg-dwarf-reader.cc(function_is_suppressed): Do not suppress a function for which there is an alias that is not suppressed. (variable_is_suppressed): Likewise for variables. * src/abg-writer.cc(write_elf_symbol_reference): Fall back to any aliased symbol if the main symbol is suppressed. * tests/data/Makefile.am: Add new test files. * tests/data/test-read-dwarf/test3-alias-1.so.hash.abi: New test file. * tests/data/test-read-dwarf/test3-alias-1.suppr: Likewise. * tests/data/test-read-dwarf/test3-alias-2.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-2.suppr: Likewise. * tests/data/test-read-dwarf/test3-alias-3.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-3.suppr: Likewise. * tests/data/test-read-dwarf/test3-alias-4.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-4.suppr: Likewise. * tests/test-read-dwarf.cc: Add new test cases. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-dwarf-reader.cc | 20 ++++++++++-- src/abg-writer.cc | 5 ++- tests/data/Makefile.am | 8 +++++ .../test-read-dwarf/test3-alias-1.so.hash.abi | 14 ++++++++ .../data/test-read-dwarf/test3-alias-1.suppr | 3 ++ .../test-read-dwarf/test3-alias-2.so.hash.abi | 18 +++++++++++ .../data/test-read-dwarf/test3-alias-2.suppr | 3 ++ .../test-read-dwarf/test3-alias-3.so.hash.abi | 14 ++++++++ .../data/test-read-dwarf/test3-alias-3.suppr | 3 ++ .../test-read-dwarf/test3-alias-4.so.hash.abi | 8 +++++ .../data/test-read-dwarf/test3-alias-4.suppr | 3 ++ tests/test-read-dwarf.cc | 32 +++++++++++++++++++ 12 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 tests/data/test-read-dwarf/test3-alias-1.so.hash.abi create mode 100644 tests/data/test-read-dwarf/test3-alias-1.suppr create mode 100644 tests/data/test-read-dwarf/test3-alias-2.so.hash.abi create mode 100644 tests/data/test-read-dwarf/test3-alias-2.suppr create mode 100644 tests/data/test-read-dwarf/test3-alias-3.so.hash.abi create mode 100644 tests/data/test-read-dwarf/test3-alias-3.suppr create mode 100644 tests/data/test-read-dwarf/test3-alias-4.so.hash.abi create mode 100644 tests/data/test-read-dwarf/test3-alias-4.suppr diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 4120b03b8ac5..d125cc980166 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -13002,8 +13002,16 @@ function_is_suppressed(const read_context& ctxt, if (!ctxt.get_function_address(function_die, fn_addr)) return true; - if (!ctxt.function_symbol_is_exported(fn_addr)) + elf_symbol_sptr symbol = ctxt.function_symbol_is_exported(fn_addr); + if (!symbol) return true; + if (!symbol->is_suppressed()) + return false; + if (symbol->has_aliases() && symbol->is_main_symbol()) + for (elf_symbol_sptr a = symbol->get_next_alias(); + !a->is_main_symbol(); a = a->get_next_alias()) + if (!a->is_suppressed()) + return false; } return suppr::function_is_suppressed(ctxt, qualified_name, @@ -13107,8 +13115,16 @@ variable_is_suppressed(const read_context& ctxt, if (!ctxt.get_variable_address(variable_die, var_addr)) return true; - if (!ctxt.variable_symbol_is_exported(var_addr)) + elf_symbol_sptr symbol = ctxt.variable_symbol_is_exported(var_addr); + if (!symbol) return true; + if (!symbol->is_suppressed()) + return false; + if (symbol->has_aliases() && symbol->is_main_symbol()) + for (elf_symbol_sptr a = symbol->get_next_alias(); + !a->is_main_symbol(); a = a->get_next_alias()) + if (!a->is_suppressed()) + return false; } return suppr::variable_is_suppressed(ctxt, qualified_name, diff --git a/src/abg-writer.cc b/src/abg-writer.cc index c5be11b26072..723db1a51256 100644 --- a/src/abg-writer.cc +++ b/src/abg-writer.cc @@ -1742,7 +1742,10 @@ write_elf_symbol_aliases(const elf_symbol& sym, ostream& out) static bool write_elf_symbol_reference(const elf_symbol& sym, ostream& o) { - o << " elf-symbol-id='" << sym.get_id_string() << "'"; + auto actual_sym = &sym; + while (actual_sym->is_suppressed() && actual_sym->has_aliases()) + actual_sym = actual_sym->get_next_alias().get(); + o << " elf-symbol-id='" << actual_sym->get_id_string() << "'"; return true; } diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 054acb8c5376..54ccb103c8ab 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -411,6 +411,14 @@ test-read-dwarf/test3.c \ test-read-dwarf/test3.so \ test-read-dwarf/test3.so.abi \ test-read-dwarf/test3.so.hash.abi \ +test-read-dwarf/test3-alias-1.so.hash.abi \ +test-read-dwarf/test3-alias-1.suppr \ +test-read-dwarf/test3-alias-2.so.hash.abi \ +test-read-dwarf/test3-alias-2.suppr \ +test-read-dwarf/test3-alias-3.so.hash.abi \ +test-read-dwarf/test3-alias-3.suppr \ +test-read-dwarf/test3-alias-4.so.hash.abi \ +test-read-dwarf/test3-alias-4.suppr \ test-read-dwarf/test4.c \ test-read-dwarf/test4.so \ test-read-dwarf/test4.so.abi \ diff --git a/tests/data/test-read-dwarf/test3-alias-1.so.hash.abi b/tests/data/test-read-dwarf/test3-alias-1.so.hash.abi new file mode 100644 index 000000000000..1ed4b0612886 --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-1.so.hash.abi @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/tests/data/test-read-dwarf/test3-alias-1.suppr b/tests/data/test-read-dwarf/test3-alias-1.suppr new file mode 100644 index 000000000000..b347500d4c4e --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-1.suppr @@ -0,0 +1,3 @@ +[suppress_function] + symbol_name_not_regexp = ^__foo$ + drop = true diff --git a/tests/data/test-read-dwarf/test3-alias-2.so.hash.abi b/tests/data/test-read-dwarf/test3-alias-2.so.hash.abi new file mode 100644 index 000000000000..50a53f97bf84 --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-2.so.hash.abi @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-dwarf/test3-alias-2.suppr b/tests/data/test-read-dwarf/test3-alias-2.suppr new file mode 100644 index 000000000000..b6d203d53c2b --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-2.suppr @@ -0,0 +1,3 @@ +[suppress_function] + symbol_name_regexp = ^__foo$ + drop = true diff --git a/tests/data/test-read-dwarf/test3-alias-3.so.hash.abi b/tests/data/test-read-dwarf/test3-alias-3.so.hash.abi new file mode 100644 index 000000000000..6de4d59b13d5 --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-3.so.hash.abi @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/tests/data/test-read-dwarf/test3-alias-3.suppr b/tests/data/test-read-dwarf/test3-alias-3.suppr new file mode 100644 index 000000000000..66cd33a8d353 --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-3.suppr @@ -0,0 +1,3 @@ +[suppress_function] + symbol_name_not_regexp = ^foo$ + drop = true diff --git a/tests/data/test-read-dwarf/test3-alias-4.so.hash.abi b/tests/data/test-read-dwarf/test3-alias-4.so.hash.abi new file mode 100644 index 000000000000..b26d12f80e61 --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-4.so.hash.abi @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/data/test-read-dwarf/test3-alias-4.suppr b/tests/data/test-read-dwarf/test3-alias-4.suppr new file mode 100644 index 000000000000..25a2c437f51e --- /dev/null +++ b/tests/data/test-read-dwarf/test3-alias-4.suppr @@ -0,0 +1,3 @@ +[suppress_function] + symbol_name_not_regexp = ^_init$ + drop = true diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc index 8502f8279241..dc11fbca2738 100644 --- a/tests/test-read-dwarf.cc +++ b/tests/test-read-dwarf.cc @@ -124,6 +124,38 @@ InOutSpec in_out_specs[] = "data/test-read-dwarf/test3.so.hash.abi", "output/test-read-dwarf/test3.so.hash.abi" }, + // suppress all except the main symbol of a group of aliases + { + "data/test-read-dwarf/test3.so", + "data/test-read-dwarf/test3-alias-1.suppr", + HASH_TYPE_ID_STYLE, + "data/test-read-dwarf/test3-alias-1.so.hash.abi", + "output/test-read-dwarf/test3-alias-1.so.hash.abi" + }, + // suppress the main symbol of a group of aliases + { + "data/test-read-dwarf/test3.so", + "data/test-read-dwarf/test3-alias-2.suppr", + HASH_TYPE_ID_STYLE, + "data/test-read-dwarf/test3-alias-2.so.hash.abi", + "output/test-read-dwarf/test3-alias-2.so.hash.abi" + }, + // suppress all except one non main symbol of a group of aliases + { + "data/test-read-dwarf/test3.so", + "data/test-read-dwarf/test3-alias-3.suppr", + HASH_TYPE_ID_STYLE, + "data/test-read-dwarf/test3-alias-3.so.hash.abi", + "output/test-read-dwarf/test3-alias-3.so.hash.abi" + }, + // suppress all symbols of a group of aliases + { + "data/test-read-dwarf/test3.so", + "data/test-read-dwarf/test3-alias-4.suppr", + HASH_TYPE_ID_STYLE, + "data/test-read-dwarf/test3-alias-4.so.hash.abi", + "output/test-read-dwarf/test3-alias-4.so.hash.abi" + }, { "data/test-read-dwarf/test4.so", "", 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); + } +} From patchwork Fri Jul 3 16:46:51 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: 39902 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 26B84384402F; Fri, 3 Jul 2020 16:48:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 26B84384402F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593794906; bh=OqMt+iDuVHoegHfcT/smmPCupgpEE1m6Xqnt87GLmSw=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=adKAJZUpGbQgS2V52ijuygFqAt0dDUwAu0ScxazTuBXPHxw65AKKw5PFJlH+zd3uy SPNEF1vCUv/esSa8qZVG8LHy216OkDDu9rVIp3ooHHnRjb6Tu/Bg8XYtM8H1MbPEOT P9P9lFfpe5pqF81zYSOtCcZeqlo+ba4wVdjom4qs= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-ed1-x549.google.com (mail-ed1-x549.google.com [IPv6:2a00:1450:4864:20::549]) by sourceware.org (Postfix) with ESMTPS id 80F6E384402F for ; Fri, 3 Jul 2020 16:48:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 80F6E384402F Received: by mail-ed1-x549.google.com with SMTP id 64so35008182edf.2 for ; Fri, 03 Jul 2020 09:48:22 -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=OqMt+iDuVHoegHfcT/smmPCupgpEE1m6Xqnt87GLmSw=; b=PYnOoO4qb7yzpojPY3BM1TUV87w5q1+eAnz/sheEwHYhBMVGrxwFImbTTFa/sJojno oxs+hh/7on48/atNKz6sSnT8KzxZS4h4yEcoqDLk5Zr30DN4B2gyT0IN8QDD+v/lQfYx 2d2xKrYN7lgijzacPy5Y1P6A/MWNqJypi8pw+KCUXqbXkNUSQp8AKQVNc9XKqwaRozNf czlDA+TMOftGwQaIlo6sYMyszMlwb5rb3KmuOgS3PwnwzaQisBrzFGVfLYQYlZqx3dYK fNRYzQgpWfmbgBpoBh6uDP56LpPb5lInHl+QADJl1EyyrAD8veOxC3QSLRyQUISwo+Ao FWHw== X-Gm-Message-State: AOAM531Gmjv/mX/INrSVoX7Z4eR8Knno4P5Op5k4Qtg1pwVVTZ51hqrx mpfBV06ZBMnuRntaaoJaRsXDWzes2Mamfa0dSu4e7K3jXsd3IGvfm/FHFYpfEJuouEy5LYSGzlg AzDJoziGKa9QT1pfPAFRqOIbtiEg0XXsb98Np4F3+uFLjrPyhkFRO96VO97bfmMNHp8ci4EM= X-Google-Smtp-Source: ABdhPJylkw7UwCSviEJkmn3POrHwDnQZXLrXLSjnkQBXqXqmyenT4Tl3IuWqB67IoKlkTFZxqXVNUrJUA03nkA== X-Received: by 2002:a17:906:f2d6:: with SMTP id gz22mr32613917ejb.407.1593794901347; Fri, 03 Jul 2020 09:48:21 -0700 (PDT) Date: Fri, 3 Jul 2020 18:46:51 +0200 In-Reply-To: <20200703164651.1510825-1-maennich@google.com> Message-Id: <20200703164651.1510825-22-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 21/21] reader/symtab: Improve handling for suppressed aliases To: libabigail@sourceware.org X-Spam-Status: No, score=-21.7 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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" When reading from XML with a symbol whitelist that leads to suppression of aliased symbols, abidiff would hit an assertion and crash when looking up the aliased symbol due to it being suppressed. In the new symtab reader we can still suppress a symbol without removing it from the lookup. Make use of that property to fix this bug. A test has been added for this as well. * src/abg-reader.cc (build_elf_symbol): Improve handling of suppressed aliased symbols when reading from XML. * src/abg-symtab-reader.cc (load): Likewise. * tests/data/Makefile.am: Add new test data files. * tests/data/test-abidiff-exit/test-missing-alias-report.txt: New test file. * tests/data/test-abidiff-exit/test-missing-alias.abi: Likewise. * tests/data/test-abidiff-exit/test-missing-alias.suppr: Likewise. * tests/test-abidiff-exit.cc: Add support for whitelists and add new testcase. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-reader.cc | 7 +++++-- src/abg-symtab-reader.cc | 16 ++++++++++++++-- tests/data/Makefile.am | 3 +++ .../test-missing-alias-report.txt | 0 .../test-abidiff-exit/test-missing-alias.abi | 12 ++++++++++++ .../test-abidiff-exit/test-missing-alias.suppr | 4 ++++ tests/test-abidiff-exit.cc | 9 +++++++++ 7 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tests/data/test-abidiff-exit/test-missing-alias-report.txt create mode 100644 tests/data/test-abidiff-exit/test-missing-alias.abi create mode 100644 tests/data/test-abidiff-exit/test-missing-alias.suppr diff --git a/src/abg-reader.cc b/src/abg-reader.cc index 3f636d00f9b8..d71e2d43503a 100644 --- a/src/abg-reader.cc +++ b/src/abg-reader.cc @@ -2850,7 +2850,8 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node, elf_symbol::version version(version_string, is_default_version); - if (drop_if_suppressed && suppr::is_elf_symbol_suppressed(ctxt, name, type)) + const bool is_suppressed = suppr::is_elf_symbol_suppressed(ctxt, name, type); + if (drop_if_suppressed && is_suppressed) return elf_symbol_sptr(); const environment* env = ctxt.get_environment(); @@ -2860,6 +2861,8 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node, version, visibility, /*is_linux_string_cst=*/false); + e->set_is_suppressed(is_suppressed); + if (crc != 0) e->set_crc(crc); @@ -2950,7 +2953,7 @@ build_elf_symbol_db(read_context& ctxt, elf_symbol_sptr sym; for (xmlNodePtr n = node->children; n; n = n->next) { - if ((sym = build_elf_symbol(ctxt, n, /*drop_if_suppress=*/true))) + if ((sym = build_elf_symbol(ctxt, n, /*drop_if_suppress=*/false))) { id_sym_map[sym->get_id_string()] = sym; xml_node_ptr_elf_symbol_map[n] = sym; diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc index c50c0f643386..424817106e70 100644 --- a/src/abg-symtab-reader.cc +++ b/src/abg-symtab-reader.cc @@ -361,7 +361,13 @@ symtab::load_(string_elf_symbols_map_sptr function_symbol_map, end = function_symbol_map->end(); it != end; ++it) { - symbols_.insert(symbols_.end(), it->second.begin(), it->second.end()); + for (elf_symbols::const_iterator sym_it = it->second.begin(), + sym_end = it->second.end(); + sym_it != sym_end; ++sym_it) + { + if (!(*sym_it)->is_suppressed()) + symbols_.push_back(*sym_it); + } ABG_ASSERT(name_symbol_map_.insert(*it).second); } @@ -371,7 +377,13 @@ symtab::load_(string_elf_symbols_map_sptr function_symbol_map, end = variables_symbol_map->end(); it != end; ++it) { - symbols_.insert(symbols_.end(), it->second.begin(), it->second.end()); + for (elf_symbols::const_iterator sym_it = it->second.begin(), + sym_end = it->second.end(); + sym_it != sym_end; ++sym_it) + { + if (!(*sym_it)->is_suppressed()) + symbols_.push_back(*sym_it); + } ABG_ASSERT(name_symbol_map_.insert(*it).second); } diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index f39a6d427b1d..bcfc3796d0bc 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -161,6 +161,9 @@ test-abidiff-exit/test-fun-param-v0.o \ test-abidiff-exit/test-fun-param-v1.abi \ test-abidiff-exit/test-fun-param-v1.c \ test-abidiff-exit/test-fun-param-v1.o \ +test-abidiff-exit/test-missing-alias-report.txt \ +test-abidiff-exit/test-missing-alias.abi \ +test-abidiff-exit/test-missing-alias.suppr \ \ test-diff-dwarf/test0-v0.cc \ test-diff-dwarf/test0-v0.o \ diff --git a/tests/data/test-abidiff-exit/test-missing-alias-report.txt b/tests/data/test-abidiff-exit/test-missing-alias-report.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/data/test-abidiff-exit/test-missing-alias.abi b/tests/data/test-abidiff-exit/test-missing-alias.abi new file mode 100644 index 000000000000..07a13f5e6d15 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-missing-alias.abi @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/data/test-abidiff-exit/test-missing-alias.suppr b/tests/data/test-abidiff-exit/test-missing-alias.suppr new file mode 100644 index 000000000000..bcebae43a350 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-missing-alias.suppr @@ -0,0 +1,4 @@ +[suppress_function] + symbol_name_not_regexp = ^__foo$ + drop = true + diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc index 4d9c19437e60..772baa78cf91 100644 --- a/tests/test-abidiff-exit.cc +++ b/tests/test-abidiff-exit.cc @@ -212,6 +212,15 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-fun-param-report.txt", "output/test-abidiff-exit/test-fun-param-report.txt" }, + { + "data/test-abidiff-exit/test-missing-alias.abi", + "data/test-abidiff-exit/test-missing-alias.abi", + "data/test-abidiff-exit/test-missing-alias.suppr", + "", + abigail::tools_utils::ABIDIFF_OK, + "data/test-abidiff-exit/test-missing-alias-report.txt", + "output/test-abidiff-exit/test-missing-alias-report.txt" + }, {0, 0, 0 ,0, abigail::tools_utils::ABIDIFF_OK, 0, 0} };