re PR target/25967 (Add attribute naked for x86)

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
This commit is contained in:
Uros Bizjak
2017-07-31 12:22:41 +02:00
parent cfdf6ff61b
commit 2ec580be15
10 changed files with 145 additions and 16 deletions
+14 -2
View 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.
+35
View 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);
}
/* 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
+11
View 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
+11
View 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
+2 -1
View 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))
+2 -1
View 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))
+14
View File
@@ -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" } } */
+14
View File
@@ -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" } } */
+39
View File
@@ -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 ();
}
@@ -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])),