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:
+14
-2
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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" } } */
|
||||
@@ -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" } } */
|
||||
@@ -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])),
|
||||
|
||||
Reference in New Issue
Block a user