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.w...@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.w...@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.w...@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.w...@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;
 }

Reply via email to