[gcc(refs/users/wschmidt/heads/dd2)] rs6000: Add ROP check slot to ELFv2 ABI stack layout

William Schmidt wschmidt@gcc.gnu.org
Wed Mar 17 21:08:12 GMT 2021


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

commit e2a596ddc14a214a1af9de216e71c6c111b33cb0
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date:   Wed Mar 17 16:07:36 2021 -0500

    rs6000: Add ROP check slot to ELFv2 ABI stack layout
    
    2021-03-17  Bill Schmidt  <wschmidt@linux.ibm.com>
    
    gcc/
            * config/rs6000/rs6000-internal.h (rs6000_stack): Add
            rop_check_save_offset and rop_check_size fields.
            * config/rs6000/rs6000-logue.c (rs6000_stack_info): Initialize
            rop_check_size and rop_check_save_offset; adjust ehrd_offset
            calculation; adjust save_size calculation.
            (debug_stack_info): Dump rop_check_size and
            rop_check_save_offset.

Diff:
---
 gcc/config/rs6000/rs6000-internal.h |  2 ++
 gcc/config/rs6000/rs6000-logue.c    | 39 ++++++++++++++++++++++++++++---------
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h
index 428a7861a98..8fc77ba6138 100644
--- a/gcc/config/rs6000/rs6000-internal.h
+++ b/gcc/config/rs6000/rs6000-internal.h
@@ -39,6 +39,7 @@ typedef struct rs6000_stack {
   int gp_save_offset;		/* offset to save GP regs from initial SP */
   int fp_save_offset;		/* offset to save FP regs from initial SP */
   int altivec_save_offset;	/* offset to save AltiVec regs from initial SP */
+  int rop_check_save_offset;	/* offset to save ROP check from initial SP */
   int lr_save_offset;		/* offset to save LR from initial SP */
   int cr_save_offset;		/* offset to save CR from initial SP */
   int vrsave_save_offset;	/* offset to save VRSAVE from initial SP */
@@ -53,6 +54,7 @@ typedef struct rs6000_stack {
   int gp_size;			/* size of saved GP registers */
   int fp_size;			/* size of saved FP registers */
   int altivec_size;		/* size of saved AltiVec registers */
+  int rop_check_size;		/* size of ROP check slot */
   int cr_size;			/* size to hold CR if not in fixed area */
   int vrsave_size;		/* size to hold VRSAVE */
   int altivec_padding_size;	/* size of altivec alignment padding */
diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
index b0ac183ceff..4b06e2a65b2 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -595,19 +595,21 @@ rs6000_savres_strategy (rs6000_stack_t *info,
 		+---------------------------------------+
 		| Parameter save area (+padding*) (P)	|  32
 		+---------------------------------------+
-		| Alloca space (A)			|  32+P
+		| Optional ROP check slot (R)		|  32+P
 		+---------------------------------------+
-		| Local variable space (L)		|  32+P+A
+		| Alloca space (A)			|  32+P+R
 		+---------------------------------------+
-		| Save area for AltiVec registers (W)	|  32+P+A+L
+		| Local variable space (L)		|  32+P+R+A
 		+---------------------------------------+
-		| AltiVec alignment padding (Y)		|  32+P+A+L+W
+		| Save area for AltiVec registers (W)	|  32+P+R+A+L
 		+---------------------------------------+
-		| Save area for GP registers (G)	|  32+P+A+L+W+Y
+		| AltiVec alignment padding (Y)		|  32+P+R+A+L+W
 		+---------------------------------------+
-		| Save area for FP registers (F)	|  32+P+A+L+W+Y+G
+		| Save area for GP registers (G)	|  32+P+R+A+L+W+Y
 		+---------------------------------------+
-	old SP->| back chain to caller's caller		|  32+P+A+L+W+Y+G+F
+		| Save area for FP registers (F)	|  32+P+R+A+L+W+Y+G
+		+---------------------------------------+
+	old SP->| back chain to caller's caller		|  32+P+R+A+L+W+Y+G+F
 		+---------------------------------------+
 
      * If the alloca area is present, the parameter save area is
@@ -714,6 +716,11 @@ rs6000_stack_info (void)
   info->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
 				 - info->first_altivec_reg_save);
 
+  if (DEFAULT_ABI == ABI_ELFv2 && rs6000_rop_protect)
+    info->rop_check_size = 8;
+  else
+    info->rop_check_size = 0;
+
   /* Does this function call anything (apart from sibling calls)?  */
   info->calls_p = (!crtl->is_leaf || cfun->machine->ra_needs_full_frame);
 
@@ -806,8 +813,14 @@ rs6000_stack_info (void)
 	  gcc_assert (info->altivec_size == 0
 		      || info->altivec_save_offset % 16 == 0);
 
-	  /* Adjust for AltiVec case.  */
-	  info->ehrd_offset = info->altivec_save_offset - ehrd_size;
+	  if (info->rop_check_size != 0)
+	    {
+	      info->rop_check_save_offset
+		= info->altivec_save_offset - info->rop_check_size;
+	      info->ehrd_offset = info->rop_check_save_offset - ehrd_size;
+	    }
+	  else
+	    info->ehrd_offset = info->altivec_save_offset - ehrd_size;
 	}
       else
 	info->ehrd_offset = info->gp_save_offset - ehrd_size;
@@ -849,6 +862,7 @@ rs6000_stack_info (void)
 				  + info->gp_size
 				  + info->altivec_size
 				  + info->altivec_padding_size
+				  + info->rop_check_size
 				  + ehrd_size
 				  + ehcr_size
 				  + info->cr_size
@@ -987,6 +1001,10 @@ debug_stack_info (rs6000_stack_t *info)
     fprintf (stderr, "\tvrsave_save_offset  = %5d\n",
 	     info->vrsave_save_offset);
 
+  if (info->rop_check_size)
+    fprintf (stderr, "\trop_check_save_offset = %5d\n",
+	     info->rop_check_save_offset);
+
   if (info->lr_save_p)
     fprintf (stderr, "\tlr_save_offset      = %5d\n", info->lr_save_offset);
 
@@ -1026,6 +1044,9 @@ debug_stack_info (rs6000_stack_t *info)
     fprintf (stderr, "\taltivec_padding_size= %5d\n",
 	     info->altivec_padding_size);
 
+  if (info->rop_check_size)
+    fprintf (stderr, "\trop_check_size      = %5d\n", info->rop_check_size);
+
   if (info->cr_size)
     fprintf (stderr, "\tcr_size             = %5d\n", info->cr_size);


More information about the Gcc-cvs mailing list