With the following code fragment aarch64-attribute-naked.c : void __attribute__((naked)) dealwithit() { // Stuff removed above, below we assume that the 'naked' attribute // does the job and does not generate the usual 'ret' instruction asm("eret"::); } $ aarch64-linux-gnu-gcc -S aarch64-attribute-naked.c aarch64-attribute-naked.c:4:1: warning: 'naked' attribute directive ignored [-Wattributes] I have tried with a gcc-6.1.1, but simply as an example, this feature has never been ported to Aarch64, I think. As this attribute is supported for the legacy ARM target, it would be nice it the Aarch64 compiler could support it.
Confirmed. > > As this attribute is supported for the legacy ARM target, it would be nice > it the Aarch64 compiler could support it. s/legacy// patches welcome for further discussion ;) regards Ramana
I really think the naked attribute as not useful at all. I think it was a bad idea. Why not write a .s file which does what you want?
Andrew, (In reply to Andrew Pinski from comment #2) > I really think the naked attribute as not useful at all. I think it was a > bad idea. Why not write a .s file which does what you want? Well, from the discussions I read (for instance in bug #25967) before posting this, I was more or less expecting this remark. I agree that some arguments there are not valid. In a nutshell, I wrote quite a lot of tricky testing code (dealing manually with functions prologues/epilogues, etc..) for the ARM target (Ramana : please pardon the misused 'legacy' adjective) using this feature, and I would like to have a similar installment for ARM64. I am also generally simply bothered at the idea of putting decoration at the beginning of an assembly file, and starting from .c enables me to have the appropriate tags automatically emitted when I switch from target to target. --C
Created attachment 47119 [details] Proposed implementation of naked functions for aarch64 The change is quite simple (see the proposed patch). I hope it can be made, as I find naked functions quite useful, especially by allowing the use of certain C features in otherwise pure assembly code (e.g., offsetof, _Static_assert). Aesthetically, naked functions provide proper prototypes that are easier to follow, document and test.
(In reply to Elad Lahav from comment #4) > Created attachment 47119 [details] > Proposed implementation of naked functions for aarch64 > > The change is quite simple (see the proposed patch). I hope it can be made, > as I find naked functions quite useful, especially by allowing the use of > certain C features in otherwise pure assembly code (e.g., offsetof, > _Static_assert). Aesthetically, naked functions provide proper prototypes > that are easier to follow, document and test. Patches need to be sent to gcc-patches@gcc.gnu.org. Note, if you've not contributed to gcc before you'll also need to sort out a copyright assignment for the change (this is a non-trivial change).
(In reply to Richard Earnshaw from comment #5) > Patches need to be sent to gcc-patches@gcc.gnu.org. Note, if you've not > contributed to gcc before you'll also need to sort out a copyright > assignment for the change (this is a non-trivial change). Yes, I figured there is more process to submitting a change. At this point I just wanted to point out that it is a simple enough fix.
The problem with the naked attribute is usually it is not well defined. For things like interrupts functions and interrupt returns, there is always plain .s files. Interrupts usually save/restore all registers including the floating point ones. So they are large. The float point ones can get complex now with SVE too.
(In reply to Andrew Pinski from comment #7) > The problem with the naked attribute is usually it is not well defined. For > things like interrupts functions and interrupt returns, there is always > plain .s files. Interrupts usually save/restore all registers including the > floating point ones. So they are large. The float point ones can get > complex now with SVE too. I am actually using this facility to write kernel entry and exit routines. As I said, the advantage over pure assembly files is that you can use offsetof() and _Static_assert() when storing and loading registers to and from kernel data structures. You can also break up large chunks (such as storing and loading FPU registers) into inline functions. So far it looks like the compiler is doing the right thing with a combination of naked functions and inline functions: the code I get is exactly the inline assembly in these functions without any modifications or additions. If that is not guaranteed then it is indeed a problem.
While trying to write a simple test to demonstrate that the suggested patch works I ran into a couple of issues. First, here is the test code: #include <stdio.h> #include <stdlib.h> #if defined(__aarch64__) static long __attribute__((naked)) add_one(long a) { __asm__ __volatile__("add x0, x0, #1; ret"); } #elif defined(__arm__) static long __attribute__((naked)) add_one(long a) { __asm__ __volatile__("add r0, r0, #1; bx lr"); } #endif int main(int argc, char **argv) { long a = 0; if (argc > 1) { a = strtol(argv[1], NULL, 0); } a = add_one(a); printf("a=%ld\n", a); return 0; } 1. GCC emits a warning: /home/elahav/src/projects/aarch64_naked/aarch64_naked.c:15:1: warning: no return statement in function returning non-void [-Wreturn-type] } This is true for ARMv7 as well. I would not expect such a warning in a naked function. 2. With -O0 GCC puts an instruction before 'add': 0000000000000000 <add_one>: 0: f90007e0 str x0, [sp, #8] 4: 91000400 add x0, x0, #0x1 8: d65f03c0 ret c: d503201f nop The ARMv7 version is better, though still has extra baggage: 00000000 <add_one>: 0: f100 0001 add.w r0, r0, #1 4: 4770 bx lr 6: bf00 nop 8: 4618 mov r0, r3 With -O2 I get the expected results: 0000000000000000 <add_one>: 0: 91000400 add x0, x0, #0x1 4: d65f03c0 ret
(In reply to Elad Lahav from comment #9) Thanks for your patch proposal! > 1. GCC emits a warning: > /home/elahav/src/projects/aarch64_naked/aarch64_naked.c:15:1: warning: no > return statement in function returning non-void [-Wreturn-type] > } > This is true for ARMv7 as well. I would not expect such a warning in a > naked function. You may be interested in reading this : bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1836547
The number of targets supporting this attribute is large but the popular aarch64 somehow doesn't support it... I just run into a case where supporting this would be nice (https://reviews.llvm.org/D126343#3536318). % grep 'naked.*function attribute,' gcc/doc/extend.texi @cindex @code{naked} function attribute, ARC @cindex @code{naked} function attribute, ARM @cindex @code{naked} function attribute, AVR @cindex @code{naked} function attribute, C-SKY @cindex @code{naked} function attribute, MCORE @cindex @code{naked} function attribute, MSP430 @cindex @code{naked} function attribute, NDS32 @cindex @code{naked} function attribute, RISC-V @cindex @code{naked} function attribute, RL78 @cindex @code{naked} function attribute, RX @cindex @code{naked} function attribute, x86
(In reply to Fangrui Song from comment #11) > The number of targets supporting this attribute is large but the popular > aarch64 somehow doesn't support it... I just run into a case where > supporting this would be nice (https://reviews.llvm.org/D126343#3536318). That is not really a good use case really. a testcase is general purpose use case.
Please reconsider this. I ran into this when debugging pointer authentication not working correctly where I have to replace the prologue of a specific existing non-trivial C function. This would be way easier with this attribute and some inline assembly than replacing the whole function.
Adding a data point from https://discourse.llvm.org/t/hand-written-in-assembly-in-libc-setjmp-longjmp/73249/9. It's becoming a code portability issue when clang supports this function attribute on functions for aarch64 targets but GCC does not.
(In reply to Nick Desaulniers from comment #14) > Adding a data point from > https://discourse.llvm.org/t/hand-written-in-assembly-in-libc-setjmp-longjmp/ > 73249/9. > > It's becoming a code portability issue when clang supports this function > attribute on functions for aarch64 targets but GCC does not. Not really since you still can use a .s (or .S) file there .... That is how all other libc implement their setjmp/longjump and even correctly. Some will even use a generator to get the offsets and/or use static_asserts to make sure offsets stay correct.