From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 106152 invoked by alias); 28 May 2019 17:27:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 106143 invoked by uid 89); 28 May 2019 17:27:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.6 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_NUMSUBJECT,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: EUR01-VE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr140074.outbound.protection.outlook.com (HELO EUR01-VE1-obe.outbound.protection.outlook.com) (40.107.14.74) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 28 May 2019 17:26:58 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yzuNT1um/FTus/sTE0hFqWLVLgtDtzBCTQeda7xbV3A=; b=CA3ej0zhgJabcl46uGmOe27RypUmfsHg0ukW5hcFA/YUPSUdLQtDWX8w7cr0UK3TlRAgXiTwhxg3Qq8ZJfWhVdHfD7FLq9m+yEhKme/vSGrhPp8JHpB3c5sdW6xIGLsirMqL78crmkV92HQ4DQ+ylFkNsqZ+rN7UrZ4oGy1pGIM= Received: from VI1PR0801MB2127.eurprd08.prod.outlook.com (10.168.62.22) by VI1PR0801MB1647.eurprd08.prod.outlook.com (10.168.66.142) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1922.15; Tue, 28 May 2019 17:26:54 +0000 Received: from VI1PR0801MB2127.eurprd08.prod.outlook.com ([fe80::fd18:cb50:3e52:9878]) by VI1PR0801MB2127.eurprd08.prod.outlook.com ([fe80::fd18:cb50:3e52:9878%7]) with mapi id 15.20.1922.021; Tue, 28 May 2019 17:26:54 +0000 From: Wilco Dijkstra To: GCC Patches CC: nd Subject: [PATCH v2] Fix PR64242 Date: Tue, 28 May 2019 17:33:00 -0000 Message-ID: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Wilco.Dijkstra@arm.com; x-ms-oob-tlc-oobclassifiers: OLM:6430; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Wilco.Dijkstra@arm.com X-SW-Source: 2019-05/txt/msg01848.txt.bz2 Improve the fix for PR64242. Various optimizations can change a memory ref= erence into a frame access. Given there are multiple virtual frame pointers which= may be replaced by multiple hard frame pointers, there are no checks for writes= to the various frame pointers. So updates to a frame pointer tends to generate in= correct code. Improve the previous fix to also add clobbers of several frame point= ers and add a scheduling barrier. This should work in most cases until GCC support= s a generic "don't optimize across this instruction" feature. Bootstrap OK. Testcase passes on AArch64 and x86-64. Inspected x86, Arm, Thumb-1 and Thumb-2 assembler which looks correct.=20 ChangeLog: 2018-12-07 Wilco Dijkstra gcc/ PR middle-end/64242 * builtins.c (expand_builtin_longjmp): Add frame clobbers and schedule blo= ck. (expand_builtin_nonlocal_goto): Likewise. testsuite/ PR middle-end/64242 * gcc.c-torture/execute/pr64242.c: Update test. -- diff --git a/gcc/builtins.c b/gcc/builtins.c index 3f32754c4d35fc34af7c53156d2a356f69a94a8f..3463ffb153914a58e5baa3896a2= 44842a28eef09 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1137,15 +1137,20 @@ expand_builtin_longjmp (rtx buf_addr, rtx value) emit_insn (targetm.gen_nonlocal_goto (value, lab, stack, fp)); else { - lab =3D copy_to_reg (lab); - emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); =20 + lab =3D copy_to_reg (lab); + /* Restore the frame pointer and stack pointer. We must use a temporary since the setjmp buffer may be a local. */ fp =3D copy_to_reg (fp); emit_stack_restore (SAVE_NONLOCAL, stack); + + /* Ensure the frame pointer move is not optimized. */ + emit_insn (gen_blockage ()); + emit_clobber (hard_frame_pointer_rtx); + emit_clobber (frame_pointer_rtx); emit_move_insn (hard_frame_pointer_rtx, fp); =20 emit_use (hard_frame_pointer_rtx); @@ -1284,15 +1289,20 @@ expand_builtin_nonlocal_goto (tree exp) emit_insn (targetm.gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)= ); else { - r_label =3D copy_to_reg (r_label); - emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); =20 + r_label =3D copy_to_reg (r_label); + /* Restore the frame pointer and stack pointer. We must use a temporary since the setjmp buffer may be a local. */ r_fp =3D copy_to_reg (r_fp); emit_stack_restore (SAVE_NONLOCAL, r_sp); + + /* Ensure the frame pointer move is not optimized. */ + emit_insn (gen_blockage ()); + emit_clobber (hard_frame_pointer_rtx); + emit_clobber (frame_pointer_rtx); emit_move_insn (hard_frame_pointer_rtx, r_fp); =20 /* USE of hard_frame_pointer_rtx added for consistency; diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64242.c b/gcc/testsuite/= gcc.c-torture/execute/pr64242.c index 46a7b23d28d71604d141281c21fb0b77849b1b0d..e6139ede3f34d587ac53d04e286= e5d75fd2ca76c 100644 --- a/gcc/testsuite/gcc.c-torture/execute/pr64242.c +++ b/gcc/testsuite/gcc.c-torture/execute/pr64242.c @@ -5,46 +5,31 @@ extern void abort (void); __attribute ((noinline)) void broken_longjmp (void *p) { - void *buf[5]; + void *buf[32]; __builtin_memcpy (buf, p, 5 * sizeof (void*)); /* Corrupts stack pointer... */ __builtin_longjmp (buf, 1); } =20 -__attribute ((noipa)) __UINTPTR_TYPE__ -foo (void *p) -{ - return (__UINTPTR_TYPE__) p; -} - -__attribute ((noipa)) void -bar (void *p) -{ - asm volatile ("" : : "r" (p)); -} - volatile int x =3D 0; -void *volatile p; -void *volatile q; +char *volatile p; +char *volatile q; =20 int main () { void *buf[5]; - struct __attribute__((aligned (32))) S { int a[4]; } s; - bar (&s); p =3D __builtin_alloca (x); + q =3D __builtin_alloca (x); if (!__builtin_setjmp (buf)) broken_longjmp (buf); =20 + /* Compute expected next alloca offset - some targets don't align proper= ly + and allocate too much. */ + p =3D q + (q - p); + /* Fails if stack pointer corrupted. */ - q =3D __builtin_alloca (x); - if (foo (p) < foo (q)) - { - if (foo (q) - foo (p) >=3D 1024) - abort (); - } - else if (foo (p) - foo (q) >=3D 1024) + if (p !=3D __builtin_alloca (x)) abort (); =20 return 0;