[Bug 1768125] [NEW] libnewlib-arm-none-eabi generates wrong code for cortex-m0

Launchpad Bug Tracker 1768125 at bugs.launchpad.net
Mon Apr 30 20:36:49 UTC 2018


You have been subscribed to a public bug:

Since my upgrade to 18.04 last weekend I can't compile a working
firmware for my stm32f0xx based drone flight controller. The mcu halts
at HardFault_Handler and it turns out the generated code for memset is
faulty.

I've managed to narrow the problem down to the following code:
int main(void)
{
    int test[4] = { 0, 0, 0, 0 };

    while (1);
}

void HardFault_Handler(void)
{
    while(1);
}

In which HardFault_Handler(void) was add to prove the HardFault occuring at the array initialisation.
The file is compiled using the following commandline:

arm-none-eabi-gcc -mcpu=cortex-m0 -g -mthumb -fdata-sections -ffunction-
sections -nostartfiles -ffreestanding --specs=nano.specs
--specs=nosys.specs -Wl,-T,flash.ld,-Map,output.map,--gc-sections
-std=gnu99 main.c <includes> -o memset.elf

And uses STM32F0xx_StdPeriph_Driver includes and
CMSIS/Device/ST/STM32F0xx based startfile.

The resulting elf binary is then coverted to a binary using arm-none-
eabi-objcopy -O binary memset.elf memset

output.map mentions memset as:
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/libc_nano.a(lib_a-memset.o)

So I suspect the memset nano libc version is used.

arm-none-eabi-objdump -d memset.elf produces the following code for
main:

080001b8 <main>:
 80001b8:	b580      	push	{r7, lr}
 80001ba:	b084      	sub	sp, #16
 80001bc:	af00      	add	r7, sp, #0
 80001be:	003b      	movs	r3, r7
 80001c0:	0018      	movs	r0, r3
 80001c2:	2310      	movs	r3, #16
 80001c4:	001a      	movs	r2, r3
 80001c6:	2100      	movs	r1, #0
 80001c8:	f7ff ff7c 	bl	80000c4 <memset>
 80001cc:	e7fe      	b.n	80001cc <main+0x14>

And memset starts like this:

080000c4 <memset>:
 80000c4:	e3100003 	tst	r0, #3
 80000c8:	e92d4010 	push	{r4, lr}
 80000cc:	0a000037 	beq	80001b0 <memset+0xec>
 80000d0:	e3520000 	cmp	r2, #0
 80000d4:	e2422001 	sub	r2, r2, #1
 80000d8:	0a000032 	beq	80001a8 <memset+0xe4>
 80000dc:	e201c0ff 	and	ip, r1, #255	; 0xff
 80000e0:	e1a03000 	mov	r3, r0
 ...

When I step through the assembly, after arriving at 0x080000c4, the
debugger however shows this assembly:

0x80000c4 <memset>      movs   r3, r0                                                                                                                                                                              
0x80000c6 <memset+2>    b.n    0x80006ea                                                                                                                                                                           
0x80000c8 <memset+4>    ands   r0, r2
0x80000ca <memset+6>    stmdb  sp!, {r0, r1, r2, r4, r5}
0x80000ce <memset+10>   lsrs   r0, r0, #8
0x80000d0 <memset+12>   movs   r0, r0
0x80000d2 <memset+14>   b.n    0x800077a
...

This doesn't look like the disassembled code at all, and

0x80006ea contains no valid code:
0x80006ea                      ; <UNDEFINED> instruction: 0xffffffff
0x80006ee                      ; <UNDEFINED> instruction: 0xffffffff
0x80006f2                      ; <UNDEFINED> instruction: 0xffffffff
0x80006f6                      ; <UNDEFINED> instruction: 0xffffffff
0x80006fa                      ; <UNDEFINED> instruction: 0xffffffff
0x80006fe                      ; <UNDEFINED> instruction: 0xffffffff

Thus reliably results in the HardFault_Handler()

I'm in no way an experienced cortex developer/debugger. The above
observations are what I managed to research last days since not being
able to compile the firmware anymore.

I noticed that the above dump of memset function from the .elf file
looks to contain valid asm (starts with tst, push and then a beq to a
valid address), but the instructions + operands are all 32bits, where as
the code in main is just 16 bits for each instruction + operand. That
smells fishy to my unexperienced eyes?

This is as far as I understand the arm toolchain and had to give up.

** Affects: newlib (Ubuntu)
     Importance: Undecided
         Status: New

-- 
libnewlib-arm-none-eabi generates wrong code for cortex-m0
https://bugs.launchpad.net/bugs/1768125
You received this bug notification because you are a member of Ubuntu Foundations Bugs, which is subscribed to newlib in Ubuntu.



More information about the foundations-bugs mailing list