From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ua1-x933.google.com (mail-ua1-x933.google.com [IPv6:2607:f8b0:4864:20::933]) by sourceware.org (Postfix) with ESMTPS id 9C4FB3858D28 for ; Wed, 15 Dec 2021 18:56:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9C4FB3858D28 Received: by mail-ua1-x933.google.com with SMTP id o1so42740777uap.4 for ; Wed, 15 Dec 2021 10:56:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=X78xc7/q1URAT47T5WYAwauZYsIomsyvq2lWt4T2Bgk=; b=mzcjOV6rUvn/2A0/szqspxjH1d1lHbxqgWuhBo8AKIy/dkbwQpWloHHjnN48RbcGAB 8lbyMTxm7ODXH3NikxbT0s/Jgg0RqNC9mH1VVqZZshZjMBMoHyO6JVocxg4pGMxg6pAk aNIWPbuWV4fJRpS2BiiQEH3rl8ENCBTULBPhURBoK1l8wL/w4s07f8UxVINTi4A/3kb7 Ti7tDkdrlZWT1BQjRmBFOACCt2aV6czPXTNulqNdeOaS8Kfo97MZyGfKgDaLUJupCxF4 VAwua+RdUmFnjgN/Y1fwwLF/ZPVwVXfYlHZIojFY7x+usPq30Ew6LlCdqEIybxoNFvUa OqSQ== X-Gm-Message-State: AOAM533eG3Fcd44E9jyc5XNaIfo8ik+/ju6835qyZo/erRvlbhX8sK3d idwwm9UEwgDPIDAtfmu74QDwMqwHWXrgw9axerythcFlUgI= X-Google-Smtp-Source: ABdhPJwma88N5gZC4U+GvvhTgjvHVlXXTiYx672F+ousZk56sdUUBAcC1aWCoSbUq9zjhomelHkIlrVUxQAJyMMWriI= X-Received: by 2002:a67:cd19:: with SMTP id u25mr4058476vsl.70.1639594606906; Wed, 15 Dec 2021 10:56:46 -0800 (PST) MIME-Version: 1.0 References: <20211215160021.24200-1-mark@klomp.org> In-Reply-To: <20211215160021.24200-1-mark@klomp.org> From: Giuliano Procida Date: Wed, 15 Dec 2021 22:56:35 +0400 Message-ID: Subject: Re: [PATCH] dwarf-reader: Workaround libdw dwarf_location_expression bug To: "Mark J. Wielaard" Cc: Giuliano Procida via Libabigail X-Spam-Status: No, score=-27.7 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 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-List-Received-Date: Wed, 15 Dec 2021 18:56:50 -0000 Hi Mark. What's the relationship, if any, between this and the patch I posted on 24 Nov to address Clang DWARF 5 addresses? I would check, but I'm currently on holiday. :-) Regards, Giuliano On Wed, 15 Dec 2021, 20:21 Mark J. Wielaard, wrote: > From: Mark Wielaard > > elfutils libdw before 0.184 would not correctly handle a > DW_AT_data_member_location when encoded as a DW_FORM_implicit const > in dwarf_location_expression. > > Work around this by first trying to read a data_member_location as a > constant value and only try to get it as a DWARF expression if that > > * src/abg-dwarf-reader.cc (die_constant_data_member_location): > New function. > (die_member_offset): Use die_constant_data_member_location > before calling die_location_expr and eval_quickly. > > Signed-off-by: Mark Wielaard > --- > src/abg-dwarf-reader.cc | 72 +++++++++++++++++++++++++++++++++-------- > 1 file changed, 58 insertions(+), 14 deletions(-) > > > https://code.wildebeest.org/git/user/mjw/libabigail/commit/?h=data_member_location > > diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc > index ec92f3f8..3f716944 100644 > --- a/src/abg-dwarf-reader.cc > +++ b/src/abg-dwarf-reader.cc > @@ -8693,6 +8693,37 @@ read_and_convert_DW_at_bit_offset(const Dwarf_Die* > die, > return true; > } > > +/// Get the value of the DW_AT_data_member_location of the given DIE > +/// attribute as an constant. > +/// > +/// @param die the DIE to read the attribute from. > +/// > +/// @param offset the attribute as a constant value. This is set iff > +/// the function returns true. > +/// > +/// @return true if the attribute exists and has a constant value. In > +/// that case the offset is set to the value. > +static bool > +die_constant_data_member_location(const Dwarf_Die *die, > + int64_t& offset) > +{ > + if (!die) > + return false; > + > + Dwarf_Attribute attr; > + if (!dwarf_attr(const_cast(die), > + DW_AT_data_member_location, > + &attr)) > + return false; > + > + Dwarf_Word val; > + if (dwarf_formudata(&attr, &val) != 0) > + return false; > + > + offset = val; > + return true; > +} > + > /// Get the offset of a struct/class member as represented by the > /// value of the DW_AT_data_member_location attribute. > /// > @@ -8758,21 +8789,34 @@ die_member_offset(const read_context& ctxt, > return true; > } > > - // Otherwise, let's see if the DW_AT_data_member_location attribute and, > - // optionally, the DW_AT_bit_offset attributes are present. > - if (!die_location_expr(die, DW_AT_data_member_location, &expr, > &expr_len)) > - return false; > - > - // The DW_AT_data_member_location attribute is present. > - // Let's evaluate it and get its constant > - // sub-expression and return that one. > - if (!eval_quickly(expr, expr_len, offset)) > - { > - bool is_tls_address = false; > - if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, > - offset, is_tls_address, > - ctxt.dwarf_expr_eval_ctxt())) > + // First try to read DW_AT_data_member_location as a plain constant. > + // We do this because the generic method using die_location_expr > + // might hit a bug in elfutils libdw dwarf_location_expression only > + // fixed in elfutils 0.184+. The bug only triggers if the attribute > + // is expressed as a (DWARF 5) DW_FORM_implicit_constant. But we > + // handle all constants here because that is more consistent (and > + // slightly faster in the general case where the attribute isn't a > + // full DWARF expression). > + if (!die_constant_data_member_location(die, offset)) > + { > + // Otherwise, let's see if the DW_AT_data_member_location > + // attribute and, optionally, the DW_AT_bit_offset attributes > + // are present. > + if (!die_location_expr(die, DW_AT_data_member_location, > + &expr, &expr_len)) > return false; > + > + // The DW_AT_data_member_location attribute is present. Let's > + // evaluate it and get its constant sub-expression and return > + // that one. > + if (!eval_quickly(expr, expr_len, offset)) > + { > + bool is_tls_address = false; > + if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, > + offset, is_tls_address, > + > ctxt.dwarf_expr_eval_ctxt())) > + return false; > + } > } > offset *= 8; > > -- > 2.18.4 > >