From patchwork Fri Apr 7 18:12:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 67528 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 184CC3858C83 for ; Fri, 7 Apr 2023 18:12:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 184CC3858C83 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680891166; bh=LRjyf1OfR1gML1GALZCXgR0jgtfyWv5Xv/xRaq5nxoE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=MiBHhN9e0g4Cz2RLQF7NzQf/jxgxrtD1N7VsZLW25I5LJaJ6sFm4cXjTuuDFS+QuO EvQkF5sdAxPObfCjZOVk1eo9SJRNKHKLtrpAX7EHLXN6Aljf0VcFzxgg4mYypmLWEK nr6lGAM8GkDaNFCsV3xu2fMFlxlFFLXtiTXZs8S4= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id BF94F3858D32 for ; Fri, 7 Apr 2023 18:12:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BF94F3858D32 Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-18-as2d_4ThNGqqWphGOzErtA-1; Fri, 07 Apr 2023 14:12:38 -0400 X-MC-Unique: as2d_4ThNGqqWphGOzErtA-1 Received: by mail-qv1-f69.google.com with SMTP id p14-20020a0cc3ce000000b005e14204a86bso11583547qvi.10 for ; Fri, 07 Apr 2023 11:12:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680891157; h=mime-version:user-agent:message-id:date:organization:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LRjyf1OfR1gML1GALZCXgR0jgtfyWv5Xv/xRaq5nxoE=; b=owLVZw2cUNFOk/5cmIl3jEaagybBqVQSAiiuhvQpZ3tL+jxiGr0iDIfX2SErKlQuYV QL6Zk/RzVxq9gKgrXASGCjevnudkgIPjCB0UfW4hFGEM0vvLkT8CKRxUr48hNSXes3wi Fk79jDkLQ6wXlLtTptXi8NWAcW4sJ0Rh//jubV1kFV2Eom4+mulFbtDb3Osw6Pw9I6Nd JCgqhYg2uoU0GsMo29hdnWdOFBEZHqrabTp2Q8mFUncGv5Xgb9T5K+w3aJ0ihbDRzeyS 2HUXQDWP4jQq2oWk+eFXz8IEol87dfWqUrAxGNpb8n3OXyIijdNhqJ4r2RSbFD2FSo/B kB7g== X-Gm-Message-State: AAQBX9dT+5mAJGbXfSfNpk658gdq2t7CxaE3NE0lW/fKLuZLOFyxOSP2 NbD+4sbALS7DDOyHS7zObe2EOge6shLi5VVzP5pd7AoWfl2y0uD7faVt8aLHFyarlxdAxYCIuWZ yYJjUwyvi59vSmrdRG7cDqzGtZZPJ1h562fVHgdmPEyf/KRPmxBWB8XiKvK7huxspRBoZnXrtWG LP X-Received: by 2002:a05:622a:1013:b0:3ae:189c:7455 with SMTP id d19-20020a05622a101300b003ae189c7455mr5377918qte.47.1680891157460; Fri, 07 Apr 2023 11:12:37 -0700 (PDT) X-Google-Smtp-Source: AKy350Yhq8P41+82mYOStZnqGkii341s5aS9fS6Zih0v1p/BtmquRK7Jg/+03TvEE2/rAagife35WA== X-Received: by 2002:a05:622a:1013:b0:3ae:189c:7455 with SMTP id d19-20020a05622a101300b003ae189c7455mr5377874qte.47.1680891156978; Fri, 07 Apr 2023 11:12:36 -0700 (PDT) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id d23-20020a05620a141700b00745f3200f54sm1446631qkj.112.2023.04.07.11.12.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Apr 2023 11:12:36 -0700 (PDT) Received: by localhost (Postfix, from userid 1000) id 08A4F581C7B; Fri, 7 Apr 2023 20:12:33 +0200 (CEST) To: libabigail@sourceware.org Subject: [PATCH, applied] dwarf-reader: Support indirectly referenced subrange_type DIEs Organization: Red Hat / France X-Operating-System: Fedora 38 X-URL: http://www.redhat.com Date: Fri, 07 Apr 2023 20:12:33 +0200 Message-ID: <87355blfxq.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org 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: Dodji Seketeli via Libabigail From: Dodji Seketeli Reply-To: Dodji Seketeli Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libabigail" Hello, This is about supporting an Ada-induced DWARF construct related to ranged types. To reproduce the issue this patch originated from, you can type: $ fedabipkgdiff --self-compare -a --from fc37 gprbuild From that gprbuild package from fc37, consider this subrange_type DIE coming from the debuginfo file prtests/gprbuild-2020-11.fc37.aarch64: 1 [ 3c10d] subrange_type abbrev: 34 2 type (ref_addr) [ 6191e] 3 lower_bound (sdata) 2 4 upper_bound (ref_udata) [ 3c0eb] At line 4, look at how the DW_AT_upper_bound attribute is a reference to another DIE, instead of being a (signed) constant value, like the DW_AT_lower_bound attribute at line 3. The referenced DIE is at offset 0x3c0eb. How do we get the actual value of the upper_bound of that subrange type? To answer that question, let's look at the DIE, at offset 0x3c0eb that is referenced by the DW_AT_upper_bound attribute at line 4: 1 [ 3c0eb] member abbrev: 87 2 name (strp) "last" 3 decl_file (data1) a-coinve.ads (35) 4 decl_line (data2) 415 5 decl_column (data1) 24 6 type (ref_udata) [ 3c0f7] It's a data member which type is referenced at line 6. Let's look at that type, which offset is 0x3c0f7: 1 [ 3c0f7] subrange_type abbrev: 122 2 upper_bound (sdata) 99999999 3 name (strp) "gpr__names__name_vectors__T449bXn" 4 type (ref_addr) [ 6191e] 5 artificial (flag_present) yes That type is a DW_TAG_subrange_type and its DW_AT_upper_bound value is a constant. Finally. Actually, the value of DW_AT_upper_bound of this DIE at offset 0x3c0f7 is the value of the DW_AT_upper_bound of the subrange_type DIE at offset 0x3c10d that we were initially looking for. The DIE at 0x3c0f7 is said to be indirectly referenced by the DIE at 0x3c10d, through its DW_AT_upper_bound attribute. This patch supports retrieving the value of the DW_AT_upper_bound of 0x3c10d through the 0x3c0f7 DIE that it indirectly references. The package gprbuild from fc37 now passes self comparison with this patch. * src/abg-dwarf-reader.cc (subrange_die_indirect_bound_value) (subrange_die_indirectly_references_subrange_die): Define new static function. (build_subrange_type): If the value of DW_AT_upper_bound is not a constant, try to consider it as an indirect reference to a DW_TAG_subrange_type DIE, whose DW_AT_upper_bound might carry the constant value that we are looking for. Signed-off-by: Dodji Seketeli --- src/abg-dwarf-reader.cc | 123 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index d5dfc48f..ef1d8a45 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -523,6 +523,16 @@ die_die_attribute(const Dwarf_Die* die, Dwarf_Die& result, bool recursively = true); +static bool +subrange_die_indirect_bound_value(const Dwarf_Die *die, + unsigned attr_name, + array_type_def::subrange_type::bound_value& v, + bool& is_signed); + +static bool +subrange_die_indirectly_references_subrange_die(const Dwarf_Die *die, + unsigned attr_name, + Dwarf_Die& referenced_subrange); static string get_internal_anonymous_die_prefix_name(const Dwarf_Die *die); @@ -6199,6 +6209,110 @@ die_die_attribute(const Dwarf_Die* die, return dwarf_formref_die(&attr, &result); } +/// Test if a subrange DIE indirectly references another subrange DIE +/// through a given attribute. +/// +/// A DW_TAG_subrange_type DIE can have its DW_AT_{lower,upper}_bound +/// attribute be a reference to either a data member or a variable +/// which type is itself a DW_TAG_subrange_type. This latter subrange +/// DIE is said to be "indirectly referenced" by the former subrange +/// DIE. In that case, the DW_AT_{lower,upper}_bound of the latter is +/// the value we want for the DW_AT_upper_bound of the former. +/// +/// This function tests if the former subrange DIE does indirectly +/// reference another subrange DIE through a given attribute (not +/// necessarily DW_AT_upper_bound). +/// +/// @param die the DIE to consider. Note that It must be a +/// DW_TAG_subrange_type. +/// +/// @param attr_name the name of the attribute to look through for the +/// indirectly referenced subrange DIE. +/// +/// @param referenced_subrange if the function returns true, then the +/// argument of this parameter is set to the indirectly referenced +/// DW_TAG_subrange_type DIE. +/// +/// @return true iff @p DIE indirectly references a subrange DIE +/// through the attribute @p attr_name. +static bool +subrange_die_indirectly_references_subrange_die(const Dwarf_Die *die, + unsigned attr_name, + Dwarf_Die& referenced_subrange) +{ + bool result = false; + + if (dwarf_tag(const_cast(die)) != DW_TAG_subrange_type) + return result; + + Dwarf_Die referenced_die; + if (die_die_attribute(die, attr_name, referenced_die)) + { + unsigned tag = dwarf_tag(&referenced_die); + if ( tag == DW_TAG_member || tag == DW_TAG_variable) + { + Dwarf_Die type_die; + if (die_die_attribute(&referenced_die, DW_AT_type, type_die)) + { + tag = dwarf_tag(&type_die); + if (tag == DW_TAG_subrange_type) + { + memcpy(&referenced_subrange, &type_die, sizeof(type_die)); + result = true; + } + } + } + } + return result; +} + +/// Return the bound value of subrange die by looking at an indirectly +/// referenced subrange DIE. +/// +/// A DW_TAG_subrange_type DIE can have its DW_AT_{lower,upper}_bound +/// attribute be a reference to either a data member or a variable +/// which type is itself a DW_TAG_subrange_type. This latter subrange +/// DIE is said to be "indirectly referenced" by the former subrange +/// DIE. In that case, the DW_AT_{lower,upper}_bound of the latter is +/// the value we want for the DW_AT_{lower,upper}_bound of the former. +/// +/// This function gets the DW_AT_{lower,upper}_bound value of a +/// subrange type by looking at the DW_AT_{lower,upper}_bound value of +/// the indirectly referenced subrange type, if it exists. +/// +/// @param die the subrange DIE to consider. +/// +/// @param attr_name the name of the attribute to consider, typically, +/// DW_AT_{lower,upper}_bound. +/// +/// @param v the found value, iff this function returned true. +/// +/// @param is_signed, this is set to true if @p v is signed. This +/// parameter is set at all only if the function returns true. +/// +/// @return true iff the DW_AT_{lower,upper}_bound was found on the +/// indirectly referenced subrange type. +static bool +subrange_die_indirect_bound_value(const Dwarf_Die *die, + unsigned attr_name, + array_type_def::subrange_type::bound_value& v, + bool& is_signed) +{ + bool result = false; + + if (dwarf_tag(const_cast(die)) != DW_TAG_subrange_type) + return result; + + Dwarf_Die subrange_die; + if (subrange_die_indirectly_references_subrange_die(die, attr_name, + subrange_die)) + { + if (die_constant_attribute(&subrange_die, attr_name, is_signed, v)) + result = true; + } + return result; +} + /// Read and return an addresss class attribute from a given DIE. /// /// @param die the DIE to consider. @@ -14162,8 +14276,15 @@ build_subrange_type(reader& rdr, // So let's look for DW_AT_lower_bound first. die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound); + bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound, + is_signed, upper_bound); + if (!found_upper_bound) + found_upper_bound = subrange_die_indirect_bound_value(die, + DW_AT_upper_bound, + upper_bound, + is_signed); // Then, DW_AT_upper_bound. - if (!die_constant_attribute(die, DW_AT_upper_bound, is_signed, upper_bound)) + if (!found_upper_bound) { // The DWARF 4 spec says, in [5.11 Subrange Type // Entries]: