info->calls_p = (!crtl->is_leaf || cfun->machine->ra_needs_full_frame);
info->rop_hash_size = 0;
- if (TARGET_POWER8
- && info->calls_p
- && DEFAULT_ABI == ABI_ELFv2
- && rs6000_rop_protect)
+ /* If we want ROP protection and this function makes a call, indicate
+ we need to create a stack slot to save the hashed return address in. */
+ if (rs6000_rop_protect
+ && info->calls_p)
info->rop_hash_size = 8;
- else if (rs6000_rop_protect && DEFAULT_ABI != ABI_ELFv2)
- {
- /* We can't check this in rs6000_option_override_internal since
- DEFAULT_ABI isn't established yet. */
- error ("%qs requires the ELFv2 ABI", "-mrop-protect");
- }
/* Determine if we need to save the condition code registers. */
if (save_reg_p (CR2_REGNO)
/* NOTE: The hashst isn't needed if we're going to do a sibcall,
but there's no way to know that here. Harmless except for
performance, of course. */
- if (TARGET_POWER8 && rs6000_rop_protect && info->rop_hash_size != 0)
+ if (info->rop_hash_size)
{
- gcc_assert (DEFAULT_ABI == ABI_ELFv2);
rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
rtx addr = gen_rtx_PLUS (Pmode, stack_ptr,
GEN_INT (info->rop_hash_save_offset));
/* The ROP hash check must occur after the stack pointer is restored
(since the hash involves r1), and is not performed for a sibcall. */
- if (TARGET_POWER8
- && rs6000_rop_protect
- && info->rop_hash_size != 0
+ if (info->rop_hash_size
&& epilogue_type != EPILOGUE_TYPE_SIBCALL)
{
- gcc_assert (DEFAULT_ABI == ABI_ELFv2);
rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
rtx addr = gen_rtx_PLUS (Pmode, stack_ptr,
GEN_INT (info->rop_hash_save_offset));
}
}
+ /* We only support ROP protection on certain targets. */
+ if (rs6000_rop_protect)
+ {
+ /* Disallow CPU targets we don't support. */
+ if (!TARGET_POWER8)
+ error ("%<-mrop-protect%> requires %<-mcpu=power8%> or later");
+
+ /* Disallow ABI targets we don't support. */
+ if (DEFAULT_ABI != ABI_ELFv2)
+ error ("%<-mrop-protect%> requires the ELFv2 ABI");
+ }
+
/* Initialize all of the registers. */
rs6000_init_hard_regno_mode_ok (global_init_p);
[(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m")
(unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
UNSPEC_HASHST))]
- "TARGET_POWER8 && rs6000_rop_protect"
+ "rs6000_rop_protect"
{
static char templ[32];
const char *p = rs6000_privileged ? "p" : "";
[(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r")
(match_operand:DI 1 "simple_offsettable_mem_operand" "m")]
UNSPEC_HASHCHK)]
- "TARGET_POWER8 && rs6000_rop_protect"
+ "rs6000_rop_protect"
{
static char templ[32];
const char *p = rs6000_privileged ? "p" : "";
--- /dev/null
+/* PR target/114759 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power7 -mrop-protect" } */
+
+/* Verify we emit an error if we use -mrop-protect with an unsupported cpu. */
+
+extern void foo (void);
+
+int
+bar (void)
+{
+ foo ();
+ return 5;
+}
+
+/* The correct line number is in the preamble to the error message, not
+ in the final line (which is all that dg-error inspects). Hence, we have
+ to tell dg-error to ignore the line number. */
+/* { dg-error "'-mrop-protect' requires '-mcpu=power8'" "PR114759" { target *-*-* } 0 } */