https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88167

            Bug ID: 88167
           Summary: [ARM] Function __builtin_return_address returns
                    invalid address
           Product: gcc
           Version: 7.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mihail.ionescu at arm dot com
  Target Milestone: ---

Used compiler options are: -mcpu=cortex-m0 -mthumb -O2.

Consider the following code:

__attribute__((used))
void *retaddr;

__attribute__((noinline))
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.

Reply via email to