I have been trying to execute a GNU C project on ARM Cortex M3 Processor. The project runs happily on -Og optimisation level , but when I tried increasing the optimisation levels to -O2, -O3 , I encountered bus faults.
The GNU tool chain was "arm-none-eabi V10.3.1"
Tried reading the BFSR register and it suggested it was a PRECISERR & STKERR. The fault was happening in a self implemented memset function and was done because the project didn't require the standard CLibs.
void* memset(void s, int c, size_t len){
unsigned char *dst;
dst = (unsigned char) s;
while (len > 0) {
*dst = (unsigned char) c;
dst++;
len--;
}
return s; }
Also after going through the Assembly for this function , noticed that this was completely different for the -Og option (which worked) and -O2/3/s option which crashed.
I am copying the screenshot of the assembly for the two options here.
Believe its the return from this function which causes the STKERR, And I have seen a BL instruction (in the -O2/O3/O4 option) which might be the root cause as it pushes the next the instruction address in the Link register and a subsequent pop PC's could fail ?
But I was able to get around the issue by a small modification the code and making the variables as volatile. The new implementation below.
void* memset(void *s, int c, size_t len) {
unsigned char * volatile dst;
volatile size_t count = 0;
dst = (unsigned char * volatile) s;
while (count < len) {
dst[count] = (unsigned char) c;
count++;
}
return s;
}
Please wanted to know whether this is a bug in the GNU tool chain ?
The assembly of the problematic memset function here (-O2/-O3/-Os) :-
.section .text.memset,"ax",%progbits
.align 1
.p2align 2,,3
.global memset
.syntax unified
.thumb
.thumb_func
.type memset, %function
memset:
.cfi_startproc
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
push {r4, lr}
mov r4, r0
cbz r2, .L34
uxtb r1, r1
bl memset
mov r0, r4
pop {r4, pc}
.cfi_endproc
Assembly of the memset function compiled with -Og option (which works)
.section .text.memset,"ax",%progbits
.align 1
.global memset
.syntax unified
.thumb
.thumb_func
.type memset, %function
memset:
.cfi_startproc
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
mov r3, r0
.L20:
strb r1, [r3], #1
subs r2, r2, #1
cmp r2, #0
bne .L20
bx lr
.cfi_endproc
.LFE81:
.size memset, .-memset