[Bug 1768125] Re: libnewlib-arm-none-eabi generates wrong code for cortex-m0
mrvanes
bugs at mrvanes.com
Mon Apr 30 20:36:47 UTC 2018
** Package changed: chkconfig (Ubuntu) => newlib (Ubuntu)
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to newlib in Ubuntu.
https://bugs.launchpad.net/bugs/1768125
Title:
libnewlib-arm-none-eabi generates wrong code for cortex-m0
Status in newlib package in Ubuntu:
New
Bug description:
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.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/newlib/+bug/1768125/+subscriptions
More information about the foundations-bugs
mailing list