-
Bug
-
Resolution: Fixed
-
Medium
-
Code Generation Tools
-
CODEGEN-13041
-
-
-
default
Observation
Enabling code coverage for a file that contains naked function breaks the naked function.
More details
The function we observe break is implemented as follows:
cpu.c
void _attribute_((naked)) CPUDelay(uint32_t count)
As per the documentation of a naked function, it assumes the first argument of the function is in R0. In the failing code, CPUDelay(3) is called.
Code coverage disabled (code functional)
Call site:
Call site
0x000004F8 2003 movs r0, #3
0x000004FA F001F97B bl CPUDelay
CPUDelay():
CPUDelay()
0x000017F4 3801 subs r0, #1
0x000017F6 D1FD bne CPUDelay
0x000017F8 4770 bx r14
Code coverage enabled (failing)
Call site:
Call site
0x0000043E 2003 movs r0, #3
__llvm_coverage_mapping
0x00000440 F001FBDC bl CPUDelay
CPUDelay():
CPUDelay()
- Highlighted section: Start
0x00001BFC 4905 ldr r1, pc, #0x14
0x00001BFE 6848 ldr r0, r1, #4
0x00001C00 680A ldr r2, [r1]
0x00001C02 2300 movs r3, #0
0x00001C04 1C52 adds r2, r2, #1
0x00001C06 4158 adcs r0, r3
0x00001C08 600A str r2, [r1]
0x00001C0A 6048 str r0, r1, #4 - Highlighted section: End
0x00001C0C 3801 subs r0, #1
0x00001C0E D1FD bne #0x1c0c
0x00001C10 4770 bx r14
The highlighted code is added by the code coverage. R0 is observed to be 0 after those instructions are executed. The subsequent "substract 1 from 0" is problematic.
Workaround
In our case, we could work around it by disabling code coverage for the entire cpu.c file (it only contains naked functions). For others, that may not be an acceptable workaround.
Update: Adding attribute no_instrument_function will also fix the issue.
void _attribute_((naked, no_profile_instrument_function)) CPUDelay(uint32_t count)
{ // ... }Suggested Solutions
Ensure the code coverage code does not break the "naked" function promise.
Do not support code coverage for naked functions