Stdio/Stdlib still linking after passing -ffreestanding and -nostdlib flags to linker

橙三吉。 提交于 2019-12-11 04:42:57

问题


I'm trying to compile a bare metal application for an ARM c Cortex-M3 processor and I'm having trouble setting up the compiler/link flags. I'm on Ubuntu Trusty, using arm-none-eabi-gcc compiler 4.9.3 20150529.

Here is my main.c:

#include <stdio.h>
void main() {
    printf("Hello, world");
}
// Tons of clock initialization code ...

And here is the generated link command:

arm-none-eabi-gcc   -mthumb -mcpu=cortex-m3 -mlittle-endian -g -ggdb  
-T /home/user/hello-arm/cmake/../ldscripts/STM32F100XB_FLASH.ld 
-ffreestanding -nostdlib CMakeFiles/blinky.elf.dir/src/main.c.o 
CMakeFiles/blinky.elf.dir/src/stm32f1xx_hal_msp.c.o 
CMakeFiles/blinky.elf.dir/src/stm32f1xx_it.c.o 
CMakeFiles/blinky.elf.dir/src/stm32vl_discovery.c.o  -o blinky.elf  
system/libhal_init.a system/libhal_cortex.a system/libhal_flash.a 
system/libhal_gpio.a system/libstartup.a system/libhal_rcc.a

and here is the error:

/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libc.a(lib_a-init.o): In function `__libc_init_array':
init.c:(.text.__libc_init_array+0x20): undefined reference to `_init'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c 
(.text._sbrk_r+0xc): undefined reference to `_sbrk'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none
eabi/lib/armv7-m/libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libc.a(lib_a-readr.o): In function `_read_r': readr.c:
(.text._read_r+0x10): undefined reference to `_read' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libc.a(lib_a-fstatr.o): In function `_fstat_r': 
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libc.a(lib_a-isattyr.o): In function `_isatty_r': 
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'

I was expecting a different error though: printf undefined. This tells me that stdio.h is being found, and stdlib is being linked.

Finally it is worth noting one thing. If I remove -nostdlib, I get a very slightly different error:

/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-
m/libg.a(lib_a-exit.o): In function `exit': exit.c:(.text.exit+0x16): 
undefined reference to `_exit' /usr/bin/../lib/gcc/arm-none-
eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/libg.a(lib_a-sbrkr.o):
In function `_sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to 
`_sbrk' /usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-
eabi/lib/armv7-m/libg.a(lib_a-writer.o): In function `_write_r': writer.c:
(.text._write_r+0x10): undefined reference to `_write' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-
m/libg.a(lib_a-closer.o): In function `_close_r': closer.c:
(.text._close_r+0xc): undefined reference to `_close' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-
m/libg.a(lib_a-lseekr.o): In function `_lseek_r': lseekr.c:
(.text._lseek_r+0x10): undefined reference to `_lseek' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-
m/libg.a(lib_a-readr.o): In function `_read_r': readr.c:
(.text._read_r+0x10): undefined reference to `_read' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-
m/libg.a(lib_a-fstatr.o): In function `_fstat_r': fstatr.c:
(.text._fstat_r+0xe): undefined reference to `_fstat' 
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-
m/libg.a(lib_a-isattyr.o): In function `_isatty_r': isattyr.c:
(.text._isatty_r+0xc): undefined reference to `_isatty' collect2: error: ld 
returned 1 exit status

[EDIT] Here is the compiling of main.c:

arm-none-eabi-gcc -DSTM32F100xB -mthumb -mcpu=cortex-m3 -mlittle-endian -nostdlib -ffreestanding -g -ggdb -I/home/user/hello-arm/apps/blinky/include -I/home/user/hello-arm/system/include/stm32f1xx_hal -I/home/user/hello-arm/system/include/cmsis -o CMakeFiles/blinky.elf.dir/src/main.c.o -c /home/user/hello-arm/apps/blinky/src/main.c

[EDIT2] Object dump of main.c.o:

00000000 <main>:
   0:   b580        push    {r7, lr}
   2:   b082        sub sp, #8
   4:   af00        add r7, sp, #0
   6:   4824        ldr r0, [pc, #144]  ; (98 <main+0x98>)
   8:   f7ff fffe   bl  0 <printf>
   c:   f7ff fffe   bl  0 <HAL_Init>
  10:   f7ff fffe   bl  a8 <SystemClock_Config>
  14:   4a21        ldr r2, [pc, #132]  ; (9c <main+0x9c>)
        ...

Looks like the printf symbol is still there.

[EDIT3] I just want to explicitly note that the difference between having -nostdlib and not having it is linking libc.a and libg.a

[EDIT4] The linker script makes no references to standard libraries outside of what I've pasted below:

  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

来源:https://stackoverflow.com/questions/45458528/stdio-stdlib-still-linking-after-passing-ffreestanding-and-nostdlib-flags-to-l

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!