re PR target/25967 (Add attribute naked for x86)
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 31 Jul 2017 10:22:41 +0000 (12:22 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 31 Jul 2017 10:22:41 +0000 (12:22 +0200)
PR target/25967
* config/i386/i386.c (ix86_function_naked): New function.
(ix86_can_use_return_insn_p): Return false for naked functions.
(ix86_expand_prologue): Skip prologue for naked functions.
(ix86_expand_epilogue): Skip epilogue for naked functions
and emit trap instruction.
(ix86_warn_func_return): New function.
(ix86_attribute_table): Add "naked" attribute specification.
(TARGET_WARN_FUNC_RETURN): Define.
* doc/extend.texi (x86 Function Attributes) <naked>: Document it.

testsuite/ChangeLog:

PR target/25967
* gcc.target/i386/naked-1.c: New test.
* gcc.target/i386/naked-2.c: Ditto.
* gcc.target/i386/naked-3.c: Ditto.
* gcc.target/x86_64/abi/ms-sysv/ms-sysv.c: Remove
do_test_body0 stub function, use attribute "naked" instead.
* gcc.dg/pr44290-1.c: Use naked_functions effective target.
* gcc.dg/pr44290-2.c: Ditto.

From-SVN: r250736

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr44290-1.c
gcc/testsuite/gcc.dg/pr44290-2.c
gcc/testsuite/gcc.target/i386/naked-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/naked-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/naked-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c

index ef0147633323a096fce95684aa8e52d3a5715cff..54e9a2e684168ae076d027ae0a9bd113750faa08 100644 (file)
@@ -1,7 +1,19 @@
+2017-07-31  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/25967
+       * config/i386/i386.c (ix86_function_naked): New function.
+       (ix86_can_use_return_insn_p): Return false for naked functions.
+       (ix86_expand_prologue): Skip prologue for naked functions.
+       (ix86_expand_epilogue): Skip epilogue for naked functions
+       and emit trap instruction.
+       (ix86_warn_func_return): New function.
+       (ix86_attribute_table): Add "naked" attribute specification.
+       (TARGET_WARN_FUNC_RETURN): Define.
+       * doc/extend.texi (x86 Function Attributes) <naked>: Document it.
+
 2017-07-31  Martin Liska  <mliska@suse.cz>
 
-       * gimple-pretty-print.c (dump_gimple_label): Never dump
-       BB info.
+       * gimple-pretty-print.c (dump_gimple_label): Never dump BB info.
        (dump_gimple_bb_header): Always dump BB info.
        (pp_cfg_jump): Do not append info about BB when dumping a jump.
 
index 47e2ae8ce2eb207d98ebbc1049de9046b7053cf2..9a35c995f26ab590b27ea7acde738e5539b9315b 100644 (file)
@@ -8748,6 +8748,15 @@ ix86_function_ms_hook_prologue (const_tree fn)
   return false;
 }
 
+static bool
+ix86_function_naked (const_tree fn)
+{
+  if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
+    return true;
+
+  return false;
+}
+
 /* Write the extra assembler code needed to declare a function properly.  */
 
 void
@@ -12249,6 +12258,9 @@ ix86_can_use_return_insn_p (void)
 {
   struct ix86_frame frame;
 
+  if (ix86_function_naked (current_function_decl))
+    return false;
+
   /* Don't use `ret' instruction in interrupt handler.  */
   if (! reload_completed
       || frame_pointer_needed
@@ -14327,6 +14339,9 @@ ix86_expand_prologue (void)
   bool sse_registers_saved;
   rtx static_chain = NULL_RTX;
 
+  if (ix86_function_naked (current_function_decl))
+    return;
+
   ix86_finalize_stack_realign_flags ();
 
   /* DRAP should not coexist with stack_realign_fp */
@@ -15184,6 +15199,13 @@ ix86_expand_epilogue (int style)
   bool using_drap;
   bool restore_stub_is_tail = false;
 
+  if (ix86_function_naked (current_function_decl))
+    {
+      /* The program should not reach this point.  */
+      emit_insn (gen_trap ());
+      return;
+    }
+
   ix86_finalize_stack_realign_flags ();
   frame = m->frame;
 
@@ -31652,6 +31674,14 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
                     LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
 }
+
+static bool
+ix86_warn_func_return (tree decl)
+{
+  /* Naked functions are implemented entirely in assembly, including the
+     return sequence, so suppress warnings about this.  */
+  return !ix86_function_naked (decl);
+}
 \f
 /* The following file contains several enumerations and data structures
    built from the definitions in i386-builtin-types.def.  */
@@ -46486,6 +46516,8 @@ static const struct attribute_spec ix86_attribute_table[] =
     ix86_handle_interrupt_attribute, false },
   { "no_caller_saved_registers", 0, 0, false, true, true,
     ix86_handle_no_caller_saved_registers_attribute, false },
+  { "naked", 0, 0, true, false, false,
+    ix86_handle_fndecl_attribute, false },
 
   /* End element.  */
   { NULL,        0, 0, false, false, false, NULL, false }
@@ -52722,6 +52754,9 @@ ix86_run_selftests (void)
 #undef TARGET_RETURN_POPS_ARGS
 #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
 
+#undef TARGET_WARN_FUNC_RETURN
+#define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
+
 #undef TARGET_LEGITIMATE_COMBINED_INSN
 #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
 
index 6934b4cde3e53ce2f073f2fe9f478b5c0dfdad16..34cb7d3dd22592b096a404ccf15b7f4bdbfa6f3b 100644 (file)
@@ -5370,6 +5370,17 @@ this function attribute to make GCC generate the ``hot-patching'' function
 prologue used in Win32 API functions in Microsoft Windows XP Service Pack 2
 and newer.
 
+@item naked
+@cindex @code{naked} function attribute, x86
+This attribute allows the compiler to construct the
+requisite function declaration, while allowing the body of the
+function to be assembly code. The specified function will not have
+prologue/epilogue sequences generated by the compiler. Only basic
+@code{asm} statements can safely be included in naked functions
+(@pxref{Basic Asm}). While using extended @code{asm} or a mixture of
+basic @code{asm} and C code may appear to work, they cannot be
+depended upon to work reliably and are not supported.
+
 @item regparm (@var{number})
 @cindex @code{regparm} function attribute, x86
 @cindex functions that are passed arguments in registers on x86-32
index f7e647c1863d9e22fdf70aa081f6d0ed237838c4..68ef6fc9365b8a93d403edc4f884413031f7d5cb 100644 (file)
@@ -1,3 +1,14 @@
+2017-07-31  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/25967
+       * gcc.target/i386/naked-1.c: New test.
+       * gcc.target/i386/naked-2.c: Ditto.
+       * gcc.target/i386/naked-3.c: Ditto.
+       * gcc.target/x86_64/abi/ms-sysv/ms-sysv.c: Remove
+       do_test_body0 stub function, use attribute "naked" instead.
+       * gcc.dg/pr44290-1.c: Use naked_functions effective target.
+       * gcc.dg/pr44290-2.c: Ditto.
+
 2017-07-31  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/81581
index c036db654f3f611c618e5ed8f5051a3e27321a5d..05d2454fc31851e5b83217cc6f92e03728c49722 100644 (file)
@@ -1,4 +1,5 @@
-/* { dg-do compile { target arm*-*-* avr-*-* mcore-*-* rx-*-* spu-*-* } } */
+/* { dg-do compile } */
+/* { dg-require-effective-target naked_functions } */
 /* { dg-options "-O2 -fdump-tree-optimized" } */
 
 static void __attribute__((naked))
index 17615366267a4fe7dd15bb6b1916bde7474d8811..073351091149a97f448c743cdf08c037f6cfdf65 100644 (file)
@@ -1,4 +1,5 @@
-/* { dg-do compile { target arm*-*-* avr-*-* mcore-*-* rx-*-* spu-*-* } } */
+/* { dg-do compile } */
+/* { dg-require-effective-target naked_functions } */
 /* { dg-options "-O2 -fdump-tree-optimized" } */
 
 static unsigned long __attribute__((naked))
diff --git a/gcc/testsuite/gcc.target/i386/naked-1.c b/gcc/testsuite/gcc.target/i386/naked-1.c
new file mode 100644 (file)
index 0000000..440dbe9
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+/* Verify that __attribute__((naked)) produces a naked function 
+   that does not use ret to return but traps at the end.  */
+void
+__attribute__((naked))
+foo (void)
+{
+  __asm__ ("# naked");
+}
+/* { dg-final { scan-assembler "# naked" } } */
+/* { dg-final { scan-assembler "ud2" } } */
+/* { dg-final { scan-assembler-not "ret" } } */
diff --git a/gcc/testsuite/gcc.target/i386/naked-2.c b/gcc/testsuite/gcc.target/i386/naked-2.c
new file mode 100644 (file)
index 0000000..adcd712
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+/* Verify that __attribute__((naked)) produces a naked function 
+   that does not construct a frame.  */
+void
+__attribute__((naked))
+foo (void)
+{
+  __asm__ ("# naked");
+}
+/* { dg-final { scan-assembler "# naked" } } */
+/* { dg-final { scan-assembler-not "push" } } */
+/* { dg-final { scan-assembler-not "pop" } } */
diff --git a/gcc/testsuite/gcc.target/i386/naked-3.c b/gcc/testsuite/gcc.target/i386/naked-3.c
new file mode 100644 (file)
index 0000000..845300d
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run { target *-*-linux* *-*-gnu* } } */
+/* { dg-options "-O2" } */
+
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+int data;
+
+/* Verify that naked function traps at the end.  */
+
+void
+__attribute__((naked, noinline, noclone))
+naked (void)
+{
+  if (data == 0x12345678)
+    return;
+  asm ("ret");
+}
+
+void handler (int i)
+{
+  exit (0);
+}
+
+int main ()
+{
+  struct sigaction s;
+
+  sigemptyset (&s.sa_mask);
+  s.sa_handler = handler;
+  s.sa_flags = 0;
+  sigaction (SIGILL, &s, NULL);
+
+  data = 0x12345678;
+  naked ();
+
+  abort ();
+}
index caf9e6b5debc4eb9021fff3cc4cbef15259428a2..5fdd1e20674b0e5b847961f584969b9d4b2d5816 100644 (file)
@@ -169,15 +169,9 @@ static const char *argv0;
 
 #define TEST_DATA_OFFSET(f)    ((int)__builtin_offsetof(struct test_data, f))
 
-void __attribute__((used))
-do_test_body0 (void)
-{
-  __asm__ ("\n"
-       "       .globl " ASMNAME(do_test_body) "\n"
-#ifdef __ELF__
-       "       .type " ASMNAME(do_test_body) ",@function\n"
-#endif
-       ASMNAME(do_test_body) ":\n"
+void __attribute__((naked))
+do_test_body (void)
+{__asm__ (
        "       # rax, r10 and r11 are usable here.\n"
        "\n"
        "       # Save registers.\n"
@@ -212,9 +206,6 @@ do_test_body0 (void)
        "       call    " ASMNAME(mem_to_regs) "\n"
        "\n"
        "       retq\n"
-#ifdef __ELF__
-       "       .size " ASMNAME(do_test_body) ",.-" ASMNAME(do_test_body) "\n"
-#endif
        ::
        "i"(TEST_DATA_OFFSET(regdata[REG_SET_SAVE])),
        "i"(TEST_DATA_OFFSET(regdata[REG_SET_INPUT])),