In connection with this discussion https://gcc.gnu.org/ml/gcc/2015-02/msg00163.html
about bad behavior of -fisolate-erroneous-paths-dereference on nios2 bare-metal targets, I realized that we also had a serious problem on nios2-linux-gnu targets as well. The "trap" and "ctrapsi4" insns were both producing a "break 3" instruction, and the Nios II ABI for Linux Systems says:
"The break instruction in a user process might generate a SIGTRAP signal for that process, but is not required to. Userspace programs should not use the break instruction and userspace debuggers should not insert one."
....and, in fact, the recent 4.0 Linux kernel hangs on a "break" instruction, at least in our hardware configuration where we have a JTAG probe attached to the board to use for flashing the kernel, etc.
After some back-and-forth with Altera, we've decided to use "trap 3" here instead. They've agreed to document in a future version of the ABI that this triggers SIGILL, and there is a kernel patch available here to implement that:
https://github.com/altera-opensource/linux-socfpga/commit/baa54ab93c2e1ced7e54f9c021fe102c0d39c090 I've committed the attached patch to update things on the GCC side. -Sandra
2015-05-12 Sandra Loosemore <san...@codesourcery.com> gcc/ * config/nios2/nios2.md (trap, ctrapsi4): Use "trap" instead of "break". gcc/testsuite/ * gcc.target/nios2/nios2-trap-insn.c: Expect "trap" instead of "break". * gcc.target/nios2/nios2-stack-check-1.c: Likewise.
Index: gcc/config/nios2/nios2.md =================================================================== --- gcc/config/nios2/nios2.md (revision 223017) +++ gcc/config/nios2/nios2.md (working copy) @@ -1000,7 +1000,7 @@ (define_insn "trap" [(trap_if (const_int 1) (const_int 3))] "" - "break\\t3" + "trap\\t3" [(set_attr "type" "control")]) (define_insn "ctrapsi4" @@ -1009,7 +1009,7 @@ (match_operand:SI 2 "reg_or_0_operand" "rM")]) (match_operand 3 "const_int_operand" "i"))] "" - "b%R0\\t%z1, %z2, 1f\;break\\t%3\;1:" + "b%R0\\t%z1, %z2, 1f\;trap\\t%3\;1:" [(set_attr "type" "control") (set_attr "length" "8")]) Index: gcc/testsuite/gcc.target/nios2/nios2-trap-insn.c =================================================================== --- gcc/testsuite/gcc.target/nios2/nios2-trap-insn.c (revision 223017) +++ gcc/testsuite/gcc.target/nios2/nios2-trap-insn.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-final { scan-assembler "break\\t3" } } */ +/* { dg-final { scan-assembler "trap\\t3" } } */ /* Test the nios2 trap instruction */ void foo(void){ Index: gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c =================================================================== --- gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c (revision 223017) +++ gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c (working copy) @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-fstack-limit-register=et" } */ /* { dg-final { scan-assembler "bgeu\\tsp, et" } } */ -/* { dg-final { scan-assembler "break\\t3" } } */ +/* { dg-final { scan-assembler "trap\\t3" } } */ /* check stack checking */ void test() {