链接另一个启动文件

时间:2013-05-19 21:47:44

标签: c gcc linker ld linker-scripts

我正在尝试使用LD脚本中的STARTUP指令将程序与我自己的启动文件链接:

...
ENTRY(_start)
STARTUP(my_crt1.o)
...

GCC驱动程序用于链接程序(不用担心libgcc等库路径):

gcc -T my_script.ld ...

不幸的是,它仅适用于为powerpc目标编译的GCC,而arm或i686目标则不包含但仍包含在collect2中的crt0.o。例如:

arm-eabi-g++ -v -T my_script.ld ...

给了我:

collect2 ... /opt/lib/gcc/arm-eabi/4.8.0/../../../../arm-eabi/lib/crt0.o ...

因此:

crt0.S:101: multiple definition of `_start'

似乎STARTUP指令完全被忽略(powerpc目标也使用其默认的crt0,除非指定了STARTUP指令)并且无法禁用默认的crt0。

是否有可移植的方式链接另一个启动文件?

我的启动文件使用libgcc个函数(调用ctors和dtors),因此需要crtbegin.ocrtend.o等,所以我想避免{{1} }禁用-nostartfiles的选项 - 我只需要停用crt*.o

谢谢

2 个答案:

答案 0 :(得分:4)

  

我正在尝试将程序与我自己的启动文件链接...
  GCC驱动程序用于链接程序...

在这种情况下,您必须还向GCC提供-nostartfiles标志。

答案 1 :(得分:2)

此限制确实会强制您使用-nostartfiles禁用默认启动文件(我更喜欢-nostdlib)。然后,您需要自己构建运行时对象列表。 gcc有选项-print-file-name来打印它编译的库的绝对路径(crtbegin.o,crtend.o,libgcc.a ...)。例如:arm-eabi-g++ <FLAGS> -print-file-name=crtbegin.o

这是我使用的GNU Make宏(提供gcc和cflags):

define m.in/toolchain/gnu/locate =
$(strip
  $(shell $(m.in/toolchain/gnu/bin/gcc) $(m.in/toolchain/gnu/cflags) \
          -print-file-name=$(m.in/argv/1))
)
endef

crtn := $(call m.in/toolchain/gnu/locate, crtn.o)