From patchwork Thu Mar 29 14:00:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 892797 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-475611-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yDTAc4+D"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40Bmcj2DgPz9s1R for ; Fri, 30 Mar 2018 01:01:08 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=FYAbg2migDSa2cRVSmPLAl5i715X81zlzUX1KQcdJwX0SiT+fU 1LzE8eubCXkFc70igmV7gB+6AxlJBqMBrlr5mbm26kloJkfIDiafetDvrJaHr52U teGxWFQXnrNzjEjFY3FXfLwAZGDVqGfybPk5NQwIFCyO+d04i0vmcoIGU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=0w7fjjbHgCxepfGjsAYCu+CBqPg=; b=yDTAc4+Dq0/hpU8guyVB wCtsaCxfHvGsSdst6gnfImD2LH+BgBoMcOzxtY0ODh0+C3RKcIZ2AsGIQzCZSH9P pVgy9kW6YxYslhPwN97lV6O4qrixPhVATuPthoUk2vEPyyeSHB1bHhSbS5kR/m6u 434k2f6DNjgGZzuxVM+U7Eo= Received: (qmail 37932 invoked by alias); 29 Mar 2018 14:01:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 32749 invoked by uid 89); 29 Mar 2018 14:00:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=20180309 X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 29 Mar 2018 14:00:51 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 93495818595A for ; Thu, 29 Mar 2018 14:00:49 +0000 (UTC) Received: from oldenburg.str.redhat.com (dhcp-192-212.str.redhat.com [10.33.192.212]) by smtp.corp.redhat.com (Postfix) with ESMTP id 32417215CDC5 for ; Thu, 29 Mar 2018 14:00:49 +0000 (UTC) To: GCC Patches From: Florian Weimer Subject: [PATCH] PR libgcc/60790: Avoid IFUNC resolver access to uninitialized data Message-ID: <8d5057e2-b0c5-342b-e0f7-9a54b7fdc061@redhat.com> Date: Thu, 29 Mar 2018 16:00:48 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch performs lazy initialization of the relevant CPUID feature register value. It will needlessly invoke the CPUID determination code on architectures which lack CPUID support or support for the feature register, but I think it's not worth to avoid the complexity for that. I verified manually that the CMPXCHG16B implementation is still selected for a 128-bit load after the change. I don't know how to write an automated test for that. Thanks, Florian Index: libatomic/ChangeLog =================================================================== --- libatomic/ChangeLog (revision 258952) +++ libatomic/ChangeLog (working copy) @@ -1,3 +1,18 @@ +2018-03-29 Florian Weimer + + PR libgcc/60790 + x86: Do not assume ELF constructors run before IFUNC resolvers. + * config/x86/host-config.h (libat_feat1_ecx, libat_feat1_edx): + Remove declarations. + (__libat_feat1, __libat_feat1_init): Declare. + (FEAT1_REGISTER): Define. + (load_feat1): New function. + (IFUNC_COND_1): Adjust. + * config/x86/init.c (libat_feat1_ecx, libat_feat1_edx) + (init_cpuid): Remove definitions. + (__libat_feat1): New variable. + (__libat_feat1_init): New function. + 2018-03-09 Andreas Krebbel * config/s390/exch_n.c: New file. Index: libatomic/config/x86/host-config.h =================================================================== --- libatomic/config/x86/host-config.h (revision 258952) +++ libatomic/config/x86/host-config.h (working copy) @@ -25,13 +25,39 @@ #if HAVE_IFUNC #include -extern unsigned int libat_feat1_ecx HIDDEN; -extern unsigned int libat_feat1_edx HIDDEN; +#ifdef __x86_64__ +# define FEAT1_REGISTER ecx +#else +# define FEAT1_REGISTER edx +#endif +/* Value of the CPUID feature FEAT1_REGISTER for the cmpxchg bit for + IFUNC_COND1 below. */ +extern unsigned int __libat_feat1 HIDDEN; + +/* Initialize libat_feat1 and return its value. */ +unsigned int __libat_feat1_init (void) HIDDEN; + +/* Return the value of the relevant feature register for the relevant + cmpxchg bit, or 0 if there is no CPUID support. */ +static inline unsigned int +__attribute__ ((const)) +load_feat1 (void) +{ + /* Synchronizes with the store in __libat_feat1_init. */ + unsigned int feat1 = __atomic_load_n (&__libat_feat1, __ATOMIC_RELAXED); + if (feat1 == 0) + /* Assume that initialization has not happened yet. This may get + called repeatedly if the CPU does not have any feature bits at + all. */ + feat1 = __libat_feat1_init (); + return feat1; +} + #ifdef __x86_64__ -# define IFUNC_COND_1 (libat_feat1_ecx & bit_CMPXCHG16B) +# define IFUNC_COND_1 (load_feat1 () & bit_CMPXCHG16B) #else -# define IFUNC_COND_1 (libat_feat1_edx & bit_CMPXCHG8B) +# define IFUNC_COND_1 (load_feat1 () & bit_CMPXCHG8B) #endif #ifdef __x86_64__ Index: libatomic/config/x86/init.c =================================================================== --- libatomic/config/x86/init.c (revision 258952) +++ libatomic/config/x86/init.c (working copy) @@ -26,13 +26,17 @@ #if HAVE_IFUNC -unsigned int libat_feat1_ecx, libat_feat1_edx; +unsigned int __libat_feat1; -static void __attribute__((constructor)) -init_cpuid (void) +unsigned int +__libat_feat1_init (void) { - unsigned int eax, ebx; - __get_cpuid (1, &eax, &ebx, &libat_feat1_ecx, &libat_feat1_edx); + unsigned int eax, ebx, ecx, edx; + FEAT1_REGISTER = 0; + __get_cpuid (1, &eax, &ebx, &ecx, &edx); + /* Synchronizes with the load in load_feat1. */ + __atomic_store_n (&__libat_feat1, FEAT1_REGISTER, __ATOMIC_RELAXED); + return FEAT1_REGISTER; } #endif /* HAVE_IFUNC */