From patchwork Fri Mar 1 17:25:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 86664 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 0557B3858C32 for ; Fri, 1 Mar 2024 17:25:28 +0000 (GMT) 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 382913858C5F for ; Fri, 1 Mar 2024 17:25:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 382913858C5F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 382913858C5F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709313924; cv=none; b=RDa5+X7VPtIn/zRC4t0NJ3YOgGUHIfdjLL+hzymXx9gs3lUN2U23upVlLsGNsl2vEuQiBweNK57dT+gjO3DV+kFW9s8IbIDpwBSW0GkKdvTAciStAwZ367VRCiwq9yzoyiXM20Fk28Fhx2KPUED3rlNBU+zI9vPw/VI9NH0PJsw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709313924; c=relaxed/simple; bh=UFed3pU1z4uvrpk8XaUCUSivsqbLsDxuRf34WbUhBjg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=l70KvcyAjARPcQDhQhLfOztQiJkXZKSCdRsk2NADDoOIwP6LlYXpI5IqcjFuJKK0w3meyvDgG29Pwf49HDkA29aU4aKdRsLlkvYdqVUSHYSgIb7w9MwhpXxw1d9rWdu4ksR9ioXHk+Bt/kPwo/Q0E2TU1jnvZ9RRLPVUmx0KAuo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709313921; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=ZMpAxxnOapR0gA8QIjyRvrpB4HXEEz0rOtd3phjHpbk=; b=HeOB9xTZBOoQV72Pdcd7irkf8pSM7lGNV3nSLCn8OaNVOnrtBb2d4Yr86CB9Ci2eP0IupW s/rmiq9euN8CGvVA67Sewui+eQ6ssReVGrKMAeb0ZpgK7pFKChLaaqtCtRRzcvNktEMM0T owZapqhh1cj56E0cYvRcRYyT7gLG0GY= Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-690-Q8wqvEM-Nny9PwCU6LuYsw-1; Fri, 01 Mar 2024 12:25:20 -0500 X-MC-Unique: Q8wqvEM-Nny9PwCU6LuYsw-1 Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-42e93b1a1d0so27510071cf.0 for ; Fri, 01 Mar 2024 09:25:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709313920; x=1709918720; h=mime-version:user-agent:message-id:date:organization:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ZMpAxxnOapR0gA8QIjyRvrpB4HXEEz0rOtd3phjHpbk=; b=MwTc9sy4RAraMJ2/Dk03VycoltoWiFFeVCcZYw2lJKsXCNONyFnkGN+XlEso3UI5Ra ZtfAJeJIKpk5BpopobgBTR/UiCY4magGt9PzNXt3qJJOOLV7sZx/yddoT++70YEp54zR EpowPiR5Aw0rzaP3KGf7peBDXIv8I3sJO0Ktf8VOmpqCtISd1t0n22D2047ArJKUbvUX iIRVjP6OohLUhWliAKJ2BYByMVAEGG3zNzizOjNGJg+TLykF4YSrZwaEXEd7JAGxsPdR DCnYkE+EGcvthCpPEd75ooh3UjucLGQVOOeb+UtC5x9cP0q8FCwlW2RaFbgk/Okrg0H3 t7Dw== X-Gm-Message-State: AOJu0YwMHllN+qNckRkiX6hiBik0F67T8Ltc6ufihu5DdqJglbJf09ZN zlja/8JfKAPfUBotFlQzZ8bSl/f1dyvgXEkBKq2mHDhu7b2LRk1JL3uZD77gPTGt5C32OlvwkY2 hxvCfwMVz3uBnj5+KZNIRF2nVi3NXyITCm4+I+XocPBI5+xQrxA81nob+7SONFff81Q== X-Received: by 2002:a05:622a:c8:b0:42e:cd4a:b6a8 with SMTP id p8-20020a05622a00c800b0042ecd4ab6a8mr1903824qtw.51.1709313919859; Fri, 01 Mar 2024 09:25:19 -0800 (PST) X-Google-Smtp-Source: AGHT+IFLw2QWyff08gdOIzU1HQ719NLapUmwNk9cB8xCbFy+jGAlNEuEzacax5QviipfPuiG32so+w== X-Received: by 2002:a05:622a:c8:b0:42e:cd4a:b6a8 with SMTP id p8-20020a05622a00c800b0042ecd4ab6a8mr1903808qtw.51.1709313919483; Fri, 01 Mar 2024 09:25:19 -0800 (PST) Received: from localhost (88-120-130-27.subs.proxad.net. [88.120.130.27]) by smtp.gmail.com with ESMTPSA id o27-20020a05620a22db00b00787b7b9ccffsm1828039qki.24.2024.03.01.09.25.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 09:25:19 -0800 (PST) Received: by localhost (Postfix, from userid 1000) id B07E85071022; Fri, 1 Mar 2024 18:25:17 +0100 (CET) From: Dodji Seketeli To: libabigail@sourceware.org Cc: dodji@redhat.com Subject: [PATCH] dwarf-reader, ir: Add member fns to exported corpus fns after c14n Organization: Red Hat / France X-Operating-System: AlmaLinux 9.3 X-URL: http://www.redhat.com Date: Fri, 01 Mar 2024 18:25:17 +0100 Message-ID: <87edct7tky.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 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_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Hello, There are cases where a member function C::f has a defined & exported ELF symbol in a translation unit TU-2, whereas it has no associated symbol in another translation unit TU-1. The class C from TU-1 and the class C from TU-2 have the same canonical type because they are equivalent. Now, suppose it's C from TU-2 that is the canonical type; that means the canonical type of C from TU-1 is C from TU-2. Today, the only types that are emitted in an ABIXML file are canonical types. So if we want the C::f which has a publicly defined & exported elf symbol to be emitted in the ABIXML file, then the C::f that is defined & exported in the ABI corpus should be the C::f from the canonical class type C i.e, the C::f from TU-2. In other words, the exported C::f should be the member function of the canonical type class C. That means that determining which C::f to export in the ABI corpus should be done *after* type canonicalization. Today however, determining which C::f to export is done during the construction of the IR, in the DWARF reader. That leads to cases where the exported C::f is the one that has no defined & exported ELF symbol. As virtual member functions (in particular) are involved in class type comparison, that could lead to spurious type changes left and right. Oops. This patch implements the export of member functions after type canonicalization in the DWARF reader. Note that CTF and BTF readers are not impacted as they only support the C language which doesn't have member functions. * src/abg-dwarf-reader.cc (reader::fixup_functions_with_no_symbols): Do not export the virtual member function here. (build_ir_node_from_die): For DW_TAG_subprogram DIEs, likewise. * src/abg-ir.cc (maybe_adjust_canonical_type): Walk the member functions of the canonical type and export them in the ABI corpus if they have a defined and exported elf symbol. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. Signed-off-by: Dodji Seketeli Applying to the master branch --- src/abg-dwarf-reader.cc | 15 ++++--- src/abg-ir.cc | 44 +++++++++++++++---- .../test9-pr18818-clang.so.abi | 2 +- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 6d64c0c7..46f08a9e 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -4552,12 +4552,7 @@ public: ABG_ASSERT(is_member_function(i->second)); ABG_ASSERT(get_member_function_is_virtual(i->second)); i->second->set_symbol(sym); - // The function_decl now has an associated (public) ELF symbol so - // it ought to be advertised as being public. - i->second->set_is_in_public_symbol_table(true); - // Add the function to the set of exported decls of the - // current corpus. - maybe_add_fn_to_exported_decls(i->second.get()); + if (do_log()) cerr << "fixed up '" << i->second->get_pretty_representation() @@ -16016,7 +16011,13 @@ build_ir_node_from_die(reader& rdr, if (fn) { - rdr.maybe_add_fn_to_exported_decls(fn.get()); + if (!is_member_function(fn) + || !get_member_function_is_virtual(fn)) + // Virtual member functions are added to the set of + // functions exported by the current ABI corpus *after* + // the canonicalization of their parent type. So let's + // not do it here. + rdr.maybe_add_fn_to_exported_decls(fn.get()); rdr.associate_die_to_decl(die, fn, where_offset, /*associate_by_repr=*/false); maybe_canonicalize_type(fn->get_type(), rdr); diff --git a/src/abg-ir.cc b/src/abg-ir.cc index d3fbafb4..d0d92055 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -15649,18 +15649,15 @@ static void maybe_adjust_canonical_type(const type_base_sptr& canonical, const type_base_sptr& type) { - if (!canonical - // If 'type' is *NOT* a newly canonicalized type ... - || type->get_naked_canonical_type() - // ... or if 'type' is it's own canonical type, then get out. - || type.get() == canonical.get()) + if (type->get_naked_canonical_type()) return; + class_decl_sptr canonical_class = is_class_type(canonical); + if (class_decl_sptr cl = is_class_type(type)) { - class_decl_sptr canonical_class = is_class_type(canonical); - - if (canonical_class) + if (canonical_class + && canonical_class.get() != cl.get()) { // Set symbols of member functions that might be missing // theirs. @@ -15695,6 +15692,37 @@ maybe_adjust_canonical_type(const type_base_sptr& canonical, } } + // Make sure the virtual member functions with exported symbols are + // all added to the set of exported functions of the corpus. + + // If we are looking at a non-canonicalized class (for instance, a + // decl-only class that has virtual member functoins), let's pretend + // it does have a canonical class so that we can perform the + // necessary virtual member function adjustments + if (class_decl_sptr cl = is_class_type(type)) + if (is_non_canonicalized_type(cl)) + { + ABG_ASSERT(!canonical_class); + canonical_class = cl; + } + + if (canonical_class) + { + if (auto abi_corpus = canonical_class->get_corpus()) + { + for (auto& fn : canonical_class->get_member_functions()) + { + if (elf_symbol_sptr sym = fn->get_symbol()) + if (sym->is_defined() && sym->is_public()) + { + fn->set_is_in_public_symbol_table(true); + auto b = abi_corpus->get_exported_decls_builder(); + b->maybe_add_fn_to_exported_fns(fn.get()); + } + } + } + } + // If an artificial function type equals a non-artfificial one in // the system, then the canonical type of both should be deemed // non-artificial. This is important because only non-artificial diff --git a/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi b/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi index a7ee1ef3..8c598216 100644 --- a/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi +++ b/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi @@ -4810,7 +4810,7 @@ - +