aarch64: fix return address access with pac [PR94891][PR94791]
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Tue, 2 Jun 2020 15:44:41 +0000 (16:44 +0100)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Mon, 13 Jul 2020 12:49:20 +0000 (13:49 +0100)
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.

gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h

index 865ad6744e1e3ce1832b7fa4c6217a21970503bc..839f801a31b8d0150143fbe36ea843947f6e0490 100644 (file)
@@ -578,6 +578,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);
index 17dbe673978b5d6cbf9c9ec9cbbcc205465d7e89..26cbeff9ac02cdaa75f15707049628e687c8bc86 100644 (file)
@@ -10825,6 +10825,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.  */
 
@@ -10833,7 +10851,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 ();
 }
 
 static void
index 4534e3717b40b1dfed9d5d62372437051ca3d3b1..d3e89d1789a23c2fa4d62744084adfdedac6a116 100644 (file)
@@ -1133,7 +1133,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);          \
   }