Bug 25967 - Add attribute naked for x86
Summary: Add attribute naked for x86
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 enhancement
Target Milestone: 8.0
Assignee: Uroš Bizjak
URL:
Keywords: patch
: 50242 52646 56209 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-01-26 08:00 UTC by Stefan
Modified: 2018-02-19 14:56 UTC (History)
6 users (show)

See Also:
Host:
Target: i?86-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-07-30 00:00:00


Attachments
Patch that implements naked attribute (740 bytes, patch)
2017-07-30 16:06 UTC, Uroš Bizjak
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan 2006-01-26 08:00:20 UTC
The naked attribute is ignored on the intel architecture (according to documentation). The MS VC++ compiler supports the naked attribute, and the functionality is used there quite frequent. 

A quick search on the internet shows that there is a lot of people waiting for this feature (including me). 

I hope this feature will be implemented soon. It's supported for ARM cpus and therefore I hope it won't be a problem to add support for x86 processors.
Comment 1 Andrew Pinski 2006-01-26 12:29:39 UTC
A quick question here.  Why not use a .s file instead?
Comment 2 Albert Cahalan 2006-09-26 04:31:20 UTC
(In reply to comment #1)
> A quick question here.  Why not use a .s file instead?

REASON #1

Sometimes people want to use --combine -fwhole-program, but the documentation for -fwhole-program starts with this:

"Assume that the current compilation unit represents whole program being compiled."

It is also implied, and stated elsewhere, that this only works for C. Thus it is apparently not allowed to have assembly, C++, Objective-C, Objective-C++, or weirder stuff.

REASON #2

Using a .s file does not allow the naked function to have static scope.

REASON #3

Even when it will work OK, the separate file is simply annoying. People naturally want to group functions together without being needlessly restricted.
Comment 3 Radoslaw Biernacki 2011-12-25 15:45:11 UTC
I will attach my comment to discussion.

I see the reason for naked attribute. I develop an embedded OS for small uC and
I would like to make a port for x86 Linux userspace. The scheduler for my OS
will behave as "fibres implementation". It will be similar to old fashioned
setcontext getcontext calls.

I need to compile following function:
void OS_NAKED OS_HOT os_context_switch(os_task_t *new_task)
{
   arch_contextstore_u();
   task_current = new_task;
   task_current->state = TASKSTATE_RUNNING;
   arch_contextrestore_u();
}

where arch_contextstore_u and arch_contextrestore_u are the architecture
depended function implemented by me in pure asm. arch_contextrestore_u will
make a return to address stored in task_current context (previously pushed on
stack by call (x86) instruction while calling os_context_switch).

The problem that I have is, that for x86 Linux environment, gcc does not
support the __attibute__ ((naked)). This attribute is supported on embedded
environments (bare metal) of all gcc ports that I found (like ARM, msp430-gcc,
avr-gcc etc).

So I'm the next person which waits for this implementation on x86 Linux.
Comment 4 Andrew Pinski 2011-12-25 17:18:17 UTC
*** Bug 50242 has been marked as a duplicate of this bug. ***
Comment 5 Andrew Pinski 2011-12-25 17:21:34 UTC
(In reply to comment #2)
> 
> REASON #1

--combine is gone.  -flto replaces it and it works correctly with a separate .s file.
> 
> REASON #2
> REASON #3

Then what about toplevel inline-asm which solves all the above reasons without much trouble.
Comment 6 Radoslaw Biernacki 2011-12-25 21:50:50 UTC
What is the main reason to not support the naked attribute in user space ?
In gcc documentation http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html there is is a statement that only reasonable usage of naked attribute is the inline assembly. Why gcc does not allow that by simply ignoring the naked attr ?

On x86 there is no need mess around with sp and bp pointers if I return from function by asm ret or jmp.
Comment 7 Andrew Pinski 2012-03-21 00:32:40 UTC
*** Bug 52646 has been marked as a duplicate of this bug. ***
Comment 8 Bryan O'Donoghue 2012-03-23 11:25:19 UTC
Guys.

I'd like to add to the calls for __attribute__((naked)) to be implemented on x86.

For the case of interrupts particularly, naked attribute would allow us to control the procedure prologue and epilogue more effectively and hence have less code and fewer cycles in order to service an IRQ on x86, which is clearly a good thing for everybody.

attribute naked is a highly useful and widely used gcc extension on ARM and all of the valid use-cases for naked on ARM are also valid reasons on x86. Particularly with attribute naked on x86 we could write a C function and stuff that directly into an interrupt gate - using macros for procedure prologue/epilogue as necessary for interrupts or exceptions (which have different stack arrangements on x86).

Most OS implementations have 256 separate functions as some sort of macro generated assembly - specifically to put into the interrupt gate.

These entry/exit functions then typically go to a lookup table and call into the 'real' interrupt handler.

That long process of indirection (and the unnecessary stub functions for the interrupt gate) could be gotten rid of, if gcc would implement naked attribute on x86, in the same fashion as on ARM.

Basically the developer should have the same freedom to implement solutions as appropriate on x86 as on ARM.
Comment 9 Andrew Pinski 2013-02-04 23:04:44 UTC
*** Bug 56209 has been marked as a duplicate of this bug. ***
Comment 10 Alexander Kobets 2013-02-05 12:51:00 UTC
(In reply to comment #1)
> A quick question here.  Why not use a .s file instead?

Quick answer. CC optimizes code better, especialy for instruction sheduling.
Comment 11 Anatol 2017-06-10 18:25:34 UTC
I need this feature in my project as well. And I was surprised to find this old feature request that has not been resolved yet. Is there any chance to see __naked__ implemented for x86?

As it turned out clang supports __naked__ attribute at x86. So we switched from GCC to CLANG as our main compiler. But I would really love to see GCC as an option for our project.
Comment 12 Daniel Santos 2017-07-29 05:34:13 UTC
For those interested in a work-around, you can define an __attribute__((used)) function and then within that function use inline assembly to declare your real function.  This can get messy depending upon how portable you need you your code to be, here is an example:

static void __attribute__((used)) dummy ()
{
  __asm__ ("\n"
	"	.globl myfunc\n"
#ifdef __ELF__
	"	.type myfunc,@function\n"
#endif
	"myfunc:\n"
	"	<your assembly here>\n"
	"	ret\n   # you must do your own ret.\n"
  )
}

I used this in the ms to system v function call tests: https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c#L172
Comment 13 Uroš Bizjak 2017-07-30 16:06:23 UTC
Created attachment 41862 [details]
Patch that implements naked attribute
Comment 14 Uroš Bizjak 2017-07-30 16:08:15 UTC
I'm testing the above patch. Using the patched compiler, the testcase that is mentioned by Daniel in Comment #12 can be changed to:

Index: testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c
===================================================================
--- testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c   (revision 250720)
+++ testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c   (working copy)
@@ -169,15 +169,9 @@
 
 #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 @@
        "       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])),
Comment 15 Uroš Bizjak 2017-07-30 16:47:57 UTC
Please also note this description from the gcc docs:

'naked'
     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
     'asm' statements can safely be included in naked functions (*note
     Basic Asm::).  While using extended 'asm' or a mixture of basic
     'asm' and C code may appear to work, they cannot be depended upon
     to work reliably and are not supported.
Comment 16 Uroš Bizjak 2017-07-30 20:30:49 UTC
Patch at [1].

[1] https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01968.html
Comment 17 uros 2017-07-31 10:23:13 UTC
Author: uros
Date: Mon Jul 31 10:22:41 2017
New Revision: 250736

URL: https://gcc.gnu.org/viewcvs?rev=250736&root=gcc&view=rev
Log:
	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.


Added:
    trunk/gcc/testsuite/gcc.target/i386/naked-1.c
    trunk/gcc/testsuite/gcc.target/i386/naked-2.c
    trunk/gcc/testsuite/gcc.target/i386/naked-3.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/doc/extend.texi
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/pr44290-1.c
    trunk/gcc/testsuite/gcc.dg/pr44290-2.c
    trunk/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c
Comment 18 Uroš Bizjak 2017-07-31 10:26:43 UTC
Implemented for gcc 8.
Comment 19 Daniel Santos 2017-07-31 10:38:41 UTC
(In reply to Uroš Bizjak from comment #18)
> Implemented for gcc 8.

Awesome!  There are actually a number of times over the years that I've wished this were implemented, thanks! :)
Comment 20 uros 2017-07-31 13:12:31 UTC
Author: uros
Date: Mon Jul 31 13:11:59 2017
New Revision: 250742

URL: https://gcc.gnu.org/viewcvs?rev=250742&root=gcc&view=rev
Log:
	PR target/25967
	* config/i386/i386.c (ix86_allocate_stack_slots_for_args):
	New function.
	(TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define.

testsuite/ChangeLog:

	PR target/25967
	* gcc.target/i386/naked-3.c (dg-options): Use -O0.
	(naked): Add attribute regparm(1) for x86_32 targets.
	Add integer argument.  Remove global "data" variable.
	(main): Pass integer argument to naked function.
	* gcc.target/i386/naked-4.c: New test.


Added:
    trunk/gcc/testsuite/gcc.target/i386/naked-4.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.target/i386/naked-3.c
Comment 21 Uroš Bizjak 2017-07-31 13:22:05 UTC
The above patch is needed to pass arguments to a naked function.

Please note that arguments can be reliably passed only in registers, so regparm convention is necessary for x86_32.

gcc.target/i386/naked-3.c and gcc.target/i386/naked-4.c testcases show function arguments and function result passing in action.
Comment 22 Aldy Hernandez 2017-09-13 16:07:47 UTC
Author: aldyh
Date: Wed Sep 13 16:07:16 2017
New Revision: 252190

URL: https://gcc.gnu.org/viewcvs?rev=252190&root=gcc&view=rev
Log:
	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.

Added:
    branches/range-gen2/gcc/testsuite/gcc.target/i386/naked-1.c
    branches/range-gen2/gcc/testsuite/gcc.target/i386/naked-2.c
    branches/range-gen2/gcc/testsuite/gcc.target/i386/naked-3.c
Modified:
    branches/range-gen2/gcc/ChangeLog
    branches/range-gen2/gcc/config/i386/i386.c
    branches/range-gen2/gcc/doc/extend.texi
    branches/range-gen2/gcc/testsuite/ChangeLog
    branches/range-gen2/gcc/testsuite/gcc.dg/pr44290-1.c
    branches/range-gen2/gcc/testsuite/gcc.dg/pr44290-2.c
    branches/range-gen2/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c
Comment 23 Aldy Hernandez 2017-09-13 16:08:47 UTC
Author: aldyh
Date: Wed Sep 13 16:08:15 2017
New Revision: 252195

URL: https://gcc.gnu.org/viewcvs?rev=252195&root=gcc&view=rev
Log:
	PR target/25967
	* config/i386/i386.c (ix86_allocate_stack_slots_for_args):
	New function.
	(TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define.

testsuite/ChangeLog:

	PR target/25967
	* gcc.target/i386/naked-3.c (dg-options): Use -O0.
	(naked): Add attribute regparm(1) for x86_32 targets.
	Add integer argument.  Remove global "data" variable.
	(main): Pass integer argument to naked function.
	* gcc.target/i386/naked-4.c: New test.

Added:
    branches/range-gen2/gcc/testsuite/gcc.target/i386/naked-4.c
Modified:
    branches/range-gen2/gcc/ChangeLog
    branches/range-gen2/gcc/config/i386/i386.c
    branches/range-gen2/gcc/testsuite/ChangeLog
    branches/range-gen2/gcc/testsuite/gcc.target/i386/naked-3.c