naked attribute

I propose to make the following change to clang.

In the presence of the "naked" attribute, in cases where clang would normally implicitly emit a "return" instruction, it should emit an "unreachable" instruction.

If someone explicitly puts a C/C++ "return" statement in the code, clang should do what it normally does.

The semantics of the "naked" attribute forbid the compiler from emitting a (implicit) return statement, prologue and epilogue code. The presumption is that there is only inline assembly in such a function but that is not a requirement but the programmer must know what he/she is doing and realize the rest of the above.

If this reasonable I'll file a clang bug and maybe fix it myself if it's obvious where to do this.

I propose to make the following change to clang.

In the presence of the "naked" attribute, in cases where clang would normally implicitly emit a "return" instruction, it should emit an "unreachable" instruction.

This seems pretty reasonable to me.

-Chris

This is a gcc extension so I am more comfortable doing what gcc does
when possible. gcc documents this extension as only being supported on
ARM, AVR, MCORE, RX and SPU, so users clearly depend on undocumented
behavior.

Now, given

__attribute__((naked)) void f(void) {
}

gcc (both 4.7 and 4.9) produce

f:
.cfi_startproc
ret
.cfi_endproc

Clang currently produces the IL

define void @f() #0 {
entry:
  ret void
}

(where #0 includes naked) and we then codegen it to

f:
.cfi_startproc
ret
.cfi_endproc

matching gcc. If we change the 'ret void' to 'unreachable', we codegen the IL to

f:
.cfi_startproc
.cfi_endproc

So I think we should keep the 'ret void'

Cheers,
Rafael

Hi Reed,

I propose to make the following change to clang.

In the presence of the "naked" attribute, in cases where clang would
normally implicitly emit a "return" instruction, it should emit an
"unreachable" instruction.

I'd have loved to if we were designing the attribute from scratch; I
think the semantics would definitely be better. Unfortunately GCC got
there first, and at least on AArch64 it also puts the implicit return
in. I'll check AArch32 at work tomorrow.

If so, there's a real risk of breaking compatibility if anyone
actually uses naked functions already. Not a fatal barrier, but one we
should consider carefully.

Tim.

A case for __attribute__((stark_naked))?

I am OK with adding such an attribute, but we should try to coordinate
with gcc, so that we don't end up with stark_naked and they add a
completely_naked or something :slight_smile:

Cheers,
Rafael

Interesting. This all conflicts with gcc documentation. When discussing the

When I use the latest code sourcery/Menor release of the ARM compiler I get no return statement. This claims to be 4.6.3

~/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin/arm-none-linux-gnueabi-gcc tnaked.c -S

void tnaked() __attribute__((naked));

void tnaked() {
}

tnaked:
     .fnstart
     @ Naked Function: prologue and epilogue provided by programmer.
     @ args = 0, pretend = 0, frame = 0
     @ frame_needed = 1, uses_anonymous_args = 0
     .fnend
     .size tnaked, .-tnaked
     .align 2
     .global tnonaked
     .type tnonaked, %function

Hi Reed,

Interesting. This all conflicts with gcc documentation.
Function Attributes (Using the GNU Compiler Collection (GCC))

Not if you read the two sections you quoted as applying only to AVR
(since they seem to come from the AVR-specific OS_main/OS_task
attributes).

It means GCC is inconsistent between targets over the behaviour, but
not necessarily inconsistent with its (sparse) documentation.

When I use the latest code sourcery/Menor release of the ARM compiler I get no return statement.

I seem to get the same for Linaro's Android toolchains, but my VPN is
playing up this evening so I can't check anything more solid until the
morning.

Of course, I have no idea about the other supported platforms.

Tim.

Lovely, so I guess this is architecture dependent. Any patch that
makes us more compatible with gcc in this area is welcome, so we need
to figure out which architectures get a ret and which ones get an
unreachable :frowning:

Cheers,
Rafael

Not all architectures support the naked attribute, even in gcc.
"Use this attribute on the ARM, AVR, MCORE, RX and SPU ports ..."

gcc 4.7 in the android toolkit for arm does not emit a return statement.

(building cross tool chains with gcc is a pain so that's why I at first just downloaded the gcc arm version from the mentor/code sourcery site).

fu@fu-G10IL:~/dev/test$ ~/dev/android-ndk-r8e/toolchains/arm-linux-androideabi-
4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -S tnaked.c

fu@fu-G10IL:~/dev/test$ cat tnaked.s
         .arch armv5te
         .fpu softvfp
         .eabi_attribute 20, 1
         .eabi_attribute 21, 1
         .eabi_attribute 23, 3
         .eabi_attribute 24, 1
         .eabi_attribute 25, 1
         .eabi_attribute 26, 2
         .eabi_attribute 30, 6
         .eabi_attribute 34, 0
         .eabi_attribute 18, 4
         .file "tnaked.c"
         .text
         .align 2
         .global tnaked
         .type tnaked, %function
tnaked:
         @ Naked Function: prologue and epilogue provided by programmer.
         @ args = 0, pretend = 0, frame = 0
         @ frame_needed = 1, uses_anonymous_args = 0
         .size tnaked, .-tnaked
         .align 2
         .global tnonaked
         .type tnonaked, %function
tnonaked:
         @ args = 0, pretend = 0, frame = 0
         @ frame_needed = 1, uses_anonymous_args = 0
         @ link register save eliminated.
         str fp, [sp, #-4]!
         add fp, sp, #0
         add sp, fp, #0
         ldmfd sp!, {fp}
         bx lr
         .size tnonaked, .-tnonaked
         .ident "GCC: (GNU) 4.7"
         .section .note.GNU-stack,"",%progbits

With my x86 version of gcc, I get a warning if I use the naked attribute that it's not supported. I have 4.4.3

I don't get the warning with clang.

Hi Tim,

Are you sure that AArch64 supports the naked attribute?

It's not on the official list of targets that support it in the gcc manual.

I think we are confusing things.

If you make a simple test case with a function that has nothing in it, you will likely see just a return instruction.

I've posted a question on the gcc developers list regarding the intent of naked functions but it makes no logical sense to me to emit a return instruction in a naked function.

You can emit the instruction yourself along with the inline asm code for the rest of your function.

gcc/llvm does not even know what flavor of return to emit.

Reed

I am working on a patch in this general direction because our naked
support doesn't match MSVC either. I am hoping to have something in
the next day or so to address this.

~Aaron

I seem to recall it in Visual Studio going back to the 5.0 days (late
1990s). For Microsoft, it was available on x86.

Is there still interest in the Windows compat stuff?

You can emit the instruction yourself along with the inline asm code for the
rest of your function.

Good, this is starting to look I bit saner. I can confirm that the
warning is still there with 4.9 on x86 (I guess I missed it in the
noise of running -o - -S).

Tim, do you really get no waring and a return statement? If not, we
can hopefully bring this down to two cases depending on the arch

* Ignored attribute (doesn't show up in the IL), with a waring (I
would actually prefer an error if possible)
* unreachable instead of ret in the other arches.

Cheers,
Rafael

I seem to recall it in Visual Studio going back to the 5.0 days (late
1990s). For Microsoft, it was available on x86.

Is there still interest in the Windows compat stuff?

Sure. We can probably put it behind -fms-extension on X86.

Cheers,
Rafael

Tim, do you really get no waring and a return statement? If not, we
can hopefully bring this down to two cases depending on the arch

Gah! No, I see the warning now. Blasted black-and-white diagnostics.
Sorry about all the confusion I've caused.

Tim.

Gah! No, I see the warning now. Blasted black-and-white diagnostics.
Sorry about all the confusion I've caused.

I did the same :frowning:

Cool, of the support architectures on clang so far we have

x86-64: warn (except for windows)
x86: warn (except for windows)
arm: produce a function ending in unreachable (can someone check
if that is the case for thumb too?)
arm64: warn

Tim.

Cheers,
Rafael

arm: produce a function ending in unreachable (can someone check
if that is the case for thumb too?)

Yep, Thumb is the same as ARM (on Linaro 2013.03, GCC 4.7 build).

Cheers.

Tim.