diff mbox

[1/5,AArch64] Return address protection on AArch64

Message ID f38fbbb0-067b-d996-46aa-1ce9c3dd2d75@foss.arm.com
State Superseded
Headers show

Commit Message

Jiong Wang Jan. 6, 2017, 11:47 a.m. UTC
On 11/11/16 18:22, Jiong Wang wrote:
> As described in the cover letter, this patch implements return address signing

> for AArch64, it's controlled by the new option:

>

>    -msign-return-address=[none | non-leaf | all]

>

> "none" means don't do return address signing at all on any function.  "non-leaf"

> means only sign non-leaf function.  "all" means sign all functions.  Return

> address signing is currently disabled on ILP32.  I haven't tested it.

>

> The instructions added in the architecture are of 2 kinds.

>

> * In the NOP instruction space, which allows binaries to run without any traps

> on older versions of the architecture. This doesn't give any additional

> protection on older hardware but allows for the same binary to be used on

> earlier versions of the architecture and newer versions of the architecture.

>

> * New instructions that are only valid for v8.3 and will trap if used on earlier

> versions of the architecture.

>

> At default, once return address signing is enabled, it will only generates NOP

> instruction.

>

> While if -march=armv8.3-a specified, GCC will try to use the most efficient

> pointer authentication instruction as it can.

>

> The architecture has 2 user invisible system keys for signing and creating

> signed addresses as part of these instructions. For some use case, the user

> might want to use difference key for different functions.  The new option

> "-msign-return-address-key=key_name" let GCC select the key used for return

> address signing.  Permissible values are "a_key" for A key and "b_key" for B

> key, and this option are supported by function target attribute and LTO will

> hopefully just work.

>

>

>

> gcc/

> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>

>          * config/aarch64/aarch64-opts.h (aarch64_pauth_key_index): New enum.

>          (aarch64_function_type): New enum.

>          * config/aarch64/aarch64-protos.h (aarch64_output_sign_auth_reg): New

>          declaration.

>          * config/aarch64/aarch64.c (aarch64_expand_prologue): Sign return

>          address before it's pushed onto stack.

>          (aarch64_expand_epilogue): Authenticate return address fetched from

>          stack.

>          (aarch64_output_sign_auth_reg): New function.

>          (aarch64_override_options): Sanity check for ILP32 and ISA level.

>          (aarch64_attributes): New function attributes for "sign-return-address",

>          "pauth-key".

>          * config/aarch64/aarch64.md (UNSPEC_AUTH_REG, UNSPEC_AUTH_REG1716,

>          UNSPEC_SIGN_REG, UNSPEC_SIGN_REG1716, UNSPEC_STRIP_REG_SIGN,

>          UNSPEC_STRIP_X30_SIGN): New unspecs.

>          ("*do_return"): Generate combined instructions according to key index.

>          ("sign_reg", "sign_reg1716", "auth_reg", "auth_reg1716",

>          "strip_reg_sign", "strip_lr_sign"): New.

>          * config/aarch64/aarch64.opt (msign-return-address, mpauth-key): New.

>          * config/aarch64/predicates.md (aarch64_const0_const1): New predicate.

>          * doc/extend.texi (AArch64 Function Attributes): Documents

>          "sign-return-address=", "pauth-key".

>          * doc/invoke.texi (AArch64 Options): Documents "-msign-return-address=",

>          "-pauth-key".

>

> gcc/testsuite/

> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>

>          * gcc.target/aarch64/return_address_sign_1.c: New testcase.

>          * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase.


Update the patchset according to new DWARF proposal described at

   https://gcc.gnu.org/ml/gcc-patches/2016-11/msg03010.html

While A key support for return address signing using DW_CFA_GNU_window_save only
needs simple modifications on code and associated DWARF generation, B key
support is complexer, it needs multiple CIE support in GCC and Binutils, so
currently we fall back to DWARF value expression which fully works although
requires longer encodings. Value expression also requires a few changes on
AArch64 prologue and epilogue hooks that code review will not be easy.

Therefore I have removed all B key support code in the initial support patch set,
and will organize them into a seperate follow up patchset so that we can do A key
code review first.

This patch is an update on the return address signing code generation.

gcc/
2017-01-06  Jiong Wang  <jiong.wang@arm.com>

         * 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.
         ("<pauth_mnem_prefix>sp", "<pauth_mnem_prefix1716", "xpaclri"): New.
         * 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  <jiong.wang@arm.com>

         * gcc.target/aarch64/return_address_sign_1.c: New testcase.
         * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase.

Comments

James Greenhalgh Jan. 13, 2017, 4:04 p.m. UTC | #1
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  <jiong.wang@arm.com>

> 

>         * 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.

>         ("<pauth_mnem_prefix>sp", "<pauth_mnem_prefix1716", "xpaclri"): New.

>         * 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  <jiong.wang@arm.com>

> 

>         * 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, mostly around the wording of comments.

> --- a/gcc/config/aarch64/aarch64.c

> +++ b/gcc/config/aarch64/aarch64.c

> @@ -3670,6 +3690,16 @@ aarch64_expand_epilogue (bool for_sibcall)

>        RTX_FRAME_RELATED_P (insn) = 1;

>      }

>  

> +  /* sibcall won't generate normally return, therefore we need to authenticate

> +     at here.  !TARGET_ARMV8_3 disallows GCC to use combined authentication

> +     instruction which we prefer, so we need to generate a seperate

> +     authentication. eh_return path can't do combined authentication, as it will

> +     do extra stack adjustment which updates CFA to EH handler's CFA while we

> +     want to use the CFA of the function which calls eh_return.  */


This comment does not read correctly to me, and I'm not sure what you
mean by it. I'd rewrite it as so:

  We prefer to emit the combined return/authenticate instruction RETAA,
  however there are three cases in which we must instead emit an explicit
  authentication instruction.

    1) Sibcalls don't return in a normal way, so if we're about to
       call one we must authenticate.
    2) The RETAA instruction is not available before ARMv8.3-A, so if we
       are generating code for !TARGET_ARMV8_3 we can't use it and must
       explicitly authenticate.
    3) On an eh_return path we make extra stack adjustments to update the
       canonical frame address to be the exception handler's CFA.  We want
       to authenticate using the CFA of the function which calls eh_return.

> +  if (aarch64_return_address_signing_enabled ()

> +      && (for_sibcall || !TARGET_ARMV8_3 || crtl->calls_eh_return))

> +    emit_insn (gen_autisp ());

> +

>    /* Stack adjustment for exception handler.  */

>    if (crtl->calls_eh_return)

>      {

> @@ -8894,6 +8924,9 @@ aarch64_override_options (void)

>      error ("Assembler does not support -mabi=ilp32");

>  #endif

>  

> +  if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE && TARGET_ILP32)

> +    error ("Return address signing is only supported on LP64");


Should this be a sorry? I think this is something which has not been
implemented rather than a fundamental restriction.

Maybe:

  sorry ("Return address signing is only supported for -mabi=lp64");

Would be clear for our users.

> +

>    /* Make sure we properly set up the explicit options.  */

>    if ((aarch64_cpu_string && valid_cpu)

>         || (aarch64_tune_string && valid_tune))

> @@ -9277,6 +9310,8 @@ static const struct aarch64_attribute_info aarch64_attributes[] =

>    { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },

>    { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,

>       OPT_mtune_ },

> +  { "sign-return-address", aarch64_attr_enum, false, NULL,

> +     OPT_msign_return_address_ },

>    { NULL, aarch64_attr_custom, false, NULL, OPT____ }

>  };

>  

> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md

> index bde42317f1bfd91a9d38a4cfa94d4cedd5246003..9b6f99dee3cecc0f15f24ec2375d3641fe03892d 100644

> --- a/gcc/config/aarch64/aarch64.md

> +++ b/gcc/config/aarch64/aarch64.md

> @@ -67,6 +67,8 @@

>  )

>  

>  (define_c_enum "unspec" [

> +    UNSPEC_AUTI1716

> +    UNSPEC_AUTISP

>      UNSPEC_CASESI

>      UNSPEC_CRC32B

>      UNSPEC_CRC32CB

> @@ -106,6 +108,8 @@

>      UNSPEC_LD4_LANE

>      UNSPEC_MB

>      UNSPEC_NOP

> +    UNSPEC_PACI1716

> +    UNSPEC_PACISP

>      UNSPEC_PRLG_STK

>      UNSPEC_RBIT

>      UNSPEC_SCVTF

> @@ -135,6 +139,7 @@

>      UNSPEC_RSQRTE

>      UNSPEC_RSQRTS

>      UNSPEC_NZCV

> +    UNSPEC_XPACLRI

>  ])

>  

>  (define_c_enum "unspecv" [

> @@ -575,7 +580,14 @@

>  (define_insn "*do_return"

>    [(return)]

>    ""

> -  "ret"

> +  {

> +    if (aarch64_return_address_signing_enabled ()

> +	&& TARGET_ARMV8_3

> +	&& !crtl->calls_eh_return)

> +      return "retaa";

> +

> +    return "ret";

> +  }

>    [(set_attr "type" "branch")]

>  )

>  

> @@ -5341,6 +5353,31 @@

>    [(set_attr "length" "0")]

>  )

>  

> +;; Pointer authentication patterns are available for all architectures.  On

> +;; pre-ARMv8.3-A architectures they are NOP.  This let the user write portable

> +;; software which can get pointer authentication on new hardware while still

> +;; runs correctly on old hardware though no pointer authentication protection.


This comment should be reworded slightly:

;; 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.

Each of these new instructions could do with a comment explaining 

> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi

> index 30bdcf07ad8b1bd086bbb87acb36fb0333944087..47250ebb149bbde021ef64eba8e96e35c2623284 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 we want to do return address signing on.  The behavior

> +and permissible arguments are the same as for the command-line option

> +@option{-msign-return-address=}.  The default value is @code{none}

> +


This could do with rewording slightly:

  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 aa0ac8b41128483be53645b91bdcead096582e23..2792dbd0a2d0ed9e3f46237685f8ae65a5d8bcf5 100644

> --- a/gcc/doc/invoke.texi

> +++ b/gcc/doc/invoke.texi

> @@ -14044,6 +14044,13 @@ 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 we want to do return address signing on.  Permissible

> +values are @samp{none}, @samp{none-leaf} and @samp{all}.  @samp{none} means


Typo: s/none-leaf/non-leaf/

> +return address signing is disabled.  @samp{non-leaf} enables it for non-leaf

> +functions.  @samp{all} for all functions and is the default value.


This documentation does not follow the patch. In the patch, the default is
"none".

I'd reword this as so:

  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 0000000000000000000000000000000000000000..9a0332abd41ca6ae994e6ed72771fca8ee532cd0

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c

> @@ -0,0 +1,56 @@

> +/* { dg-do compile } */

> +/* { dg-options "-O2 -msign-return-address=all" } */

> +

> +int foo (int);

> +int bar (int, 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 */

> +}

> +

> +/* non-leaf function.  */

> +int __attribute__ ((target ("arch=armv8.3-a")))

> +func4 (int a, int b, int c)

> +{

> +  /* paciasp */

> +  return a + foo (b) + c;

> +  /* retab */

> +}

> +

> +int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))

> +func4_disable (int a, int b, int c, int d)

> +{

> +  return c + bar (a, b) + d;

> +}

> +

> +/* { dg-final { scan-assembler-times "autiasp" 3 } } */

> +/* { dg-final { scan-assembler-times "paciasp" 4 } } */

> +/* { dg-final { scan-assembler-times "retaa" 1 } } */


These testcases should both be split.

As it stands, multiple buggy implementations could cancel each other out
when it comes to a scan-assembler-times and the test would still pass.

It would be much clearer to test each expected behaviour in a single file.

Thanks,
James
Andrew Pinski Jan. 20, 2017, 3:39 a.m. UTC | #2
On Fri, Jan 6, 2017 at 3:47 AM, Jiong Wang <jiong.wang@foss.arm.com> wrote:
> On 11/11/16 18:22, Jiong Wang wrote:

>>

>> As described in the cover letter, this patch implements return address

>> signing

>> for AArch64, it's controlled by the new option:

>>

>>    -msign-return-address=[none | non-leaf | all]

>>

>> "none" means don't do return address signing at all on any function.

>> "non-leaf"

>> means only sign non-leaf function.  "all" means sign all functions.

>> Return

>> address signing is currently disabled on ILP32.  I haven't tested it.

>>

>> The instructions added in the architecture are of 2 kinds.

>>

>> * In the NOP instruction space, which allows binaries to run without any

>> traps

>> on older versions of the architecture. This doesn't give any additional

>> protection on older hardware but allows for the same binary to be used on

>> earlier versions of the architecture and newer versions of the

>> architecture.

>>

>> * New instructions that are only valid for v8.3 and will trap if used on

>> earlier

>> versions of the architecture.

>>

>> At default, once return address signing is enabled, it will only generates

>> NOP

>> instruction.

>>

>> While if -march=armv8.3-a specified, GCC will try to use the most

>> efficient

>> pointer authentication instruction as it can.

>>

>> The architecture has 2 user invisible system keys for signing and creating

>> signed addresses as part of these instructions. For some use case, the

>> user

>> might want to use difference key for different functions.  The new option

>> "-msign-return-address-key=key_name" let GCC select the key used for

>> return

>> address signing.  Permissible values are "a_key" for A key and "b_key" for

>> B

>> key, and this option are supported by function target attribute and LTO

>> will

>> hopefully just work.

>>

>>

>>

>> gcc/

>> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>>

>>          * config/aarch64/aarch64-opts.h (aarch64_pauth_key_index): New

>> enum.

>>          (aarch64_function_type): New enum.

>>          * config/aarch64/aarch64-protos.h (aarch64_output_sign_auth_reg):

>> New

>>          declaration.

>>          * config/aarch64/aarch64.c (aarch64_expand_prologue): Sign return

>>          address before it's pushed onto stack.

>>          (aarch64_expand_epilogue): Authenticate return address fetched

>> from

>>          stack.

>>          (aarch64_output_sign_auth_reg): New function.

>>          (aarch64_override_options): Sanity check for ILP32 and ISA level.

>>          (aarch64_attributes): New function attributes for

>> "sign-return-address",

>>          "pauth-key".

>>          * config/aarch64/aarch64.md (UNSPEC_AUTH_REG,

>> UNSPEC_AUTH_REG1716,

>>          UNSPEC_SIGN_REG, UNSPEC_SIGN_REG1716, UNSPEC_STRIP_REG_SIGN,

>>          UNSPEC_STRIP_X30_SIGN): New unspecs.

>>          ("*do_return"): Generate combined instructions according to key

>> index.

>>          ("sign_reg", "sign_reg1716", "auth_reg", "auth_reg1716",

>>          "strip_reg_sign", "strip_lr_sign"): New.

>>          * config/aarch64/aarch64.opt (msign-return-address, mpauth-key):

>> New.

>>          * config/aarch64/predicates.md (aarch64_const0_const1): New

>> predicate.

>>          * doc/extend.texi (AArch64 Function Attributes): Documents

>>          "sign-return-address=", "pauth-key".

>>          * doc/invoke.texi (AArch64 Options): Documents

>> "-msign-return-address=",

>>          "-pauth-key".

>>

>> gcc/testsuite/

>> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>>

>>          * gcc.target/aarch64/return_address_sign_1.c: New testcase.

>>          * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase.

>

>

> Update the patchset according to new DWARF proposal described at

>

>   https://gcc.gnu.org/ml/gcc-patches/2016-11/msg03010.html


One of these patches of this patch set break ILP32 building for
aarch64-elf and most likely also aarch64-linux-gnu.

/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/libgcc/unwind-dw2.c:
In function ‘uw_init_context_1’:
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/libgcc/unwind-dw2.c:1567:6:
internal compiler error: in emit_move_insn, at expr.c:3698
   ra = MD_POST_EXTRACT_ROOT_ADDR (ra);
0x8270cf emit_move_insn(rtx_def*, rtx_def*)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.c:3697
0x80867b force_reg(machine_mode, rtx_def*)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/explow.c:648
0xe9143f aarch64_expand_builtin(tree_node*, rtx_def*, rtx_def*,
machine_mode, int)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/config/aarch64/aarch64-builtins.c:1336
0x6fae09 expand_builtin(tree_node*, rtx_def*, rtx_def*, machine_mode, int)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/builtins.c:6359
0x8227bb expand_expr_real_1(tree_node*, rtx_def*, machine_mode,
expand_modifier, rtx_def**, bool)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.c:10782
0x82de70 expand_expr
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.h:276
0x82de70 store_expr_with_bounds(tree_node*, rtx_def*, int, bool, bool,
tree_node*)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.c:5459
0x82f3b8 expand_assignment(tree_node*, tree_node*, bool)
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.c:5321
0x71e8da expand_call_stmt
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/cfgexpand.c:2656
0x71e8da expand_gimple_stmt_1
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/cfgexpand.c:3571
0x71e8da expand_gimple_stmt
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/cfgexpand.c:3737
0x72085f expand_gimple_basic_block
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/cfgexpand.c:5744
0x726826 execute
/home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/cfgexpand.c:6357
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://www.cavium.com/support.html> for instructions.


Thanks,
Andrew




>

> While A key support for return address signing using DW_CFA_GNU_window_save

> only

> needs simple modifications on code and associated DWARF generation, B key

> support is complexer, it needs multiple CIE support in GCC and Binutils, so

> currently we fall back to DWARF value expression which fully works although

> requires longer encodings. Value expression also requires a few changes on

> AArch64 prologue and epilogue hooks that code review will not be easy.

>

> Therefore I have removed all B key support code in the initial support patch

> set,

> and will organize them into a seperate follow up patchset so that we can do

> A key

> code review first.

>

> This patch is an update on the return address signing code generation.

>

> gcc/

> 2017-01-06  Jiong Wang  <jiong.wang@arm.com>

>

>         * 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.

>         ("<pauth_mnem_prefix>sp", "<pauth_mnem_prefix1716", "xpaclri"): New.

>         * 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  <jiong.wang@arm.com>

>

>

>         * gcc.target/aarch64/return_address_sign_1.c: New testcase.

>         * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase.

>

>
Jiong Wang Jan. 20, 2017, 11:15 a.m. UTC | #3
On 20/01/17 03:39, Andrew Pinski wrote:
> On Fri, Jan 6, 2017 at 3:47 AM, Jiong Wang <jiong.wang@foss.arm.com> wrote:

>> On 11/11/16 18:22, Jiong Wang wrote:

>>> As described in the cover letter, this patch implements return address

>>> signing

>>> for AArch64, it's controlled by the new option:

>>>

>>>     -msign-return-address=[none | non-leaf | all]

>>>

>>> "none" means don't do return address signing at all on any function.

>>> "non-leaf"

>>> means only sign non-leaf function.  "all" means sign all functions.

>>> Return

>>> address signing is currently disabled on ILP32.  I haven't tested it.

>>>

>>> The instructions added in the architecture are of 2 kinds.

>>>

>>> * In the NOP instruction space, which allows binaries to run without any

>>> traps

>>> on older versions of the architecture. This doesn't give any additional

>>> protection on older hardware but allows for the same binary to be used on

>>> earlier versions of the architecture and newer versions of the

>>> architecture.

>>>

>>> * New instructions that are only valid for v8.3 and will trap if used on

>>> earlier

>>> versions of the architecture.

>>>

>>> At default, once return address signing is enabled, it will only generates

>>> NOP

>>> instruction.

>>>

>>> While if -march=armv8.3-a specified, GCC will try to use the most

>>> efficient

>>> pointer authentication instruction as it can.

>>>

>>> The architecture has 2 user invisible system keys for signing and creating

>>> signed addresses as part of these instructions. For some use case, the

>>> user

>>> might want to use difference key for different functions.  The new option

>>> "-msign-return-address-key=key_name" let GCC select the key used for

>>> return

>>> address signing.  Permissible values are "a_key" for A key and "b_key" for

>>> B

>>> key, and this option are supported by function target attribute and LTO

>>> will

>>> hopefully just work.

>>>

>>>

>>>

>>> gcc/

>>> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>>>

>>>           * config/aarch64/aarch64-opts.h (aarch64_pauth_key_index): New

>>> enum.

>>>           (aarch64_function_type): New enum.

>>>           * config/aarch64/aarch64-protos.h (aarch64_output_sign_auth_reg):

>>> New

>>>           declaration.

>>>           * config/aarch64/aarch64.c (aarch64_expand_prologue): Sign return

>>>           address before it's pushed onto stack.

>>>           (aarch64_expand_epilogue): Authenticate return address fetched

>>> from

>>>           stack.

>>>           (aarch64_output_sign_auth_reg): New function.

>>>           (aarch64_override_options): Sanity check for ILP32 and ISA level.

>>>           (aarch64_attributes): New function attributes for

>>> "sign-return-address",

>>>           "pauth-key".

>>>           * config/aarch64/aarch64.md (UNSPEC_AUTH_REG,

>>> UNSPEC_AUTH_REG1716,

>>>           UNSPEC_SIGN_REG, UNSPEC_SIGN_REG1716, UNSPEC_STRIP_REG_SIGN,

>>>           UNSPEC_STRIP_X30_SIGN): New unspecs.

>>>           ("*do_return"): Generate combined instructions according to key

>>> index.

>>>           ("sign_reg", "sign_reg1716", "auth_reg", "auth_reg1716",

>>>           "strip_reg_sign", "strip_lr_sign"): New.

>>>           * config/aarch64/aarch64.opt (msign-return-address, mpauth-key):

>>> New.

>>>           * config/aarch64/predicates.md (aarch64_const0_const1): New

>>> predicate.

>>>           * doc/extend.texi (AArch64 Function Attributes): Documents

>>>           "sign-return-address=", "pauth-key".

>>>           * doc/invoke.texi (AArch64 Options): Documents

>>> "-msign-return-address=",

>>>           "-pauth-key".

>>>

>>> gcc/testsuite/

>>> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>>>

>>>           * gcc.target/aarch64/return_address_sign_1.c: New testcase.

>>>           * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase.

>>

>> Update the patchset according to new DWARF proposal described at

>>

>>    https://gcc.gnu.org/ml/gcc-patches/2016-11/msg03010.html

> One of these patches of this patch set break ILP32 building for

> aarch64-elf and most likely also aarch64-linux-gnu.

>

> /home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/libgcc/unwind-dw2.c:

> In function ‘uw_init_context_1’:

> /home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/libgcc/unwind-dw2.c:1567:6:

> internal compiler error: in emit_move_insn, at expr.c:3698

>     ra = MD_POST_EXTRACT_ROOT_ADDR (ra);

> 0x8270cf emit_move_insn(rtx_def*, rtx_def*)

> /home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.c:3697

> 0x80867b force_reg(machine_mode, rtx_def*)

Must be the Pmode issue under ILP32, I am testing a fix (I don't have 
full ILP32 environment, so can only test simply by force libgcc build 
with -mabi=ilp32)

>

> Thanks,

> Andrew

>

>

>

>

>> While A key support for return address signing using DW_CFA_GNU_window_save

>> only

>> needs simple modifications on code and associated DWARF generation, B key

>> support is complexer, it needs multiple CIE support in GCC and Binutils, so

>> currently we fall back to DWARF value expression which fully works although

>> requires longer encodings. Value expression also requires a few changes on

>> AArch64 prologue and epilogue hooks that code review will not be easy.

>>

>> Therefore I have removed all B key support code in the initial support patch

>> set,

>> and will organize them into a seperate follow up patchset so that we can do

>> A key

>> code review first.

>>

>> This patch is an update on the return address signing code generation.

>>

>> gcc/

>> 2017-01-06  Jiong Wang  <jiong.wang@arm.com>

>>

>>          * 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.

>>          ("<pauth_mnem_prefix>sp", "<pauth_mnem_prefix1716", "xpaclri"): New.

>>          * 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  <jiong.wang@arm.com>

>>

>>

>>          * gcc.target/aarch64/return_address_sign_1.c: New testcase.

>>          * gcc.target/aarch64/return_address_sign_scope_1.c: New testcase.

>>

>>
Jiong Wang Jan. 20, 2017, 12:36 p.m. UTC | #4
On 20/01/17 11:15, Jiong Wang wrote:
>

>

> On 20/01/17 03:39, Andrew Pinski wrote:

>> On Fri, Jan 6, 2017 at 3:47 AM, Jiong Wang <jiong.wang@foss.arm.com> 

>> wrote:

>>> On 11/11/16 18:22, Jiong Wang wrote:

>>>> As described in the cover letter, this patch implements return address

>>>> signing

>>>> for AArch64, it's controlled by the new option:

>>>>

>>>>     -msign-return-address=[none | non-leaf | all]

>>>>

>>>> "none" means don't do return address signing at all on any function.

>>>> "non-leaf"

>>>> means only sign non-leaf function.  "all" means sign all functions.

>>>> Return

>>>> address signing is currently disabled on ILP32.  I haven't tested it.

>>>>

>>>> The instructions added in the architecture are of 2 kinds.

>>>>

>>>> * In the NOP instruction space, which allows binaries to run 

>>>> without any

>>>> traps

>>>> on older versions of the architecture. This doesn't give any 

>>>> additional

>>>> protection on older hardware but allows for the same binary to be 

>>>> used on

>>>> earlier versions of the architecture and newer versions of the

>>>> architecture.

>>>>

>>>> * New instructions that are only valid for v8.3 and will trap if 

>>>> used on

>>>> earlier

>>>> versions of the architecture.

>>>>

>>>> At default, once return address signing is enabled, it will only 

>>>> generates

>>>> NOP

>>>> instruction.

>>>>

>>>> While if -march=armv8.3-a specified, GCC will try to use the most

>>>> efficient

>>>> pointer authentication instruction as it can.

>>>>

>>>> The architecture has 2 user invisible system keys for signing and 

>>>> creating

>>>> signed addresses as part of these instructions. For some use case, the

>>>> user

>>>> might want to use difference key for different functions. The new 

>>>> option

>>>> "-msign-return-address-key=key_name" let GCC select the key used for

>>>> return

>>>> address signing.  Permissible values are "a_key" for A key and 

>>>> "b_key" for

>>>> B

>>>> key, and this option are supported by function target attribute and 

>>>> LTO

>>>> will

>>>> hopefully just work.

>>>>

>>>>

>>>>

>>>> gcc/

>>>> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>>>>

>>>>           * config/aarch64/aarch64-opts.h 

>>>> (aarch64_pauth_key_index): New

>>>> enum.

>>>>           (aarch64_function_type): New enum.

>>>>           * config/aarch64/aarch64-protos.h 

>>>> (aarch64_output_sign_auth_reg):

>>>> New

>>>>           declaration.

>>>>           * config/aarch64/aarch64.c (aarch64_expand_prologue): 

>>>> Sign return

>>>>           address before it's pushed onto stack.

>>>>           (aarch64_expand_epilogue): Authenticate return address 

>>>> fetched

>>>> from

>>>>           stack.

>>>>           (aarch64_output_sign_auth_reg): New function.

>>>>           (aarch64_override_options): Sanity check for ILP32 and 

>>>> ISA level.

>>>>           (aarch64_attributes): New function attributes for

>>>> "sign-return-address",

>>>>           "pauth-key".

>>>>           * config/aarch64/aarch64.md (UNSPEC_AUTH_REG,

>>>> UNSPEC_AUTH_REG1716,

>>>>           UNSPEC_SIGN_REG, UNSPEC_SIGN_REG1716, UNSPEC_STRIP_REG_SIGN,

>>>>           UNSPEC_STRIP_X30_SIGN): New unspecs.

>>>>           ("*do_return"): Generate combined instructions according 

>>>> to key

>>>> index.

>>>>           ("sign_reg", "sign_reg1716", "auth_reg", "auth_reg1716",

>>>>           "strip_reg_sign", "strip_lr_sign"): New.

>>>>           * config/aarch64/aarch64.opt (msign-return-address, 

>>>> mpauth-key):

>>>> New.

>>>>           * config/aarch64/predicates.md (aarch64_const0_const1): New

>>>> predicate.

>>>>           * doc/extend.texi (AArch64 Function Attributes): Documents

>>>>           "sign-return-address=", "pauth-key".

>>>>           * doc/invoke.texi (AArch64 Options): Documents

>>>> "-msign-return-address=",

>>>>           "-pauth-key".

>>>>

>>>> gcc/testsuite/

>>>> 2016-11-09  Jiong Wang<jiong.wang@arm.com>

>>>>

>>>>           * gcc.target/aarch64/return_address_sign_1.c: New testcase.

>>>>           * gcc.target/aarch64/return_address_sign_scope_1.c: New 

>>>> testcase.

>>>

>>> Update the patchset according to new DWARF proposal described at

>>>

>>>    https://gcc.gnu.org/ml/gcc-patches/2016-11/msg03010.html

>> One of these patches of this patch set break ILP32 building for

>> aarch64-elf and most likely also aarch64-linux-gnu.

>>

>> /home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/libgcc/unwind-dw2.c: 

>>

>> In function ‘uw_init_context_1’:

>> /home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/libgcc/unwind-dw2.c:1567:6: 

>>

>> internal compiler error: in emit_move_insn, at expr.c:3698

>>     ra = MD_POST_EXTRACT_ROOT_ADDR (ra);

>> 0x8270cf emit_move_insn(rtx_def*, rtx_def*)

>> /home/jenkins/workspace/BuildToolchainAARCH64_thunder_elf_upstream/toolchain/scripts/../src/gcc/expr.c:3697 

>>

>> 0x80867b force_reg(machine_mode, rtx_def*)

> Must be the Pmode issue under ILP32, I am testing a fix (I don't have 

> full ILP32 environment, so can only test simply by force libgcc build 

> with -mabi=ilp32)


Here is the patch.

For XPACLRI builtin which drops the signature in a pointer, it's prototype is  "void *foo (void *)"
FOR PAC/AUT builtin which sign or authenticate a pointer, it's prototype is "void *foo (void *, uint64)".

This patch adjusted those modes to make sure they strictly follow the C prototype. I also borrow the type define in ARM backend

   typedef unsigned _uw64 __attribute__((mode(__DI__)));

And this is need to type cast the salt value which is always DImode.

It passed my local ILP32 cross build.

OK for trunk?

gcc/
2017-01-20  Jiong Wang  <jiong.wang@arm.com>
         * config/aarch64/aarch64-builtins.c (aarch64_expand_builtin): Fix modes
         for AARCH64_PAUTH_BUILTIN_XPACLRI, AARCH64_PAUTH_BUILTIN_PACIA1716 and
         AARCH64_PAUTH_BUILTIN_AUTIA1716.

libgcc/
         * config/aarch64/aarch64-unwind.h (_uw64): New typedef.
         (aarch64_post_extract_frame_addr):  Cast salt to _uw64.
         (aarch64_post_frob_eh_handler_addr): Likewise.diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 6c6530c..7ef351e 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -1333,18 +1333,20 @@ aarch64_expand_builtin (tree exp,
     case AARCH64_PAUTH_BUILTIN_PACIA1716:
     case AARCH64_PAUTH_BUILTIN_XPACLRI:
       arg0 = CALL_EXPR_ARG (exp, 0);
-      op0 = force_reg (Pmode, expand_normal (arg0));
+      /* Operand0 should have ptr_mode as its a ptr_type_node, this makes both
+	 LP64 and ILP32 expand correctly.  */
+      op0 = force_reg (ptr_mode, expand_normal (arg0));
 
       if (!target)
-	target = gen_reg_rtx (Pmode);
+	target = gen_reg_rtx (ptr_mode);
       else
-	target = force_reg (Pmode, target);
+	target = force_reg (ptr_mode, target);
 
       emit_move_insn (target, op0);
 
       if (fcode == AARCH64_PAUTH_BUILTIN_XPACLRI)
 	{
-	  rtx lr = gen_rtx_REG (Pmode, R30_REGNUM);
+	  rtx lr = gen_rtx_REG (ptr_mode, R30_REGNUM);
 	  icode = CODE_FOR_xpaclri;
 	  emit_move_insn (lr, op0);
 	  emit_insn (GEN_FCN (icode) ());
@@ -1353,12 +1355,13 @@ aarch64_expand_builtin (tree exp,
       else
 	{
 	  tree arg1 = CALL_EXPR_ARG (exp, 1);
-	  rtx op1 = force_reg (Pmode, expand_normal (arg1));
+	  /* Operand1 for either PAC or AUT is a unsigned_intDI_type_node.  */
+	  rtx op1 = force_reg (DImode, expand_normal (arg1));
 	  icode = (fcode == AARCH64_PAUTH_BUILTIN_PACIA1716
 		   ? CODE_FOR_paci1716 : CODE_FOR_auti1716);
 
-	  rtx x16_reg = gen_rtx_REG (Pmode, R16_REGNUM);
-	  rtx x17_reg = gen_rtx_REG (Pmode, R17_REGNUM);
+	  rtx x16_reg = gen_rtx_REG (DImode, R16_REGNUM);
+	  rtx x17_reg = gen_rtx_REG (ptr_mode, R17_REGNUM);
 	  emit_move_insn (x17_reg, op0);
 	  emit_move_insn (x16_reg, op1);
 	  emit_insn (GEN_FCN (icode) ());
diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h
index a43d965..7dd2549 100644
--- a/libgcc/config/aarch64/aarch64-unwind.h
+++ b/libgcc/config/aarch64/aarch64-unwind.h
@@ -35,6 +35,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define MD_FROB_UPDATE_CONTEXT(context, fs) \
   aarch64_frob_update_context (context, fs)
 
+typedef unsigned _uw64 __attribute__((mode(__DI__)));
+
 /* Do AArch64 private extraction on ADDR based on context info CONTEXT and
    unwind frame info FS.  If ADDR is signed, we do address authentication on it
    using CFA of current frame.  */
@@ -45,7 +47,7 @@ aarch64_post_extract_frame_addr (struct _Unwind_Context *context,
 {
   if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1)
     {
-      _Unwind_Word salt = (_Unwind_Word) context->cfa;
+      _uw64 salt = (_uw64) context->cfa;
       return __builtin_aarch64_autia1716 (addr, salt);
     }
   else
@@ -64,7 +66,7 @@ aarch64_post_frob_eh_handler_addr (struct _Unwind_Context *current,
 {
   if (current->flags & RA_A_SIGNED_BIT)
     return __builtin_aarch64_pacia1716 (handler_addr,
-					(_Unwind_Word) current->cfa);
+					(_uw64) current->cfa);
   else
     return handler_addr;
 }

Jiong Wang Jan. 20, 2017, 6:23 p.m. UTC | #5
>> Here is the patch.

>>

>> For XPACLRI builtin which drops the signature in a pointer, it's

>> prototype is  "void *foo (void *)"

>> FOR PAC/AUT builtin which sign or authenticate a pointer, it's prototype

>> is "void *foo (void *, uint64)".

>>

>> This patch adjusted those modes to make sure they strictly follow the C

>> prototype. I also borrow the type define in ARM backend

>>

>>    typedef unsigned _uw64 __attribute__((mode(__DI__)));

>>

>> And this is need to type cast the salt value which is always DImode.

>>

>> It passed my local ILP32 cross build.

>>

>> OK for trunk?

>>

>> gcc/

>> 2017-01-20  Jiong Wang  <jiong.wang@arm.com>

>>          * config/aarch64/aarch64-builtins.c (aarch64_expand_builtin):

>> Fix modes

>>          for AARCH64_PAUTH_BUILTIN_XPACLRI,

>> AARCH64_PAUTH_BUILTIN_PACIA1716 and

>>          AARCH64_PAUTH_BUILTIN_AUTIA1716.

>>

>> libgcc/

>>          * config/aarch64/aarch64-unwind.h (_uw64): New typedef.

>>          (aarch64_post_extract_frame_addr):  Cast salt to _uw64.

>>          (aarch64_post_frob_eh_handler_addr): Likewise.

>>

>>

> Hmm, we currently don't support ILP32 at all for pointer signing (sorry

> ("Return address signing is only supported for -mabi=lp64");), so I

> wonder if it would be better for now to simply suppress all the new

> hooks in aarch64-unwind.h ifdef __ILP32__.

>

> R.

>


OK, the attached patch disable the building of pointer signing code in libgcc
on ILP32 mode, except the macro bit RA_A_SIGNED_BIT is still defined as I
want to book this bit for ILP32 as LP64 in case we later enable ILP32 support.

All pauth builtins are not registered as well for ILP32 mode as these builtins
are supposed to be used by libgcc unwinder code only.

I also gated the three new testcases for return address signing using the
following directive and verified it works under my dejagnu environment.

{ dg-require-effective-target lp64 }

multilib cross build finished (lp64, ilp32), OK for trunk?

BTW, the mode fix patch doesn't have conflict with this patch, we may
still need it if we want to enable ILP32 support later.

Thanks.

gcc/
2017-01-20  Jiong Wang  <jiong.wang@arm.com>

         * config/aarch64/aarch64-builtins.c (aarch64_init_builtins): Don't
         register pauth builtins for ILP32.

libgcc/
         * config/aarch64/aarch64-unwind.h: Restrict this file on LP64 only.
         * unwind-dw2.c (execute_cfa_program):  Only multiplexing
         DW_CFA_GNU_window_save for AArch64 LP64.diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 7ef351eb53b21c94a07dbd7c49813276dfcebdb2..66bcb9ad5872d1f6cac4ce9613806eb390be33af 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -983,9 +983,14 @@ aarch64_init_builtins (void)
   aarch64_init_crc32_builtins ();
   aarch64_init_builtin_rsqrt ();
 
-/* Initialize pointer authentication builtins which are backed by instructions
-   in NOP encoding space.  */
-  aarch64_init_pauth_hint_builtins ();
+  /* Initialize pointer authentication builtins which are backed by instructions
+     in NOP encoding space.
+
+     NOTE: these builtins are supposed to be used by libgcc unwinder only, as
+     there is no support on return address signing under ILP32, we don't
+     register them.  */
+  if (!TARGET_ILP32)
+    aarch64_init_pauth_hint_builtins ();
 }
 
 tree
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
index fda72a414f1df7e81785864e994681e3695852f1..f87c3d28d1edff473a787a39a436e57076f97508 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -1,6 +1,7 @@
 /* Testing return address signing where no combined instructions used.  */
 /* { dg-do compile } */
 /* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-require-effective-target lp64 } */
 
 int foo (int);
 
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
index 54fe47a69723d182c65941ddb73e2f1a5aa0af84..c5c1439b92e6637f85c47c6161cd797c0d68df25 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
@@ -1,6 +1,7 @@
 /* Testing return address signing where combined instructions used.  */
 /* { dg-do compile } */
 /* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-require-effective-target lp64 } */
 
 int foo (int);
 int bar (int, int);
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
index adc5effdded8900b2dfb68459883d399ebd91ac8..7d9ec6eebd1ce452013d2895a551671c59e98f0c 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_3.c
@@ -1,6 +1,7 @@
 /* Testing the disable of return address signing.  */
 /* { dg-do compile } */
 /* { dg-options "-O2 -msign-return-address=all" } */
+/* { dg-require-effective-target lp64 } */
 
 int bar (int, int);
 
diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h
index 7dd2549dbda501314112fa36b00f298342416a6a..76f7ea8a4e72133160f8caee95e31bcf9292c951 100644
--- a/libgcc/config/aarch64/aarch64-unwind.h
+++ b/libgcc/config/aarch64/aarch64-unwind.h
@@ -22,7 +22,7 @@ a copy of the GCC Runtime Library Exception along with this program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
-#ifndef AARCH64_UNWIND_H
+#if !defined (AARCH64_UNWIND_H) && !defined (__ILP32__)
 #define AARCH64_UNWIND_H
 
 #define DWARF_REGNUM_AARCH64_RA_STATE 34
@@ -86,4 +86,4 @@ aarch64_frob_update_context (struct _Unwind_Context *context,
   return;
 }
 
-#endif /* defined AARCH64_UNWIND_H */
+#endif /* defined AARCH64_UNWIND_H && defined __ILP32__ */
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
index fe74387992ab7f10c141d7b62f72a755878612c5..3f26eaf73de3116b538dc8ba0a99f12de939c5e5 100644
--- a/libgcc/unwind-dw2.c
+++ b/libgcc/unwind-dw2.c
@@ -1187,7 +1187,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
 	  break;
 
 	case DW_CFA_GNU_window_save:
-#ifdef __aarch64__
+#if defined (__aarch64__) && !defined (__ILP32__)
 	  /* This CFA is multiplexed with Sparc.  On AArch64 it's used to toggle
 	     return address signing status.  */
 	  fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset ^= 1;

Jiong Wang Jan. 20, 2017, 6:30 p.m. UTC | #6
On 20/01/17 18:23, Jiong Wang wrote:
>

> OK, the attached patch disable the building of pointer signing code in 

> libgcc

> on ILP32 mode, except the macro bit RA_A_SIGNED_BIT is still defined as I

> want to book this bit for ILP32 as LP64 in case we later enable ILP32 

> support.

>

> All pauth builtins are not registered as well for ILP32 mode as these 

> builtins

> are supposed to be used by libgcc unwinder code only.

>

> I also gated the three new testcases for return address signing using the

> following directive and verified it works under my dejagnu environment.

>

> { dg-require-effective-target lp64 }

>

> multilib cross build finished (lp64, ilp32), OK for trunk?

>

> BTW, the mode fix patch doesn't have conflict with this patch, we may

> still need it if we want to enable ILP32 support later.

>

> Thanks.

>

> gcc/

> 2017-01-20  Jiong Wang  <jiong.wang@arm.com>

>

>         * config/aarch64/aarch64-builtins.c (aarch64_init_builtins): 

> Don't

>         register pauth builtins for ILP32.

>

> libgcc/

>         * config/aarch64/aarch64-unwind.h: Restrict this file on LP64 

> only.

>         * unwind-dw2.c (execute_cfa_program):  Only multiplexing

>         DW_CFA_GNU_window_save for AArch64 LP64.

>

>


Missing testcase change in Changelog, added:

gcc/
2017-01-20  Jiong Wang  <jiong.wang@arm.com>

          * config/aarch64/aarch64-builtins.c (aarch64_init_builtins): Register
          register pauth builtins for LP64 only.
          * testsuite/gcc.target/aarch64/return_address_sign_1.c: Enable on LP64
          only.
          * testsuite/gcc.target/aarch64/return_address_sign_2.c: Likewise.
          * testsuite/gcc.target/aarch64/return_address_sign_3.c: Likewise.

libgcc/
          * config/aarch64/aarch64-unwind.h: Empty this file on ILP32.
          * unwind-dw2.c (execute_cfa_program):  Only multiplexing
          DW_CFA_GNU_window_save for AArch64 and LP64.
Richard Earnshaw (lists) Jan. 20, 2017, 6:49 p.m. UTC | #7
On 20/01/17 18:30, Jiong Wang wrote:
> 

> On 20/01/17 18:23, Jiong Wang wrote:

>>

>> OK, the attached patch disable the building of pointer signing code in

>> libgcc

>> on ILP32 mode, except the macro bit RA_A_SIGNED_BIT is still defined as I

>> want to book this bit for ILP32 as LP64 in case we later enable ILP32

>> support.

>>

>> All pauth builtins are not registered as well for ILP32 mode as these

>> builtins

>> are supposed to be used by libgcc unwinder code only.

>>

>> I also gated the three new testcases for return address signing using the

>> following directive and verified it works under my dejagnu environment.

>>

>> { dg-require-effective-target lp64 }

>>

>> multilib cross build finished (lp64, ilp32), OK for trunk?

>>

>> BTW, the mode fix patch doesn't have conflict with this patch, we may

>> still need it if we want to enable ILP32 support later.

>>

>> Thanks.

>>

>> gcc/

>> 2017-01-20  Jiong Wang  <jiong.wang@arm.com>

>>

>>         * config/aarch64/aarch64-builtins.c (aarch64_init_builtins):

>> Don't

>>         register pauth builtins for ILP32.

>>

>> libgcc/

>>         * config/aarch64/aarch64-unwind.h: Restrict this file on LP64

>> only.

>>         * unwind-dw2.c (execute_cfa_program):  Only multiplexing

>>         DW_CFA_GNU_window_save for AArch64 LP64.

>>

>>

> 

> Missing testcase change in Changelog, added:

> 

> gcc/

> 2017-01-20  Jiong Wang  <jiong.wang@arm.com>

> 

>          * config/aarch64/aarch64-builtins.c (aarch64_init_builtins):

> Register

>          register pauth builtins for LP64 only.

>          * testsuite/gcc.target/aarch64/return_address_sign_1.c: Enable

> on LP64

>          only.

>          * testsuite/gcc.target/aarch64/return_address_sign_2.c: Likewise.

>          * testsuite/gcc.target/aarch64/return_address_sign_3.c: Likewise.

> 

> libgcc/

>          * config/aarch64/aarch64-unwind.h: Empty this file on ILP32.

>          * unwind-dw2.c (execute_cfa_program):  Only multiplexing

>          DW_CFA_GNU_window_save for AArch64 and LP64.

> 

> 


The testsuite has its own ChangeLog file.

Otherwise OK.

R.
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h
index 9f37b9b432e5ed978032fa3356b138e2c7433760..ba5d052e9b694289574a68f156ca68b66ad6e2ee 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -71,4 +71,14 @@  enum aarch64_code_model {
   AARCH64_CMODEL_LARGE
 };
 
+/* Function types -msign-return-address should sign.  */
+enum aarch64_function_type {
+  /* Don't sign any function.  */
+  AARCH64_FUNCTION_NONE,
+  /* Non-leaf functions.  */
+  AARCH64_FUNCTION_NON_LEAF,
+  /* All functions.  */
+  AARCH64_FUNCTION_ALL
+};
+
 #endif
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 29a3bd71151aa4fb7c6728f0fb52e2f3f233f41d..632dd4768d82c340ae4e9b4a93206743756c06e7 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -386,6 +386,7 @@  void aarch64_emit_call_insn (rtx);
 void aarch64_register_pragmas (void);
 void aarch64_relayout_simd_types (void);
 void aarch64_reset_previous_fndecl (void);
+bool aarch64_return_address_signing_enabled (void);
 void aarch64_save_restore_target_globals (tree);
 
 /* Initialize builtins for SIMD intrinsics.  */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 9dd75b07498871db3e37b335dc8a3e1d66ec1d8b..002895a167ce0deb45a5c1726527651af18bb4df 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3117,6 +3117,22 @@  aarch64_gen_load_pair (machine_mode mode, rtx reg1, rtx mem1, rtx reg2,
     }
 }
 
+/* Return TRUE if return address signing should be enabled for one function,
+   otherwise return FALSE.  */
+
+bool
+aarch64_return_address_signing_enabled (void)
+{
+  /* This function should only be called after frame laid out.   */
+  gcc_assert (cfun->machine->frame.laid_out);
+
+  /* If signing scope is AARCH64_FUNCTION_NON_LEAF, we only sign a leaf function
+     if it's LR is pushed onto stack.  */
+  return (aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL
+	  || (aarch64_ra_sign_scope == AARCH64_FUNCTION_NON_LEAF
+	      && cfun->machine->frame.reg_offset[LR_REGNUM] >= 0));
+}
+
 /* Emit code to save the callee-saved registers from register number START
    to LIMIT to the stack at the location starting at offset START_OFFSET,
    skipping any write-back candidates if SKIP_WB is true.  */
@@ -3535,6 +3551,10 @@  aarch64_expand_prologue (void)
   unsigned reg2 = cfun->machine->frame.wb_candidate2;
   rtx_insn *insn;
 
+  /* Sign return address for functions.  */
+  if (aarch64_return_address_signing_enabled ())
+    emit_insn (gen_pacisp ());
+
   if (flag_stack_usage_info)
     current_function_static_stack_size = frame_size;
 
@@ -3670,6 +3690,16 @@  aarch64_expand_epilogue (bool for_sibcall)
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 
+  /* sibcall won't generate normally return, therefore we need to authenticate
+     at here.  !TARGET_ARMV8_3 disallows GCC to use combined authentication
+     instruction which we prefer, so we need to generate a seperate
+     authentication. eh_return path can't do combined authentication, as it will
+     do extra stack adjustment which updates CFA to EH handler's CFA while we
+     want to use the CFA of the function which calls eh_return.  */
+  if (aarch64_return_address_signing_enabled ()
+      && (for_sibcall || !TARGET_ARMV8_3 || crtl->calls_eh_return))
+    emit_insn (gen_autisp ());
+
   /* Stack adjustment for exception handler.  */
   if (crtl->calls_eh_return)
     {
@@ -8894,6 +8924,9 @@  aarch64_override_options (void)
     error ("Assembler does not support -mabi=ilp32");
 #endif
 
+  if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE && TARGET_ILP32)
+    error ("Return address signing is only supported on LP64");
+
   /* Make sure we properly set up the explicit options.  */
   if ((aarch64_cpu_string && valid_cpu)
        || (aarch64_tune_string && valid_tune))
@@ -9277,6 +9310,8 @@  static const struct aarch64_attribute_info aarch64_attributes[] =
   { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ },
   { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune,
      OPT_mtune_ },
+  { "sign-return-address", aarch64_attr_enum, false, NULL,
+     OPT_msign_return_address_ },
   { NULL, aarch64_attr_custom, false, NULL, OPT____ }
 };
 
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index bde42317f1bfd91a9d38a4cfa94d4cedd5246003..9b6f99dee3cecc0f15f24ec2375d3641fe03892d 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -67,6 +67,8 @@ 
 )
 
 (define_c_enum "unspec" [
+    UNSPEC_AUTI1716
+    UNSPEC_AUTISP
     UNSPEC_CASESI
     UNSPEC_CRC32B
     UNSPEC_CRC32CB
@@ -106,6 +108,8 @@ 
     UNSPEC_LD4_LANE
     UNSPEC_MB
     UNSPEC_NOP
+    UNSPEC_PACI1716
+    UNSPEC_PACISP
     UNSPEC_PRLG_STK
     UNSPEC_RBIT
     UNSPEC_SCVTF
@@ -135,6 +139,7 @@ 
     UNSPEC_RSQRTE
     UNSPEC_RSQRTS
     UNSPEC_NZCV
+    UNSPEC_XPACLRI
 ])
 
 (define_c_enum "unspecv" [
@@ -575,7 +580,14 @@ 
 (define_insn "*do_return"
   [(return)]
   ""
-  "ret"
+  {
+    if (aarch64_return_address_signing_enabled ()
+	&& TARGET_ARMV8_3
+	&& !crtl->calls_eh_return)
+      return "retaa";
+
+    return "ret";
+  }
   [(set_attr "type" "branch")]
 )
 
@@ -5341,6 +5353,31 @@ 
   [(set_attr "length" "0")]
 )
 
+;; Pointer authentication patterns are available for all architectures.  On
+;; pre-ARMv8.3-A architectures they are NOP.  This let the user write portable
+;; software which can get pointer authentication on new hardware while still
+;; runs correctly on old hardware though no pointer authentication protection.
+
+(define_insn "<pauth_mnem_prefix>sp"
+  [(set (reg:DI R30_REGNUM)
+	(unspec:DI [(reg:DI R30_REGNUM) (reg:DI SP_REGNUM)] PAUTH_LR_SP))]
+  ""
+  "hint\t<pauth_hint_num_a> // <pauth_mnem_prefix>asp";
+)
+
+(define_insn "<pauth_mnem_prefix>1716"
+  [(set (reg:DI R17_REGNUM)
+	(unspec:DI [(reg:DI R17_REGNUM) (reg:DI R16_REGNUM)] PAUTH_17_16))]
+  ""
+  "hint\t<pauth_hint_num_a> // <pauth_mnem_prefix>a1716";
+)
+
+(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 56b920dfe5abda1349c441c2188e5ac3ca05ab5a..54368848bbb249949921a3018d927c4bd61b1fbd 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 e2377c1cb2161c52ccadec3804294c494819cbb8..c59d31e5053a28fa31259341e82b6696f6ac8781 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 30bdcf07ad8b1bd086bbb87acb36fb0333944087..47250ebb149bbde021ef64eba8e96e35c2623284 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 we want to do return address signing on.  The behavior
+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 aa0ac8b41128483be53645b91bdcead096582e23..2792dbd0a2d0ed9e3f46237685f8ae65a5d8bcf5 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -14044,6 +14044,13 @@  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 we want to do return address signing on.  Permissible
+values are @samp{none}, @samp{none-leaf} and @samp{all}.  @samp{none} means
+return address signing is disabled.  @samp{non-leaf} enables it for non-leaf
+functions.  @samp{all} for all functions and is the default value.
+
 @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 0000000000000000000000000000000000000000..9a0332abd41ca6ae994e6ed72771fca8ee532cd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -0,0 +1,56 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -msign-return-address=all" } */
+
+int foo (int);
+int bar (int, 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 */
+}
+
+/* non-leaf function.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func4 (int a, int b, int c)
+{
+  /* paciasp */
+  return a + foo (b) + c;
+  /* retab */
+}
+
+int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+func4_disable (int a, int b, int c, int d)
+{
+  return c + bar (a, b) + d;
+}
+
+/* { dg-final { scan-assembler-times "autiasp" 3 } } */
+/* { dg-final { scan-assembler-times "paciasp" 4 } } */
+/* { dg-final { scan-assembler-times "retaa" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_scope_1.c b/gcc/testsuite/gcc.target/aarch64/return_address_sign_scope_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..6876e26a6a38eb670f8676f8f06dd74dfc18f41d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_scope_1.c
@@ -0,0 +1,55 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -msign-return-address=non-leaf" } */
+
+int foo (int);
+int bar (int, int);
+
+/* sibcall only.  */
+int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=non-leaf")))
+func1 (int a, int b)
+{
+  /* No authentication.  */
+  return foo (a + b);
+}
+
+/* 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)
+{
+  /* pacibsp */
+  return a + foo (b) + c;
+  /* autibsp */
+}
+
+/* non-leaf function.  */
+int __attribute__ ((target ("arch=armv8.3-a")))
+func4 (int a, int b, int c)
+{
+  /* pacibsp */
+  return a + foo (b) + c;
+  /* retab */
+}
+
+int __attribute__ ((target ("arch=armv8.3-a, sign-return-address=none")))
+func4_disable (int a, int b, int c, int d)
+{
+  return c + bar (a, b) + d;
+}
+
+/* { dg-final { scan-assembler-times "paciasp" 3 } } */
+/* { dg-final { scan-assembler-times "autiasp" 2 } } */
+/* { dg-final { scan-assembler-times "retaa" 1 } } */