From patchwork Mon Nov 15 16:38:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 47685 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 40C953858031 for ; Mon, 15 Nov 2021 16:38:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 40C953858031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1636994334; bh=la2MOAtXdvpPzzojmXSdjdnV9j3uBG8kTRtfS4VJJtA=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Help: List-Subscribe:From:Reply-To:From; b=YlShL1CW0gMPdJOBmXHsxdr+yCwPLT67RQ6Rx+A9NlykBJqD1GDPZWwtLB7xJ8Z/1 67/30NMeqWzLe4yklNpYUlsLy5CVcqguhoeybOdO7UuzajmVCN9CfZK5ZGuOJbVnPI cZCXZ5d1kW3uw25kcqbw9xDyhwKpPvm4vcIQWbH0= 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 260DB3858416 for ; Mon, 15 Nov 2021 16:38:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 260DB3858416 Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-247-Qfu2w124OdC5w_h4XGThnA-1; Mon, 15 Nov 2021 11:38:09 -0500 X-MC-Unique: Qfu2w124OdC5w_h4XGThnA-1 Received: by mail-qk1-f199.google.com with SMTP id k18-20020a05620a07f200b00467e6cd54a2so10400726qkk.22 for ; Mon, 15 Nov 2021 08:38:09 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:organization:date:message-id :user-agent:mime-version; bh=la2MOAtXdvpPzzojmXSdjdnV9j3uBG8kTRtfS4VJJtA=; b=7ixcXaJxW8f+itLs0Vxl2C3iFGMPf0mYLx6PHcTt9iWLs90gEhidZmsT4lr1RPEGWY /UiW1K5ZTtEZSEsz0jbQaR59NaWow1zrDgPWZcIOJD7PMPUSkCqoxxvz8j3hu0LdbYpl c9orNSCYXTIfGAM9t5TltDpqR7CEb+gtpvqxDwaGnGqpxopIUmXBzZmpoDnXo2P7rW3/ D8R7rnwScChcVHTBDOc3mraf4PQsl7gD+BOZRqp4oROLSPmZDn1/sMuQOVeoungL2dlw Utcf7B2sxspx5IIPir5dr2ke/WjaXdPJ5JfjZwsKMpiEWJGY5vC/qrpD4rV0WiEWRoq/ vTvg== X-Gm-Message-State: AOAM531L6FolrryTvfNkfjL7Yi75m6EjHs/qHh1aT0iFaVEVRwh4vpm+ PCMv6AqpzMt8atnsQf9zY2HxqJZLV9u2z9Uu5eLR2jfmXVL0ufH6AEE3upDDHotITXHPXQ2K2Rj oTRTK+Vvre+uzKnkpRa5b/BVute9ymtJ9q5Pdw/znxle2qYgjDFMMNb+uFagV2v6Cs8ea X-Received: by 2002:a05:622a:189:: with SMTP id s9mr325589qtw.352.1636994288130; Mon, 15 Nov 2021 08:38:08 -0800 (PST) X-Google-Smtp-Source: ABdhPJwaOdX4s5F6AN7SeH7FWyCK/4zSzddu+kbZz7Z53Z+0d7m66v9+8PlWiJpKjzrsh0CCwUyDyA== X-Received: by 2002:a05:622a:189:: with SMTP id s9mr325472qtw.352.1636994287214; Mon, 15 Nov 2021 08:38:07 -0800 (PST) Received: from localhost ([88.120.130.27]) by smtp.gmail.com with ESMTPSA id d23sm6911949qkl.70.2021.11.15.08.38.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Nov 2021 08:38:06 -0800 (PST) Received: by localhost (Postfix, from userid 1000) id 7D381581C23; Mon, 15 Nov 2021 17:38:04 +0100 (CET) To: libabigail@sourceware.org Subject: [PATCH, applied] Bug 28584 - Don't drop global variables that lack DW_AT_external Organization: Red Hat / France X-Operating-System: Fedora 36 X-URL: http://www.redhat.com Date: Mon, 15 Nov 2021 17:38:04 +0100 Message-ID: <87y25p5q8j.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.5 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_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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, Clang doesn't always emit the DW_AT_external property that flags a decl as being external. In those cases, the DWARF reader just drops the variable on the floor as it considers it as being "non-exported". This patch considers that a variable decl that is at named namespace scope is essentially "external". Then if the variable has an ELF symbol associated to it, then an IR node will be created for it. The other changes are just needed adaptations due to the core change. * src/abg-dwarf-reader.cc (die_is_effectively_public_decl): Define new static function. (die_flag_attribute, die_is_public_decl): Adjust const-ness. (build_ir_node_from_die): When building an IR for a variable, consider the variable as being external if the variable is at namespace scope, even if its DIE doesn't have the DW_AT_external attribute. * tests/data/test-read-dwarf/PR28584/PR28584-smv.cc: New source code for a new clang-built binary. * tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o: New clang-built input binary for testing purposes. * tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi: The reference output abixml. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-read-dwarf.cc (in_out_specs): Add the new test input to this test harness. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Adjust. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. Signed-off-by: Dodji Seketeli Applied to master. --- src/abg-dwarf-reader.cc | 71 +++++++++-- tests/data/Makefile.am | 3 + .../test-read-dwarf/PR22122-libftdc.so.abi | 115 ++++++++++-------- .../test-read-dwarf/PR28584/PR28584-smv.cc | 4 + .../PR28584/PR28584-smv.clang.o | Bin 0 -> 1824 bytes .../PR28584/PR28584-smv.clang.o.abi | 15 +++ .../test-read-dwarf/test-libandroid.so.abi | 8 +- tests/test-read-dwarf.cc | 8 ++ 8 files changed, 158 insertions(+), 66 deletions(-) create mode 100644 tests/data/test-read-dwarf/PR28584/PR28584-smv.cc create mode 100644 tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o create mode 100644 tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 6c7c1dae..ec92f3f8 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -6445,15 +6445,15 @@ form_is_DW_FORM_line_strp(unsigned form) /// @return true if the DIE has a flag attribute named @p attr_name, /// false otherwise. static bool -die_flag_attribute(Dwarf_Die* die, +die_flag_attribute(const Dwarf_Die* die, unsigned attr_name, bool& flag, bool recursively = true) { Dwarf_Attribute attr; if (recursively - ? !dwarf_attr_integrate(die, attr_name, &attr) - : !dwarf_attr(die, attr_name, &attr)) + ? !dwarf_attr_integrate(const_cast(die), attr_name, &attr) + : !dwarf_attr(const_cast(die), attr_name, &attr)) return false; bool f = false; @@ -6697,13 +6697,56 @@ die_access_specifier(Dwarf_Die * die, access_specifier& access) /// @return true if a DW_AT_external attribute is present and its /// value is set to the true; return false otherwise. static bool -die_is_public_decl(Dwarf_Die* die) +die_is_public_decl(const Dwarf_Die* die) { bool is_public = false; die_flag_attribute(die, DW_AT_external, is_public); return is_public; } +/// Test if a DIE is effectively public. +/// +/// This is meant to return true when either the DIE is public or when +/// it's a variable DIE that is at (global) namespace level. +/// +/// @return true iff either the DIE is public or is a variable DIE +/// that is at (global) namespace level. +static bool +die_is_effectively_public_decl(const read_context& ctxt, + const Dwarf_Die* die) +{ + if (die_is_public_decl(die)) + return true; + + unsigned tag = dwarf_tag(const_cast(die)); + if (tag == DW_TAG_variable || tag == DW_TAG_member) + { + // The DIE is a variable. + Dwarf_Die parent_die; + size_t where_offset = 0; + if (!get_parent_die(ctxt, die, parent_die, where_offset)) + return false; + + tag = dwarf_tag(&parent_die); + if (tag == DW_TAG_compile_unit + || tag == DW_TAG_partial_unit + || tag == DW_TAG_type_unit) + // The DIE is at global scope. + return true; + + if (tag == DW_TAG_namespace) + { + string name = die_name(&parent_die); + if (name.empty()) + // The DIE at unnamed namespace scope, so it's not public. + return false; + // The DIE is at namespace scope. + return true; + } + } + return false; +} + /// Test whether a given DIE represents a declaration-only DIE. /// /// That is, if the DIE has the DW_AT_declaration flag set. @@ -15065,9 +15108,11 @@ build_ir_node_from_die(read_context& ctxt, || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin, spec_die, false))) { - scope_decl_sptr spec_scope = get_scope_for_die(ctxt, &spec_die, - called_from_public_decl, - where_offset); + scope_decl_sptr spec_scope = + get_scope_for_die(ctxt, &spec_die, + /*called_from_public_decl=*/ + die_is_effectively_public_decl(ctxt, die), + where_offset); if (spec_scope) { decl_base_sptr d = @@ -15377,8 +15422,18 @@ build_ir_node_from_die(read_context& ctxt, true); } + // Normaly, a decl that is meant to be external has a DW_AT_external + // set. But then some compilers fail to always emit that flag. For + // instance, for static data members, some compilers won't emit the + // DW_AT_external. In that case, we assume that if the variable is + // at global or named namespace scope, then we can assume it's + // external. If the variable doesn't have any ELF symbol associated + // to it, it'll be dropped on the floor anyway. Those variable + // decls are considered as being "effectively public". + bool consider_as_called_from_public_decl = + called_from_public_decl || die_is_effectively_public_decl(ctxt, die); scope_decl_sptr scope = get_scope_for_die(ctxt, die, - called_from_public_decl, + consider_as_called_from_public_decl, where_offset); return build_ir_node_from_die(ctxt, die, scope.get(), called_from_public_decl, diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index bc2577da..b83f05be 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -580,6 +580,9 @@ test-read-dwarf/PR27700/test-PR27700.c \ test-read-dwarf/PR27700/test-PR27700.o \ test-read-dwarf/test-libaaudio.so \ test-read-dwarf/test-libaaudio.so.abi \ +test-read-dwarf/PR28584/PR28584-smv.cc \ +test-read-dwarf/PR28584/PR28584-smv.clang.o \ +test-read-dwarf/PR28584/PR28584-smv.clang.o.abi \ \ test-annotate/test0.abi \ test-annotate/test1.abi \ diff --git a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi index 085ff0f9..16e867ef 100644 --- a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi +++ b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi @@ -7797,34 +7797,36 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + - + @@ -7839,13 +7841,13 @@ - + - + @@ -7859,7 +7861,7 @@ - + @@ -7877,7 +7879,7 @@ - + @@ -7885,7 +7887,7 @@ - + @@ -7909,7 +7911,7 @@ - + @@ -7930,7 +7932,7 @@ - + @@ -7938,7 +7940,7 @@ - + @@ -7950,21 +7952,21 @@ - + - + - + @@ -7972,7 +7974,11 @@ - + + + + + @@ -7981,12 +7987,13 @@ - + + - + @@ -8001,7 +8008,7 @@ - + @@ -8012,7 +8019,7 @@ - + @@ -8020,7 +8027,7 @@ - + @@ -8035,7 +8042,7 @@ - + @@ -8050,7 +8057,7 @@ - + @@ -8066,7 +8073,7 @@ - + @@ -8082,7 +8089,7 @@ - + @@ -8098,7 +8105,7 @@ - + @@ -8106,7 +8113,7 @@ - + @@ -8121,7 +8128,7 @@ - + @@ -8155,7 +8162,7 @@ - + @@ -8168,7 +8175,7 @@ - + @@ -8257,7 +8264,7 @@ - + @@ -8305,20 +8312,20 @@ - - + + - - + + - + @@ -8354,9 +8361,9 @@ - - + + @@ -8431,7 +8438,7 @@ - + @@ -8441,7 +8448,7 @@ - + @@ -8450,7 +8457,7 @@ - + @@ -8480,9 +8487,9 @@ - + - + diff --git a/tests/data/test-read-dwarf/PR28584/PR28584-smv.cc b/tests/data/test-read-dwarf/PR28584/PR28584-smv.cc new file mode 100644 index 00000000..ee43efbf --- /dev/null +++ b/tests/data/test-read-dwarf/PR28584/PR28584-smv.cc @@ -0,0 +1,4 @@ +namespace N { +struct S { static int D; }; +int S::D = 17; +} diff --git a/tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o b/tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o new file mode 100644 index 0000000000000000000000000000000000000000..c8a3e22383f983e9489b041d8350ecc178520857 GIT binary patch literal 1824 zcmbtUOK;Oa5FW=#DVPRA1hgPQky^y7c8w|o1+_V(6i|pN6(qzZ@?$Yp{Xn)8fjCgk zaDacq&*8!k;LM@SIJ1h`Rs@Na?V0bJ`PQS|+5NE9dsx#nkVAtFm>|gleAg#_r*u0o zhnX$(wU)NrY&Z1g>GKzx0JVFXjz(XD?RITGLAT!4?ihO0FxHLx20&vD^ycF>fz5>n z3ji}qNNgAe#$X5EdijIdvW_dIFF!SM^iBL6uM~ue1_d;&R@xr@nOhgXjFnN`NnWTjq$aQ}L^AbRFVo=G8FHTOF5 zYE6{-h!4s5k^`V~LVY?*K^*gAGrkVcUu7)K4|et?!B+lX+Ox=$uj&OST%Dp{XT6dJ ypX3jefJ(oZqQ5pp{{-WD?|_ciel=D0pXB5{qyC@HarHiu`QJG43ljv7TL0gY(TI}( literal 0 HcmV?d00001 diff --git a/tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi b/tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi new file mode 100644 index 00000000..b6ab4779 --- /dev/null +++ b/tests/data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-dwarf/test-libandroid.so.abi b/tests/data/test-read-dwarf/test-libandroid.so.abi index 66235756..815c82ce 100644 --- a/tests/data/test-read-dwarf/test-libandroid.so.abi +++ b/tests/data/test-read-dwarf/test-libandroid.so.abi @@ -19478,10 +19478,10 @@ - + - + @@ -19754,10 +19754,10 @@ - + - + diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc index 726786a1..585aca5e 100644 --- a/tests/test-read-dwarf.cc +++ b/tests/test-read-dwarf.cc @@ -496,6 +496,14 @@ InOutSpec in_out_specs[] = "data/test-read-dwarf/test-libaaudio.so.abi", "output/test-read-dwarf/test-libaaudio.so.abi", }, + { + "data/test-read-dwarf/PR28584/PR28584-smv.clang.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi", + "output/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi", + }, // This should be the last entry. {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} };