From patchwork Mon Nov 30 06:05:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 41232 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 B4612385782B; Mon, 30 Nov 2020 06:05:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B4612385782B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1606716336; bh=g5pHB4lZL5SqfOLk0WvmxoY4zNrydXuiHJaC5yiLybc=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=iFwHimriIp7cZdx21aS7skiuggoBrtNa+LrHwnRMLruiZWdd1KDOLqOHGVFouHv8f xza0uwRuyAnOmyPaAp4TKa7GjoiOLLBMmHChFgiZk4S1TVu9PK5Cfe7yoS9DQ4L5Os 8HLqeRCpe0tI/efbCqlG4EYWAi5I8aLovvX3NQRU= 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 [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 00F7F3857804 for ; Mon, 30 Nov 2020 06:05:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 00F7F3857804 Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-170-cXgk1TQCM2WMwWi4irPE4Q-1; Mon, 30 Nov 2020 01:05:30 -0500 X-MC-Unique: cXgk1TQCM2WMwWi4irPE4Q-1 Received: by mail-wr1-f69.google.com with SMTP id b1so5678197wrc.14 for ; Sun, 29 Nov 2020 22:05:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:organization:date:message-id :user-agent:mime-version; bh=g5pHB4lZL5SqfOLk0WvmxoY4zNrydXuiHJaC5yiLybc=; b=TrL7puqKvOuSnM8/QLhhl8JJXkywFkzZ1PqVQcfo3CHM9R6FNlTo3msc27drCMNZmM Z7GZ4sUc9UerkvICrxxGMzp+zZ+3Faqyfw91f96qv7H54NEy6UpuPbUH1/ssraftnI1r wnJlI+wGHbZoVEHHIEKCiQZIGvxw9+a706p/dyM4KAqX638hroFbELpChveLZyHifUzj uU2gDNLd/blOd+cspq4BBm+uIG9MT5cpLb1kJJB6f+op+btNlT2MbxvSOAmuaJeZTGkF P6ASvwdbxTWStPBrWb5ucmGHwHJE2IfiFgnWopcZLuA/px6SlIi0vCFEzZCXM+L4elx/ 94xw== X-Gm-Message-State: AOAM532s8JIpbo77V8H96KkCX7s6sKQEe82ho9v2QMtD9Wb8dOm81z+f 3MwK0QDY2XohMD7al5UeaOk9+8DBy+JGwfadI3CvoRXBs/yiJUpNzegDrob0YWb6XxCSbWwNeWH /Lb0+FPYClwFnSeDOvNKUhACC6wwzhX22fp99gRIZqe9U+RjDNneZ/ynrdspqljQQ0zQX X-Received: by 2002:a7b:cb41:: with SMTP id v1mr9719694wmj.36.1606716328826; Sun, 29 Nov 2020 22:05:28 -0800 (PST) X-Google-Smtp-Source: ABdhPJz38pnJqjDkVb9sU/Wkl8g0EMtFETt26WH/F245e58kih77jTWSycta4XapIrX32sBxB9IG1Q== X-Received: by 2002:a7b:cb41:: with SMTP id v1mr9719663wmj.36.1606716328402; Sun, 29 Nov 2020 22:05:28 -0800 (PST) Received: from localhost ([2a01:e0a:1a0:d060:5246:5dff:feab:d19c]) by smtp.gmail.com with ESMTPSA id f17sm21878221wmh.10.2020.11.29.22.05.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Nov 2020 22:05:27 -0800 (PST) Received: by localhost (Postfix, from userid 1000) id 76D57581C18; Mon, 30 Nov 2020 07:05:26 +0100 (CET) To: libabigail@sourceware.org Subject: [PATCH] dwarf-reader: Bug 26908 - don't crash on empty DW_TAG_partial_unit Organization: Red Hat / France X-Operating-System: Fedora 34 X-URL: http://www.redhat.com Date: Mon, 30 Nov 2020 07:05:26 +0100 Message-ID: <87mtyz5qhl.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=-12.0 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_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP 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: Dodji Seketeli via Libabigail From: Dodji Seketeli Reply-To: Dodji Seketeli Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" Hello, Sometimes a DW_TAG_partial_unit (imported via a DW_TAG_imported_unit) has no children node. That means the the DW_TAG_partial_unit has no sub-tree. In those cases, the dwarf-reader crashes when ctxt.build_die_parent_relations_under tries to record the point at which the sub-tree (which is non-existent here) of the partial unit is imported by the DW_TAG_imported_unit DIE. This patch avoids crashing in those cases. As this problem is reported on libclang-cpp.so (on Fedora 33) which takes "abidw --abidiff" five hours and ~ 20GB of ram to complete at this point (on a power7 box) this patch doesn't have a regression test attached. * src/abg-dwarf-reader.cc (die_has_children): Define new static function. (read_context::build_die_parent_relations_under): Do not try to instantiate an imported_unit_point type for an imported unit with no children node. (imported_unit_point::imported_unit_point): Assert that the imported die has a sub-tree. (imported_unit_point::imported_unit_point): Remove useless spaces. Signed-off-by: Dodji Seketeli Apply to master. --- src/abg-dwarf-reader.cc | 49 ++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index fd1372a3..61845a63 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -220,7 +220,7 @@ struct imported_unit_point Dwarf_Off imported_unit_child_off; /// Default constructor for @ref the type imported_unit_point. - imported_unit_point () + imported_unit_point() : offset_of_import(), imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE), imported_unit_die_off(), @@ -232,7 +232,7 @@ struct imported_unit_point /// /// @param import_off the offset of the point at which the unit has /// been imported. - imported_unit_point (Dwarf_Off import_off) + imported_unit_point(Dwarf_Off import_off) : offset_of_import(import_off), imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE), imported_unit_die_off(), @@ -248,9 +248,9 @@ struct imported_unit_point /// @param from where the imported DIE comes from. /// /// @param imported_die the die of the unit that has been imported. - imported_unit_point (Dwarf_Off import_off, - const Dwarf_Die& imported_die, - die_source from) + imported_unit_point(Dwarf_Off import_off, + const Dwarf_Die& imported_die, + die_source from) : offset_of_import(import_off), imported_unit_die_source(from), imported_unit_die_off(dwarf_dieoffset @@ -260,8 +260,9 @@ struct imported_unit_point { Dwarf_Die imported_unit_child; - dwarf_child(const_cast(&imported_die), - &imported_unit_child); + ABG_ASSERT(dwarf_child(const_cast(&imported_die), + &imported_unit_child) == 0); + imported_unit_child_off = dwarf_dieoffset(const_cast(&imported_unit_child)); @@ -355,6 +356,9 @@ static bool die_has_object_pointer(const Dwarf_Die* die, Dwarf_Die& object_pointer); +static bool +die_has_children(const Dwarf_Die* die); + static bool die_this_pointer_from_object_pointer(Dwarf_Die* die, Dwarf_Die& this_pointer); @@ -7710,7 +7714,18 @@ public: if (dwarf_tag(&child) == DW_TAG_imported_unit) { Dwarf_Die imported_unit; - if (die_die_attribute(&child, DW_AT_import, imported_unit)) + if (die_die_attribute(&child, DW_AT_import, imported_unit) + // If the imported_unit has a sub-tree, let's record + // this point at which the sub-tree is imported into + // the current debug info. + // + // Otherwise, if the imported_unit has no sub-tree, + // there is no point in recording where a non-existent + // sub-tree is being imported. + // + // Note that the imported_unit_points_type type below + // expects the imported_unit to have a sub-tree. + && die_has_children(&imported_unit)) { die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE; ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source)); @@ -8906,6 +8921,24 @@ die_has_object_pointer(const Dwarf_Die* die, Dwarf_Die& object_pointer) return false; } +/// Test if a DIE has children DIEs. +/// +/// @param die the DIE to consider. +/// +/// @return true iff @p DIE has at least one child node. +static bool +die_has_children(const Dwarf_Die* die) +{ + if (!die) + return false; + + Dwarf_Die child; + if (dwarf_child(const_cast(die), &child) == 0) + return true; + + return false; +} + /// When given the object pointer DIE of a function type or member /// function DIE, this function returns the "this" pointer that points /// to the associated class.