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.