Prologue/epilogue sequences added to naked functions

Bug #1549542 reported by Cory Snider
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Confirmed
Undecided
Unassigned

Bug Description

The compiler inserts instructions into the prologue and/or epilogue of functions declared with __attribute__((naked)) when the function is declared to either return a struct type by value or accept an argument of a struct type.

The following test case demonstrates the issue:

struct foo { int a; int b; };
void __attribute__((naked)) frob(struct foo a) {
  __asm("bx lr");
}
struct foo __attribute__((naked)) return_a_foo(void) {
  __asm("bx lr");
}

When compiled with gcc-arm-none-eabi-4.8_2014q3 in thumb2 mode (-mthumb -mcpu=cortex-m3), the disassembled output is:

00000000 <frob>:
   0: 463b mov r3, r7
   2: e883 0003 stmia.w r3, {r0, r1}
   6: 4770 bx lr

00000008 <return_a_foo>:
   8: 4603 mov r3, r0
   a: 4770 bx lr
   c: 4618 mov r0, r3
   e: bf00 nop

gcc-arm-none-eabi-5_2-2015q4 produces similar results.

Changed in gcc-arm-embedded:
status: New → Confirmed
Revision history for this message
Andre Vieira (andre-simoesdiasvieira) wrote :

Hi Cory,

Thank you for reporting, I can confirm the same behavior. As far as I can tell this is generating suboptimal code sequences, but it shouldnt influence the correctness of the rest of the function. Do you have any example in which this behavior corrupts your function?

I will try to look into why this code is being inserted and I'll keep you posted!

Cheers,
Andre

Revision history for this message
Cory Snider (corhere) wrote :

The following code snippet, compiled with "arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -Os", generates code sequences that will cause the functions to behave incorrectly.

struct foo { int a; int b; };
void __attribute__((naked)) frob(struct foo a, int b, int c) {
  __asm("bx lr");
}
struct foo __attribute__((naked)) return_a_foo(int a, int b, int c) {
  __asm("bx lr");
}

Dissasembly:
00000000 <frob>:
   0: ab02 add r3, sp, #8
   2: e903 0003 stmdb r3, {r0, r1}
   6: 4770 bx lr

00000008 <return_a_foo>:
   8: 4603 mov r3, r0
   a: 4770 bx lr
   c: 4618 mov r0, r3

r3 is clobbered in both functions, which corrupts the "int c" parameter. And the "frob" function writes into the caller's stack frame!

Revision history for this message
Andre Vieira (andre-simoesdiasvieira) wrote :

The corruption of r3 for example 1 is indeed an issue and would have been for example two if it had an extra parameter too.

Revision history for this message
Andre Vieira (andre-simoesdiasvieira) wrote :

I opened a bugzilla ticket for this https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69979

Revision history for this message
Cory Snider (corhere) wrote :

A GCC maintainer has closed the bugzilla ticket as RESOLVED INVALID with an explanation that involves a very strange reading of the documentation. I replied to the ticket after it was closed with a testcase demonstrating that it is a bug by the GCC test suite's definitions, but there has not been any response. What is the next step here?

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.