Function __builtin_return_address returns invalid address

Bug #1803508 reported by Giovanni Di Sirio
This bug affects 2 people
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Mihail-Calin Ionescu

Bug Description

The problem only applies to Cortex-M0 and any GCC release 6 and 7. Previous versions work correctly.

Consider the following code:

void *retaddr;

void xxxxtest(void) {
  retaddr = __builtin_return_address(0);

  /* Used for enforcing registers stacking.*/
  asm volatile("" : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
                        "r8", "r9", "r10", "r11", "r12");

It produces the following asm:

 8001940: b5f0 push {r4, r5, r6, r7, lr}
 8001942: 46de mov lr, fp <=========== HERE LR is used as a scratchpad
 8001944: 4657 mov r7, sl
 8001946: 464e mov r6, r9
 8001948: 4645 mov r5, r8
 800194a: 4672 mov r2, lr <=========== HERE LR is accessed for return address
 800194c: 4b04 ldr r3, [pc, #16] ; (8001960 <xxxxtest+0x20>)
 800194e: b5e0 push {r5, r6, r7, lr}
 8001950: 601a str r2, [r3, #0]
 8001952: bc3c pop {r2, r3, r4, r5}
 8001954: 4690 mov r8, r2
 8001956: 4699 mov r9, r3
 8001958: 46a2 mov sl, r4
 800195a: 46ab mov fp, r5
 800195c: bdf0 pop {r4, r5, r6, r7, pc}

The problem is in the function entry code, where callee-saved registers are stacked. LR is used as scratchpad @8001942 before the return address is taken @800194a.

This problem broke the ChibiOS port for Cortex-M0 using the latest compilers, the builtin is used for enforcing context switch after nested ISRs execution, a very critical bit of code, there is no easy way to workaround this.

Used compiler options are: -mcpu=cortex-m0 -mthumb -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -ffunction-sections -fdata-sections -fno-common -flto

Disabling optimizations hides the problem.

tags: added: chibios
Changed in gcc-arm-embedded:
assignee: nobody → Mihail-Calin Ionescu (mihail.ionescu)
Changed in gcc-arm-embedded:
status: New → In Progress
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers