From patchwork Fri Jan 13 17:05:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiong Wang X-Patchwork-Id: 91474 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp286583qgi; Fri, 13 Jan 2017 09:06:13 -0800 (PST) X-Received: by 10.99.48.68 with SMTP id w65mr25252907pgw.107.1484327173405; Fri, 13 Jan 2017 09:06:13 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id b9si13212893pga.202.2017.01.13.09.06.13 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Jan 2017 09:06:13 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-446113-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-446113-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-446113-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=GpRaOL7kBdNSdopf8 HzfvTtgzvBGHUUNn1E0KFap09rpKqyNnVSylKBMfEGdBGu/jlQ4stB8JuusY28wL +vWL3rP3QzbK5lU1vXZiuI/9jfxDtnio/NmrAoNt1kPFarQQ4yqV4rIB5/9ETgI4 91Znvfd9ygJLK4fNnJJbQxtK/M= 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 :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=iUx3MX40v3JXbv9V+ap2Ped sdbU=; b=uNSxg7aA8xYNkObPie0hnxg2+EMaFt4vUcx57luG97qutiZK/AMTj57 E4olzFW2ZIhLnaVHbL41aQr9B6Po/jQThHpk+fF1svvKKs4iK7BKQh1vue/dlRGw L4xd+SiRcImtSh0rcilAVfQtvNu8+d0d2bOAqVnO82F8OGFU5vR8= Received: (qmail 49341 invoked by alias); 13 Jan 2017 17:05:57 -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 49329 invoked by uid 89); 13 Jan 2017 17:05:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=trn, 575, 7, 5757, aarch64optsh X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 13 Jan 2017 17:05:46 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3FEF8154D; Fri, 13 Jan 2017 09:05:45 -0800 (PST) Received: from [10.2.206.198] (e104437-lin.cambridge.arm.com [10.2.206.198]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 80F1D3F242; Fri, 13 Jan 2017 09:05:44 -0800 (PST) Subject: Re: [1/5][AArch64] Return address protection on AArch64 To: James Greenhalgh References: <4cf21d03-0a88-c6fa-df37-59ec4edf1d89@foss.arm.com> <6f8e65e0-643d-d0b0-26ad-4a20c3daf421@foss.arm.com> <20170113160443.GB39391@arm.com> Cc: gcc-patches , "Richard Earnshaw (lists)" , nd@arm.com From: Jiong Wang Message-ID: <3f1218be-51b4-23d9-3748-e0f4d0bd5170@foss.arm.com> Date: Fri, 13 Jan 2017 17:05:43 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: <20170113160443.GB39391@arm.com> X-IsSubscribed: yes On 13/01/17 16:04, James Greenhalgh wrote: > On Fri, Jan 06, 2017 at 11:47:07AM +0000, Jiong Wang wrote: >> On 11/11/16 18:22, Jiong Wang wrote: >> gcc/ >> 2017-01-06 Jiong Wang >> >> * config/aarch64/aarch64-opts.h (aarch64_function_type): New enum. >> * config/aarch64/aarch64-protos.h >> (aarch64_return_address_signing_enabled): New declaration. >> * config/aarch64/aarch64.c (aarch64_return_address_signing_enabled): >> New function. >> (aarch64_expand_prologue): Sign return address before it's pushed onto >> stack. >> (aarch64_expand_epilogue): Authenticate return address fetched from >> stack. >> (aarch64_override_options): Sanity check for ILP32 and ISA level. >> (aarch64_attributes): New function attributes for "sign-return-address". >> * config/aarch64/aarch64.md (UNSPEC_AUTI1716, UNSPEC_AUTISP, >> UNSPEC_PACI1716, UNSPEC_PACISP, UNSPEC_XPACLRI): New unspecs. >> ("*do_return"): Generate combined instructions according to key index. >> ("sp", "> * config/aarch64/iterators.md (PAUTH_LR_SP, PAUTH_17_16): New integer >> iterators. >> (pauth_mnem_prefix, pauth_hint_num_a): New integer attributes. >> * config/aarch64/aarch64.opt (msign-return-address=): New. >> * doc/extend.texi (AArch64 Function Attributes): Documents >> "sign-return-address=". >> * doc/invoke.texi (AArch64 Options): Documents "-msign-return-address=". >> >> gcc/testsuite/ >> 2017-01-06 Jiong Wang >> >> * gcc.target/aarch64/return_address_sign_1.c: New testcase. >> * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase. > I have a few comments on this patch All fixed. New patch attached. gcc/ 2017-01-13 Jiong Wang * config/aarch64/aarch64-opts.h (aarch64_function_type): New enum. * config/aarch64/aarch64-protos.h (aarch64_return_address_signing_enabled): New declaration. * config/aarch64/aarch64.c (aarch64_return_address_signing_enabled): New function. (aarch64_expand_prologue): Sign return address before it's pushed onto stack. (aarch64_expand_epilogue): Authenticate return address fetched from stack. (aarch64_override_options): Sanity check for ILP32 and ISA level. (aarch64_attributes): New function attributes for "sign-return-address". * config/aarch64/aarch64.md (UNSPEC_AUTI1716, UNSPEC_AUTISP, UNSPEC_PACI1716, UNSPEC_PACISP, UNSPEC_XPACLRI): New unspecs. ("*do_return"): Generate combined instructions according to key index. ("sp", "calls_eh_return) + return "retaa"; + + return "ret"; + } [(set_attr "type" "branch")] ) @@ -5341,6 +5353,36 @@ [(set_attr "length" "0")] ) +;; Pointer authentication patterns are always provided. In architecture +;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs. +;; This lets the user write portable software which authenticates pointers +;; when run on something which implements ARMv8.3-A, and which runs +;; correctly, but does not authenticate pointers, where ARMv8.3-A is not +;; implemented. + +;; Signing/Authenticating R30 using SP as the salt. +(define_insn "sp" + [(set (reg:DI R30_REGNUM) + (unspec:DI [(reg:DI R30_REGNUM) (reg:DI SP_REGNUM)] PAUTH_LR_SP))] + "" + "hint\t // asp"; +) + +;; Signing/Authenticating X17 using X16 as the salt. +(define_insn "1716" + [(set (reg:DI R17_REGNUM) + (unspec:DI [(reg:DI R17_REGNUM) (reg:DI R16_REGNUM)] PAUTH_17_16))] + "" + "hint\t // a1716"; +) + +;; Stripping the signature in R30. +(define_insn "xpaclri" + [(set (reg:DI R30_REGNUM) (unspec:DI [(reg:DI R30_REGNUM)] UNSPEC_XPACLRI))] + "" + "hint\t7 // xpaclri" +) + ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; all of memory. This blocks insns from being moved across this point. diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index 56b920d..5436884 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -149,6 +149,23 @@ mpc-relative-literal-loads Target Report Save Var(pcrelative_literal_loads) Init(2) Save PC relative literal loads. +msign-return-address= +Target RejectNegative Report Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save +Select return address signing scope. + +Enum +Name(aarch64_ra_sign_scope_t) Type(enum aarch64_function_type) +Supported AArch64 return address signing scope (for use with -msign-return-address= option): + +EnumValue +Enum(aarch64_ra_sign_scope_t) String(none) Value(AARCH64_FUNCTION_NONE) + +EnumValue +Enum(aarch64_ra_sign_scope_t) String(non-leaf) Value(AARCH64_FUNCTION_NON_LEAF) + +EnumValue +Enum(aarch64_ra_sign_scope_t) String(all) Value(AARCH64_FUNCTION_ALL) + mlow-precision-recip-sqrt Common Var(flag_mrecip_low_precision_sqrt) Optimization Enable the reciprocal square root approximation. Enabling this reduces diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index e2377c1..c59d31e 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -1032,6 +1032,10 @@ (define_int_iterator FMAXMIN_UNS [UNSPEC_FMAX UNSPEC_FMIN UNSPEC_FMAXNM UNSPEC_FMINNM]) +(define_int_iterator PAUTH_LR_SP [UNSPEC_PACISP UNSPEC_AUTISP]) + +(define_int_iterator PAUTH_17_16 [UNSPEC_PACI1716 UNSPEC_AUTI1716]) + (define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH]) (define_int_iterator USSUQADD [UNSPEC_SUQADD UNSPEC_USQADD]) @@ -1218,6 +1222,18 @@ (UNSPEC_FCVTZS "fcvtzs") (UNSPEC_FCVTZU "fcvtzu")]) +;; Pointer authentication mnemonic prefix. +(define_int_attr pauth_mnem_prefix [(UNSPEC_PACISP "paci") + (UNSPEC_AUTISP "auti") + (UNSPEC_PACI1716 "paci") + (UNSPEC_AUTI1716 "auti")]) + +;; Pointer authentication HINT number for NOP space instructions using A Key. +(define_int_attr pauth_hint_num_a [(UNSPEC_PACISP "25") + (UNSPEC_AUTISP "29") + (UNSPEC_PACI1716 "8") + (UNSPEC_AUTI1716 "12")]) + (define_int_attr perm_insn [(UNSPEC_ZIP1 "zip") (UNSPEC_ZIP2 "zip") (UNSPEC_TRN1 "trn") (UNSPEC_TRN2 "trn") (UNSPEC_UZP1 "uzp") (UNSPEC_UZP2 "uzp")]) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 30bdcf0..4516a86 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3513,6 +3513,12 @@ Specifies the core for which to tune the performance of this function and also whose architectural features to use. The behavior and valid arguments are the same as for the @option{-mcpu=} command-line option. +@item sign-return-address +@cindex @code{sign-return-address} function attribute, AArch64 +Select the function scope on which return address signing will be applied. The +behaviour and permissible arguments are the same as for the command-line option +@option{-msign-return-address=}. The default value is @code{none}. + @end table The above target attributes can be specified as follows: diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index aa0ac8b..c75d4b3 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -14044,6 +14044,14 @@ accessed using a single instruction and emitted after each function. This limits the maximum size of functions to 1MB. This is enabled by default for @option{-mcmodel=tiny}. +@item -msign-return-address=@var{scope} +@opindex msign-return-address +Select the function scope on which return address signing will be applied. +Permissible values are @samp{none}, which disables return address signing, +@samp{non-leaf}, which enables pointer signing for functions which are not leaf +functions, and @samp{all}, which enables pointer signing for all functions. The +default value is @samp{none}. + @end table @subsubsection @option{-march} and @option{-mcpu} Feature Modifiers diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c new file mode 100644 index 0000000..fda72a4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c @@ -0,0 +1,51 @@ +/* Testing return address signing where no combined instructions used. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msign-return-address=all" } */ + +int foo (int); + +/* sibcall only. */ +int __attribute__ ((target ("arch=armv8.3-a"))) +func1 (int a, int b) +{ + /* paciasp */ + return foo (a + b); + /* autiasp */ +} + +/* non-leaf function with sibcall. */ +int __attribute__ ((target ("arch=armv8.3-a"))) +func2 (int a, int b) +{ + /* paciasp */ + if (a < b) + return b; + + a = foo (b); + + return foo (a); + /* autiasp */ +} + +/* non-leaf function, legacy arch. */ +int __attribute__ ((target ("arch=armv8.2-a"))) +func3 (int a, int b, int c) +{ + /* paciasp */ + return a + foo (b) + c; + /* autiasp */ +} + +/* eh_return. */ +void __attribute__ ((target ("arch=armv8.3-a"))) +func4 (long offset, void *handler, int *ptr, int imm1, int imm2) +{ + /* paciasp */ + *ptr = imm1 + foo (imm1) + imm2; + __builtin_eh_return (offset, handler); + /* autiasp */ + return; +} + +/* { dg-final { scan-assembler-times "autiasp" 4 } } */ +/* { dg-final { scan-assembler-times "paciasp" 4 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c new file mode 100644 index 0000000..54fe47a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c @@ -0,0 +1,17 @@ +/* Testing return address signing where combined instructions used. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msign-return-address=all" } */ + +int foo (int); +int bar (int, int); + +int __attribute__ ((target ("arch=armv8.3-a"))) +func1 (int a, int b, int c) +{ + /* paciasp */ + return a + foo (b) + c; + /* retaa */ +} + +/* { dg-final { scan-assembler-times "paciasp" 1 } } */ +/* { dg-final { scan-assembler-times "retaa" 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c new file mode 100644 index 0000000..adc5eff --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c @@ -0,0 +1,21 @@ +/* Testing the disable of return address signing. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msign-return-address=all" } */ + +int bar (int, int); + +int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=non-leaf"))) +func1_leaf (int a, int b, int c, int d) +{ + return a + b + c + d; +} + +int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none"))) +func2_none (int a, int b, int c, int d) +{ + return c + bar (a, b) + d; +} + +/* { dg-final { scan-assembler-not "paciasp" } } */ +/* { dg-final { scan-assembler-not "autiasp" } } */ +/* { dg-final { scan-assembler-not "retaa" } } */