From nobody Thu Apr 25 10:48:01 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1679064624; cv=none; d=zohomail.com; s=zohoarc; b=MFdcVfDQMpCGvcKzrKisKYDplSPV0SxKuw7Ek9Lj2h4K62yaYUFE3PvsTLurIiJn2Sxt/nJnInH5Fo8wI6FEdp0u91deTL5ViQjNi20wJDwddeE3+2gpiGz3k2r3gGa55OE2uvajZb765sypilvKuIH58WWkh3Nb/e21lbQy8Tk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1679064624; h=Content-Type:Content-Transfer-Encoding:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=5tfJGXJo8r5RMgEYX+TnoiFSY2a3kOcNfZjwwUP702U=; b=UQ38uDVYrDZETztMaGrjPsTXhUTZNB4J/bh0nv5R4LVrh7zadanx80WM7gH9LlRfT89o08x6JwMG05FP3PZcaUW5P7jdOn32jkPSUyDgxX4HIci/ail7/sKrVrPIqNfLMPqw5ThQVjBeBNApC2uJCbi6MxIjoikWlgU48kXk+ZM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1679064624443376.8928400602132; Fri, 17 Mar 2023 07:50:24 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-519-SCl8jIHOM0uTf4L1a4g0eA-1; Fri, 17 Mar 2023 10:50:20 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1FAC087A380; Fri, 17 Mar 2023 14:49:45 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0894DC15BAE; Fri, 17 Mar 2023 14:49:45 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id E30471946A45; Fri, 17 Mar 2023 14:49:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 2F25E1946587 for ; Thu, 16 Mar 2023 13:05:45 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id E21CA2166B26; Thu, 16 Mar 2023 13:05:44 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.33.36.69]) by smtp.corp.redhat.com (Postfix) with ESMTP id 613232166B29; Thu, 16 Mar 2023 13:05:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1679064623; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=5tfJGXJo8r5RMgEYX+TnoiFSY2a3kOcNfZjwwUP702U=; b=bFGRu4hkDD6AS+C49UkxANh0C5qEe1Xz+fpdQ5/8vKjgyv2dXK0I+tJ7Cp207eXzDfIrre t/BmLZ/GVSH5gpDKfNYTaKP5o1N2zYA1umrP1xmGcH6dlWuRUoJz8UOpaImy2Nro5YxRD2 DuhiB365XARobK8VxmZRdBVlblr+AOk= X-MC-Unique: SCl8jIHOM0uTf4L1a4g0eA-1 X-Original-To: libvir-list@listman.corp.redhat.com From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH] meson: stop CLang doing inter-procedural analysis Date: Thu, 16 Mar 2023 13:05:43 +0000 Message-Id: <20230316130543.493573-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1679064625720100002 The virNumaNodeIsAvailable function is stubbed out when building without libnuma, such that it just returns a constant value. When CLang is optimizing, it does inter-procedural analysis across function calls. When it sees that the call to virNumaNodeIsAvailable returns a fixed constant, it elides the conditional check for errors in the callers such as virNumaNodesetIsAvailable. This is a valid optimization as the C standard declares that there must only be one implementation of each function in a binary. This is normally the case, but ELF allows for function overrides when linking or at runtime with LD_PRELOAD, which is technically outside the mandated C language behaviour. So while CLang's optimization works fine at runtime, it breaks in our test suite which aims to mock the virNumaNodeIsAvailable function so that it has specific semantics regardless of whether libnuma is built or not. The return value check optimization though means our mock override won't have the right effect. The mock will be invoked, but its return value is not used. Potentially the same problem could be exhibited with GCC if certain combinations of optimizations are enabled, though thus far we've not seen it. To be robust on both CLang and GCC we need to make it more explicit that we want to be able to replace functions and thus optimization of calls must be limited. Currently we rely on 'noinline' which does succesfully prevent inlining of the function, but it cannot stop the eliding of checks based on the constant return value. Thus we need a bigger hammer. There are a couple of options to disable this optimization: * Annotate a symbol as 'weak'. This is tells the compiler that the symbol is intended to be overridable at linktime or runtime, and thus it will avoid doing inter-procedural analysis for optimizations. This was tried previously but have to be reverted as it had unintended consequences when linking .a files into our final .so, resulting in all the weak symbol impls being lost. See commit 407a281a8e2b6c5078ba1148535663ea64fd9314 * Annotate a symbol with 'noipa'. This tells the compiler to avoid inter-procedural analysis for calls to just this function. This wold be ideal match for our scenario, but unfortunately it is only implemented for GCC currently: https://reviews.llvm.org/D101011 * The '-fsemantic-interposition' argument tells the optimizer that any functions may be replaced with alternative implementations that have different semantics. It thus blocks any optimizations across function calls. This is quite a harsh block on the optimizer, but it appears to be the only one that is viable with CLang. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko Reviewed-by: Peter Krempa --- meson.build | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/meson.build b/meson.build index 319ed790f9..c35823a79a 100644 --- a/meson.build +++ b/meson.build @@ -404,6 +404,26 @@ cc_flags +=3D [ '-Wwrite-strings', ] =20 +if cc.get_id() =3D=3D 'clang' + # Stop CLang from doing inter-procedural analysis of calls + # between functions in the same compilation unit. Such an + # optimization has been know to break the test suite by + # making assumptions that a return value is a constant. + # This makes it impossible to mock certain functions with + # replacement definitions via LD_PRELOAD that have different + # semantics. + # + # This is a bit of a big hammer, but alternatives don't work: + # + # - 'weak' attribute - weak symbols get dropped from + # when the .a libs are combined into the .so + # see commit 407a281a8e2b6c5078ba1148535663ea64fd9314 + # + # - 'noipa' attribute - only available with GCC currently + # https://reviews.llvm.org/D101011 + cc_flags +=3D [ '-fsemantic-interposition' ] +endif + supported_cc_flags =3D [] if get_option('warning_level') =3D=3D '2' supported_cc_flags =3D cc.get_supported_arguments(cc_flags) --=20 2.39.2