[gcc(refs/vendors/ibm/heads/gcc-9-branch)] aarch64: fix return address access with pac [PR94891][PR94791]

Peter Bergner bergner@gcc.gnu.org
Fri Sep 4 19:23:39 GMT 2020


https://gcc.gnu.org/g:a70d5d81c41048556fd86eaa1036018a6bfba115

commit a70d5d81c41048556fd86eaa1036018a6bfba115
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Tue Jun 2 16:44:41 2020 +0100

    aarch64: fix return address access with pac [PR94891][PR94791]
    
    This is a big hammer fix for __builtin_return_address (PR target/94891)
    returning signed addresses (sometimes, depending on wether lr happens
    to be signed or not at the time of call which depends on optimizations),
    and similarly -pg may pass signed return address to _mcount
    (PR target/94791).
    
    At the time of return address expansion we don't know if it's signed or
    not so it is done unconditionally.
    
    2020-07-13  Szabolcs Nagy  <szabolcs.nagy@arm.com>
    
    gcc/ChangeLog:
    
            PR target/94891
            PR target/94791
            * config/aarch64/aarch64-protos.h (aarch64_return_addr_rtx): Declare.
            * config/aarch64/aarch64.c (aarch64_return_addr_rtx): New.
            (aarch64_return_addr): Use aarch64_return_addr_rtx.
            * config/aarch64/aarch64.h (PROFILE_HOOK): Likewise.
    
    (cherry picked from commit 463a54e5d4956143f81c1f23b91cbd2d93855741)

Diff:
---
 gcc/config/aarch64/aarch64-protos.h |  1 +
 gcc/config/aarch64/aarch64.c        | 20 +++++++++++++++++++-
 gcc/config/aarch64/aarch64.h        |  2 +-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index b9bfb281275..af2a17f0bf3 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -492,6 +492,7 @@ int aarch64_vec_fpconst_pow_of_2 (rtx);
 rtx aarch64_eh_return_handler_rtx (void);
 rtx aarch64_mask_from_zextract_ops (rtx, rtx);
 const char *aarch64_output_move_struct (rtx *operands);
+rtx aarch64_return_addr_rtx (void);
 rtx aarch64_return_addr (int, rtx);
 rtx aarch64_simd_gen_const_vector_dup (machine_mode, HOST_WIDE_INT);
 bool aarch64_simd_mem_operand_p (rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 35b5b2fd3a6..4bb16d125c6 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8425,6 +8425,24 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to)
   return cfun->machine->frame.frame_size;
 }
 
+
+/* Get return address without mangling.  */
+
+rtx
+aarch64_return_addr_rtx (void)
+{
+  rtx val = get_hard_reg_initial_val (Pmode, LR_REGNUM);
+  /* Note: aarch64_return_address_signing_enabled only
+     works after cfun->machine->frame.laid_out is set,
+     so here we don't know if the return address will
+     be signed or not.  */
+  rtx lr = gen_rtx_REG (Pmode, LR_REGNUM);
+  emit_move_insn (lr, val);
+  emit_insn (GEN_FCN (CODE_FOR_xpaclri) ());
+  return lr;
+}
+
+
 /* Implement RETURN_ADDR_RTX.  We do not support moving back to a
    previous frame.  */
 
@@ -8433,7 +8451,7 @@ aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
 {
   if (count != 0)
     return const0_rtx;
-  return get_hard_reg_initial_val (Pmode, LR_REGNUM);
+  return aarch64_return_addr_rtx ();
 }
 
 
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 772a9729688..0e9b79e23f0 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -968,7 +968,7 @@ typedef struct
 #define PROFILE_HOOK(LABEL)						\
   {									\
     rtx fun, lr;							\
-    lr = get_hard_reg_initial_val (Pmode, LR_REGNUM);			\
+    lr = aarch64_return_addr_rtx ();					\
     fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME);			\
     emit_library_call (fun, LCT_NORMAL, VOIDmode, lr, Pmode);		\
   }


More information about the Gcc-cvs mailing list