This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 29/03/16 17:49, Andre Vieira (lists) wrote: > On 29/01/16 17:07, Andre Vieira (lists) wrote: >> On 26/12/15 01:54, Thomas Preud'homme wrote: >>> [Sending on behalf of Andre Vieira] >>> >>> Hello, >>> >>> This patch extends support for the ARMv8-M Security Extensions >>> 'cmse_nonsecure_entry' attribute to safeguard against leak of >>> information through unbanked registers. >>> >>> When returning from a nonsecure entry function we clear all >>> caller-saved registers that are not used to pass return values, by >>> writing either the LR, in case of general purpose registers, or the >>> value 0, in case of FP registers. We use the LR to write to APSR and >>> FPSCR too. We currently only support 32 FP registers as in we only >>> clear D0-D7. >>> We currently do not support entry functions that pass arguments or >>> return variables on the stack and we diagnose this. This patch relies >>> on the existing code to make sure callee-saved registers used in >>> cmse_nonsecure_entry functions are saved and restored thus retaining >>> their nonsecure mode value, this should be happening already as it is >>> required by AAPCS. >>> >>> >>> *** gcc/ChangeLog *** >>> 2015-10-27 Andre Vieira <andre.simoesdiasvieira@arm.com> >>> Thomas Preud'homme <thomas.preudhomme@arm.com> >>> >>> * gcc/config/arm/arm.c (output_return_instruction): Clear >>> registers. >>> (thumb2_expand_return): Likewise. >>> (thumb1_expand_epilogue): Likewise. >>> (arm_expand_epilogue): Likewise. >>> (cmse_nonsecure_entry_clear_before_return): New. >>> * gcc/config/arm/arm.h (TARGET_DSP_ADD): New macro define. >>> * gcc/config/arm/thumb1.md (*epilogue_insns): Change length >>> attribute. >>> * gcc/config/arm/thumb2.md (*thumb2_return): Likewise. >>> >>> *** gcc/testsuite/ChangeLog *** >>> 2015-10-27 Andre Vieira <andre.simoesdiasvieira@arm.com> >>> Thomas Preud'homme <thomas.preudhomme@arm.com> >>> >>> * gcc.target/arm/cmse/cmse.exp: Test different multilibs >>> separate. >>> * gcc.target/arm/cmse/baseline/cmse-2.c: Test that registers >>> are cleared. >>> * gcc.target/arm/cmse/mainline/soft/cmse-5.c: New. >>> * gcc.target/arm/cmse/mainline/hard/cmse-5.c: New. >>> * gcc.target/arm/cmse/mainline/hard-sp/cmse-5.c: New. >>> * gcc.target/arm/cmse/mainline/softfp/cmse-5.c: New. >>> * gcc.target/arm/cmse/mainline/softfp-sp/cmse-5.c: New. >>> >>> >>> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h >>> index >>> f12e3c93bbe24b10ed8eee6687161826773ef649..b06e0586a3da50f57645bda13629bc4dbd3d53b7 >>> 100644 >>> --- a/gcc/config/arm/arm.h >>> +++ b/gcc/config/arm/arm.h >>> @@ -230,6 +230,9 @@ extern void >>> (*arm_lang_output_object_attributes_hook)(void); >>> /* Integer SIMD instructions, and extend-accumulate instructions. */ >>> #define TARGET_INT_SIMD \ >>> (TARGET_32BIT && arm_arch6 && (arm_arch_notm || arm_arch7em)) >>> +/* Parallel addition and subtraction instructions. */ >>> +#define TARGET_DSP_ADD \ >>> + (TARGET_ARM_ARCH >= 6 && (arm_arch_notm || arm_arch7em)) >>> >>> /* Should MOVW/MOVT be used in preference to a constant pool. */ >>> #define TARGET_USE_MOVT \ >>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c >>> index >>> e530b772e3cc053c16421a2a2861d815d53ebb01..0700478ca38307f35d0cb01f83ea182802ba28fa >>> 100644 >>> --- a/gcc/config/arm/arm.c >>> +++ b/gcc/config/arm/arm.c >>> @@ -19755,6 +19755,24 @@ output_return_instruction (rtx operand, bool >>> really_return, bool reverse, >>> default: >>> if (IS_CMSE_ENTRY (func_type)) >>> { >>> + char flags[12] = "APSR_nzcvq"; >>> + /* Check if we have to clear the 'GE bits' which is only >>> used if >>> + parallel add and subtraction instructions are available. */ >>> + if (TARGET_DSP_ADD) >>> + { >>> + /* If so also clear the ge flags. */ >>> + flags[10] = 'g'; >>> + flags[11] = '\0'; >>> + } >>> + snprintf (instr, sizeof (instr), "msr%s\t%s, %%|lr", >>> conditional, >>> + flags); >>> + output_asm_insn (instr, & operand); >>> + if (TARGET_HARD_FLOAT && TARGET_VFP) >>> + { >>> + snprintf (instr, sizeof (instr), "vmsr%s\tfpscr, %%|lr", >>> + conditional); >>> + output_asm_insn (instr, & operand); >>> + } >>> snprintf (instr, sizeof (instr), "bxns%s\t%%|lr", >>> conditional); >>> } >>> /* Use bx if it's available. */ >>> @@ -23999,6 +24017,17 @@ thumb_pop (FILE *f, unsigned long mask) >>> static void >>> thumb1_cmse_nonsecure_entry_return (FILE *f, int >>> reg_containing_return_addr) >>> { >>> + char flags[12] = "APSR_nzcvq"; >>> + /* Check if we have to clear the 'GE bits' which is only used if >>> + parallel add and subtraction instructions are available. */ >>> + if (TARGET_DSP_ADD) >>> + { >>> + flags[10] = 'g'; >>> + flags[11] = '\0'; >>> + } >>> + asm_fprintf (f, "\tmsr\t%s, %r\n", flags, reg_containing_return_addr); >>> + if (TARGET_HARD_FLOAT && TARGET_VFP) >>> + asm_fprintf (f, "\tvmsr\tfpscr, %r\n", reg_containing_return_addr); >>> asm_fprintf (f, "\tbxns\t%r\n", reg_containing_return_addr); >>> } >>> >>> @@ -25140,6 +25169,139 @@ thumb1_expand_prologue (void) >>> cfun->machine->lr_save_eliminated = 0; >>> } >>> >>> +/* Clear caller saved registers not used to pass return values and >>> leaked >>> + condition flags before exiting a cmse_nonsecure_entry function. */ >>> + >>> +void >>> +cmse_nonsecure_entry_clear_before_return (void) >>> +{ >>> + uint64_t to_clear_mask; >>> + int regno, maxregno = IP_REGNUM; >>> + tree result_type; >>> + rtx result_rtl; >>> + >>> + to_clear_mask = (1LL << (NUM_ARG_REGS)) - 1; >>> + to_clear_mask |= (1LL << IP_REGNUM); >>> + /* If we are not dealing with -mfloat-abi=softfp we will need to >>> clear VFP >>> + registers. We also check TARGET_VFP to make sure these are >>> present. */ >>> + if (TARGET_HARD_FLOAT && TARGET_VFP) >>> + { >>> + uint64_t float_mask = (1LL << (D7_VFP_REGNUM + 1)) - 1; >>> + float_mask &= ~((1LL << FIRST_VFP_REGNUM) - 1); >>> + to_clear_mask |= float_mask; >>> + maxregno = LAST_VFP_REGNUM; >>> + } >>> + >>> + /* If the user has defined registers to be caller saved, these are >>> no longer >>> + restored by the function before returning and must thus be >>> cleared for >>> + security purposes. */ >>> + for (regno = NUM_ARG_REGS; regno < LAST_VFP_REGNUM; regno++) >>> + { >>> + /* We leave registers traditionally used to pass arguments >>> untouched, >>> + since if these should not be made callee-saved by the user. */ >>> + if (regno >= FIRST_VFP_REGNUM && regno <= D7_VFP_REGNUM) >>> + continue; >>> + if (regno >= IP_REGNUM && regno <= PC_REGNUM) >>> + continue; >>> + if (call_used_regs[regno]) >>> + to_clear_mask |= (1LL << regno); >>> + } >>> + >>> + /* Make sure we do not clear the registers used to pass the result >>> in. */ >>> + result_type = TREE_TYPE (DECL_RESULT (current_function_decl)); >>> + if (!VOID_TYPE_P (result_type)) >>> + { >>> + rtx reg; >>> + >>> + result_rtl = arm_function_value (result_type, >>> current_function_decl, 0); >>> + >>> + /* No need to check that we return in registers, because we don't >>> + support returning on stack yet. */ >>> + switch (GET_MODE (result_rtl)) >>> + { >>> + case BLKmode: >>> + /* We are dealing with a return in multiple VFP registers. */ >>> + { >>> + int i; >>> + /* This should really only occur when dealing with an hard float >>> + abi. */ >>> + gcc_assert (TARGET_HARD_FLOAT_ABI && TARGET_VFP); >>> + >>> + for (i = 0; i < XVECLEN (result_rtl, 0); i++) >>> + { >>> + reg = XEXP (XVECEXP (result_rtl, 0, i), 0); >>> + gcc_assert (REG_P (reg)); >>> + /* If we are dealing with DF mode, make sure you don't clear >>> + either registers it addresses. */ >>> + if (GET_MODE (reg) == DFmode) >>> + to_clear_mask &= ~(1LL << (REGNO (reg) + 1)); >>> + to_clear_mask &= ~(1LL << REGNO (reg)); >>> + } >>> + } >>> + break; >>> + case DImode: >>> + to_clear_mask &= ~2; /* Don't clear r0 and r1. */ >>> + case SImode: >>> + to_clear_mask &= ~1; /* Don't clear r0. */ >>> + break; >>> + case DFmode: >>> + /* If we have -mfloat-abi=hard, do not clear registers used to >>> pass >>> + return value. */ >>> + if (TARGET_HARD_FLOAT_ABI && TARGET_VFP) >>> + /* Don't clear s0 and s1. */ >>> + to_clear_mask &= ~(1LL << (FIRST_VFP_REGNUM + 1)); >>> + else >>> + to_clear_mask &= ~2; /* Don't clear r0, r1. */ >>> + case SFmode: >>> + /* If we have -mfloat-abi=hard, do not clear registers used to >>> pass >>> + return value. */ >>> + if (TARGET_HARD_FLOAT_ABI && TARGET_VFP) >>> + /* Don't clear s0. */ >>> + to_clear_mask &= ~(1LL << FIRST_VFP_REGNUM); >>> + else >>> + to_clear_mask &= ~1; /* Don't clear r0. */ >>> + break; >>> + default: >>> + /* We are missing a mode, though AAPCS says we may only return in >>> + r0 and r1, s0-d15/d0-d7 so something went wrong here. */ >>> + gcc_unreachable (); >>> + break; >>> + } >>> + } >>> + >>> + for (regno = 0; regno <= maxregno; regno++) >>> + { >>> + if (!(to_clear_mask & (1LL << regno))) >>> + continue; >>> + >>> + /* If regno is a vfp register, even and its successor is also to >>> + be cleared, use vmov. */ >>> + if (IS_VFP_REGNUM (regno)) >>> + { >>> + if (TARGET_VFP_DOUBLE >>> + && VFP_REGNO_OK_FOR_DOUBLE (regno) >>> + && to_clear_mask & (1LL << (regno + 1))) >>> + { >>> + emit_move_insn (gen_rtx_REG (DFmode, regno++), >>> + CONST1_RTX (DFmode)); >>> + emit_use (gen_rtx_REG (DFmode, regno)); >>> + } >>> + else >>> + { >>> + emit_move_insn (gen_rtx_REG (SFmode, regno), >>> + CONST1_RTX (SFmode)); >>> + emit_use (gen_rtx_REG (SFmode, regno)); >>> + } >>> + } >>> + else >>> + { >>> + emit_move_insn (gen_rtx_REG (SImode, regno), >>> + gen_rtx_REG (SImode, LR_REGNUM)); >>> + emit_use (gen_rtx_REG (SImode, regno)); >>> + } >>> + } >>> +} >>> + >>> /* Generate pattern *pop_multiple_with_stack_update_and_return if >>> single >>> POP instruction can be generated. LR should be replaced by PC. All >>> the checks required are already done by USE_RETURN_INSN (). Hence, >>> @@ -25189,6 +25351,8 @@ thumb2_expand_return (bool simple_return) >>> } >>> else >>> { >>> + if (IS_CMSE_ENTRY (arm_current_func_type ())) >>> + cmse_nonsecure_entry_clear_before_return (); >>> emit_jump_insn (simple_return_rtx); >>> } >>> } >>> @@ -25247,6 +25411,10 @@ thumb1_expand_epilogue (void) >>> >>> if (! df_regs_ever_live_p (LR_REGNUM)) >>> emit_use (gen_rtx_REG (SImode, LR_REGNUM)); >>> + >>> + /* Clear all caller-saved regs that are not used to return. */ >>> + if (IS_CMSE_ENTRY (arm_current_func_type ())) >>> + cmse_nonsecure_entry_clear_before_return (); >>> } >>> >>> /* Epilogue code for APCS frame. */ >>> @@ -25681,6 +25849,14 @@ arm_expand_epilogue (bool really_return) >>> stack_pointer_rtx, stack_pointer_rtx); >>> } >>> >>> + /* Clear all caller-saved regs that are not used to return. */ >>> + if (IS_CMSE_ENTRY (arm_current_func_type ())) >>> + { >>> + /* CMSE_ENTRY always returns! */ >>> + gcc_assert (really_return); >>> + cmse_nonsecure_entry_clear_before_return (); >>> + } >>> + >>> if (!really_return) >>> return; >>> >>> diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md >>> index >>> d2a0420a2e9c71bb954d134fb88a86d694cf786d..cdcf397b0cab0ea7f246ad830ad28b07fed71d8b >>> 100644 >>> --- a/gcc/config/arm/thumb1.md >>> +++ b/gcc/config/arm/thumb1.md >>> @@ -1757,8 +1757,15 @@ >>> "* >>> return thumb1_unexpanded_epilogue (); >>> " >>> - ; Length is absolute worst case >>> - [(set_attr "length" "44") >>> + ; Length is absolute worst case, when using CMSE and if this is an >>> entry >>> + ; function an extra 4 (msr) to 8 (vmsr) extra might be added. >>> + [(set (attr "length") >>> + (if_then_else >>> + (match_test "IS_CMSE_ENTRY (arm_current_func_type ())") >>> + (if_then_else (match_test "TARGET_HARD_FLOAT && TARGET_VFP") >>> + (const_int 52) >>> + (const_int 48)) >>> + (const_int 44))) >>> (set_attr "type" "block") >>> ;; We don't clobber the conditions, but the potential length of this >>> ;; operation is sufficient to make conditionalizing the sequence >>> diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md >>> index >>> a724752a39cf2862c68a53ef28a239de2ae1ed96..0c07df91fe8844a7e7437ef5b7f00f74815d63f4 >>> 100644 >>> --- a/gcc/config/arm/thumb2.md >>> +++ b/gcc/config/arm/thumb2.md >>> @@ -1106,7 +1106,15 @@ >>> "TARGET_THUMB2" >>> "* return output_return_instruction (const_true_rtx, true, false, >>> true);" >>> [(set_attr "type" "branch") >>> - (set_attr "length" "4")] >>> + ; If this is a return from a cmse_nonsecure_entry function then >>> code will be >>> + ; added to clear the APSR and potentially the FPSCR if VFP is >>> available, so >>> + ; we adapt the length accordingly. >>> + (set (attr "length") >>> + (if_then_else (match_test "IS_CMSE_ENTRY (arm_current_func_type >>> ())") >>> + (if_then_else (match_test "TARGET_HARD_FLOAT && TARGET_VFP") >>> + (const_int 12) >>> + (const_int 8)) >>> + (const_int 4)))] >>> ) >>> >>> (define_insn_and_split "thumb2_eh_return" >>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-2.c >>> b/gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-2.c >>> new file mode 100644 >>> index >>> 0000000000000000000000000000000000000000..7cef73372fd5f5be080bdfe30999694564deaa9a >>> >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/baseline/cmse-2.c >>> @@ -0,0 +1,18 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-require-effective-target arm_arch_v8m_base_ok } */ >>> +/* { dg-add-options arm_arch_v8m_base } */ >>> +/* { dg-options "-mcmse" } */ >>> + >>> +extern float bar (void); >>> + >>> +float __attribute__ ((cmse_nonsecure_entry)) >>> +foo (void) >>> +{ >>> + return bar (); >>> +} >>> +/* { dg-final { scan-assembler "mov\tr1, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr2, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr3, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tip, lr" } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, r1" } } */ >>> +/* { dg-final { scan-assembler "bxns\tr1" } } */ >>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp >>> b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp >>> index >>> 6d4bfec1d12bc575218e0b8c33559d0a4da9ec70..592349ad07257f8074f9443a599ae08c36136a80 >>> 100644 >>> --- a/gcc/testsuite/gcc.target/arm/cmse/cmse.exp >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse.exp >>> @@ -38,6 +38,26 @@ set LTO_TORTURE_OPTIONS "" >>> gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \ >>> "" $DEFAULT_CFLAGS >>> >>> +if {[check_effective_target_arm_arch_v8m_base_ok]} then { >>> + # Baseline only >>> + gcc-dg-runtest [lsort [glob $srcdir/$subdir/baseline/*.c]] \ >>> + "" $DEFAULT_CFLAGS >>> +} >>> + >>> +if {[check_effective_target_arm_arch_v8m_main_ok]} then { >>> + # Mainline -mfloat-abi=soft >>> + gcc-dg-runtest [lsort [glob $srcdir/$subdir/mainline/soft/*.c]] \ >>> + "-mfloat-abi=soft" $DEFAULT_CFLAGS >>> + gcc-dg-runtest [lsort [glob $srcdir/$subdir/mainline/softfp/*.c]] \ >>> + "" $DEFAULT_CFLAGS >>> + gcc-dg-runtest [lsort [glob >>> $srcdir/$subdir/mainline/softfp-sp/*.c]] \ >>> + "" $DEFAULT_CFLAGS >>> + gcc-dg-runtest [lsort [glob $srcdir/$subdir/mainline/hard/*.c]] \ >>> + "" $DEFAULT_CFLAGS >>> + gcc-dg-runtest [lsort [glob $srcdir/$subdir/mainline/hard-sp/*.c]] \ >>> + "" $DEFAULT_CFLAGS >>> +} >>> + >>> set LTO_TORTURE_OPTIONS ${saved-lto_torture_options} >>> set dg-do-what-default ${saved-dg-do-what-default} >>> >>> diff --git >>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-5.c >>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-5.c >>> new file mode 100644 >>> index >>> 0000000000000000000000000000000000000000..ab607aa1b7210acc7983bfb401e95117eb8c0d17 >>> >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/hard-sp/cmse-5.c >>> @@ -0,0 +1,37 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-require-effective-target arm_arch_v8m_main_ok } */ >>> +/* { dg-add-options arm_arch_v8m_main } */ >>> +/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" >>> {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */ >>> +/* { dg-skip-if "Skip these if testing double precision" {*-*-*} >>> {"-mfpu=fpv[4-5]-d16"} {""} } */ >>> +/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-sp-d16" } */ >>> + >>> +extern float bar (void); >>> + >>> +float __attribute__ ((cmse_nonsecure_entry)) >>> +foo (void) >>> +{ >>> + return bar (); >>> +} >>> +/* { dg-final { scan-assembler "mov\tr0, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr1, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr2, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr3, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tip, lr" } } */ >>> +/* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts2, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts3, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts4, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts5, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts6, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts7, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts8, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts9, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts10, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts11, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts12, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts13, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts14, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts15, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { >>> arm_arch_v8m_main_ok && { ! arm_dsp } } } } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target { >>> arm_arch_v8m_main_ok && arm_dsp } } } } */ >>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-5.c >>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-5.c >>> new file mode 100644 >>> index >>> 0000000000000000000000000000000000000000..5ed7e1d6404b8f17d630895eb06df5921a1a965f >>> >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/hard/cmse-5.c >>> @@ -0,0 +1,30 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-require-effective-target arm_arch_v8m_main_ok } */ >>> +/* { dg-add-options arm_arch_v8m_main } */ >>> +/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" >>> {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=softfp } {""} } */ >>> +/* { dg-skip-if "Skip these if testing single precision" {*-*-*} >>> {"-mfpu=*-sp-*"} {""} } */ >>> +/* { dg-options "-mcmse -mfloat-abi=hard -mfpu=fpv5-d16" } */ >>> + >>> +extern float bar (void); >>> + >>> +float __attribute__ ((cmse_nonsecure_entry)) >>> +foo (void) >>> +{ >>> + return bar (); >>> +} >>> +/* { dg-final { scan-assembler "mov\tr0, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr1, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr2, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr3, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tip, lr" } } */ >>> +/* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td1, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td2, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td3, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td4, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td5, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td6, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td7, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { >>> arm_arch_v8m_main_ok && { ! arm_dsp } } } } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target { >>> arm_arch_v8m_main_ok && arm_dsp } } } } */ >>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-5.c >>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-5.c >>> new file mode 100644 >>> index >>> 0000000000000000000000000000000000000000..d24683f52eba11df5b41eef0e5a8e365fb206fe8 >>> >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/soft/cmse-5.c >>> @@ -0,0 +1,22 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-require-effective-target arm_arch_v8m_main_ok } */ >>> +/* { dg-add-options arm_arch_v8m_main } */ >>> +/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" >>> {*-*-*} {"-mfloat-abi=hard" -mfloat-abi=softfp } {""} } */ >>> +/* { dg-options "-mcmse -mfloat-abi=soft" } */ >>> + >>> +extern float bar (void); >>> + >>> +float __attribute__ ((cmse_nonsecure_entry)) >>> +foo (void) >>> +{ >>> + return bar (); >>> +} >>> + >>> +/* { dg-final { scan-assembler "mov\tr1, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr2, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr3, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tip, lr" } } */ >>> +/* { dg-final { scan-assembler-not "vmov" } } */ >>> +/* { dg-final { scan-assembler-not "vmsr" } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { >>> arm_arch_v8m_main_ok && { ! arm_dsp } } } } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target { >>> arm_arch_v8m_main_ok && arm_dsp } } } } */ >>> diff --git >>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/softfp-sp/cmse-5.c >>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/softfp-sp/cmse-5.c >>> new file mode 100644 >>> index >>> 0000000000000000000000000000000000000000..c22775ace8361729c36130422475522fbaca05b5 >>> >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/softfp-sp/cmse-5.c >>> @@ -0,0 +1,39 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-require-effective-target arm_arch_v8m_main_ok } */ >>> +/* { dg-add-options arm_arch_v8m_main } */ >>> +/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" >>> {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */ >>> +/* { dg-skip-if "Skip these if testing double precision" {*-*-*} >>> {"-mfpu=fpv[4-5]-d16"} {""} } */ >>> +/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-sp-d16" } */ >>> + >>> +extern float bar (void); >>> + >>> +float __attribute__ ((cmse_nonsecure_entry)) >>> +foo (void) >>> +{ >>> + return bar (); >>> +} >>> +/* { dg-final { scan-assembler "__acle_se_foo:" } } */ >>> +/* { dg-final { scan-assembler-not "mov\tr0, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr1, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr2, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr3, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tip, lr" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts0, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts2, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts3, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts4, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts5, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts6, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts7, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts8, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts9, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts10, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts11, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts12, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts13, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts14, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f32\ts15, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { >>> arm_arch_v8m_main_ok && { ! arm_dsp } } } } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target { >>> arm_arch_v8m_main_ok && arm_dsp } } } } */ >>> +/* { dg-final { scan-assembler "bxns" } } */ >>> diff --git >>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-5.c >>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-5.c >>> new file mode 100644 >>> index >>> 0000000000000000000000000000000000000000..28b05c391081bd42407b4e56a1e84daa549fa06e >>> >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/softfp/cmse-5.c >>> @@ -0,0 +1,31 @@ >>> +/* { dg-do compile } */ >>> +/* { dg-require-effective-target arm_arch_v8m_main_ok } */ >>> +/* { dg-add-options arm_arch_v8m_main } */ >>> +/* { dg-skip-if "Do not combine float-abi= hard | soft | softfp" >>> {*-*-*} {"-mfloat-abi=soft" -mfloat-abi=hard } {""} } */ >>> +/* { dg-skip-if "Skip these if testing single precision" {*-*-*} >>> {"-mfpu=*-sp-*"} {""} } */ >>> +/* { dg-options "-mcmse -mfloat-abi=softfp -mfpu=fpv5-d16" } */ >>> + >>> +extern float bar (void); >>> + >>> +float __attribute__ ((cmse_nonsecure_entry)) >>> +foo (void) >>> +{ >>> + return bar (); >>> +} >>> +/* { dg-final { scan-assembler "__acle_se_foo:" } } */ >>> +/* { dg-final { scan-assembler-not "mov\tr0, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr1, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr2, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tr3, lr" } } */ >>> +/* { dg-final { scan-assembler "mov\tip, lr" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td0, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td1, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td2, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td3, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td4, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td5, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td6, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "vmov\.f64\td7, #1\.0" } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { >>> arm_arch_v8m_main_ok && { ! arm_dsp } } } } } */ >>> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target { >>> arm_arch_v8m_main_ok && arm_dsp } } } } */ >>> +/* { dg-final { scan-assembler "bxns" } } */ >>> >>> We welcome any comments. >>> >>> Cheers, >>> >>> Andre >>> >> Ping. >> > Hi there, > > This is an updated version of the previous patch to clear the unused > bits when returning a compound type. As per the ABI these have undefined > values and thus may leak security sensitive information. > > Any comments? > > Cheers, > Andre > > *** ChangeLog *** > 2016-03-29 Andre Vieira <andre.simoesdiasvieira@arm.com> > Thomas Preud'homme <thomas.preudhomme@arm.com> > > * gcc/config/arm/arm.c (output_return_instruction): Clear > registers. > (thumb2_expand_return): Likewise. > (thumb1_expand_epilogue): Likewise. > (arm_expand_epilogue): Likewise. > (cmse_nonsecure_entry_clear_before_return): New. > * gcc/config/arm/thumb1.md (*epilogue_insns): Change length > attribute. > * gcc/config/arm/thumb2.md (*thumb2_return): Likewise. > > *** gcc/testsuite/ChangeLog *** > 2016-03-29 Andre Vieira <andre.simoesdiasvieira@arm.com> > Thomas Preud'homme <thomas.preudhomme@arm.com> > > * gcc.target/arm/cmse/cmse.exp: Test different multilibs separate. > * gcc.target/arm/cmse/struct-1.c: New. > * gcc.target/arm/cmse/bitfield-1.c: New. > * gcc.target/arm/cmse/bitfield-2.c: New. > * gcc.target/arm/cmse/bitfield-3.c: New. > * gcc.target/arm/cmse/baseline/cmse-2.c: Test that registers are > cleared. > * gcc.target/arm/cmse/mainline/soft/cmse-5.c: New. > * gcc.target/arm/cmse/mainline/hard/cmse-5.c: New. > * gcc.target/arm/cmse/mainline/hard-sp/cmse-5.c: New. > * gcc.target/arm/cmse/mainline/softfp/cmse-5.c: New. > * gcc.target/arm/cmse/mainline/softfp-sp/cmse-5.c: New. > Hi there, I realized that in the patch in https://gcc.gnu.org/ml/gcc-patches/2016-03/msg01524.html, that I left two mistakes in two of the testcases where I was doing a compile test instead of run test and within those two also noticed that I was using 'char' where I should've been using 'signed char', so heres a respun version. Any comments? Cheers, Andre *** gcc/ChangeLog *** 2016-03-30 Andre Vieira <andre.simoesdiasvieira@arm.com> Thomas Preud'homme <thomas.preudhomme@arm.com> * gcc/config/arm/arm.c (output_return_instruction): Clear registers. (thumb2_expand_return): Likewise. (thumb1_expand_epilogue): Likewise. (arm_expand_epilogue): Likewise. (cmse_nonsecure_entry_clear_before_return): New. * gcc/config/arm/thumb1.md (*epilogue_insns): Change length attribute. * gcc/config/arm/thumb2.md (*thumb2_return): Likewise. *** gcc/testsuite/ChangeLog *** 2016-03-30 Andre Vieira <andre.simoesdiasvieira@arm.com> Thomas Preud'homme <thomas.preudhomme@arm.com> * gcc.target/arm/cmse/cmse.exp: Test different multilibs separate. * gcc.target/arm/cmse/struct-1.c: New. * gcc.target/arm/cmse/bitfield-1.c: New. * gcc.target/arm/cmse/bitfield-2.c: New. * gcc.target/arm/cmse/bitfield-3.c: New. * gcc.target/arm/cmse/baseline/cmse-2.c: Test that registers are cleared. * gcc.target/arm/cmse/mainline/soft/cmse-5.c: New. * gcc.target/arm/cmse/mainline/hard/cmse-5.c: New. * gcc.target/arm/cmse/mainline/hard-sp/cmse-5.c: New. * gcc.target/arm/cmse/mainline/softfp/cmse-5.c: New. * gcc.target/arm/cmse/mainline/softfp-sp/cmse-5.c: New.
Attachment:
diff5
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |