新的libc存根应该如何包含/链接到自己的代码中?

3

如果我在代码中没有显式调用存根函数(即_sbrk),则链接器在我的项目链接过程中会出现以下错误:

c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-abort.o): In function `abort':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\stdlib/../../../../../newlib-1.19.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-signalr.o): In function `_kill_r':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.19.0/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-signalr.o): In function `_getpid_r':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.19.0/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-sbrkr.o): In function `_sbrk_r':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.19.0/newlib/libc/reent/sbrkr.c:60: undefined reference to `_sbrk'
collect2: ld returned 1 exit status

我知道我需要一些newlibc所需的存根函数,并且我有一个包含所有上述缺失的函数的“C”文件。我确信该文件正在编译并添加到一个存档文件(*.a),然后进行链接。

我使用以下命令调用链接器:

arm-none-eabi-gcc -L -T linkerscript.ld -nostartfiles -Wl,-Map,$(TARGET).map -lc archive.a

我的问题很简单(希望如此),我如何确保链接器将我的存根函数链接到elf文件中,而不必从我的项目文件中进行显式函数调用?


这里链接顺序是否很重要,就像构建可执行文件一样?那些错误看起来像我在错误的顺序中将库链接到可执行文件时得到的错误。 - Mosby
@Mosby 目前我发现解决这个问题的唯一方法是显式调用一个桩函数。更改项目文件的链接顺序似乎对此问题没有影响。 - maguirre
2个回答

3

我认为你遇到的错误是由于链接器找不到适当的库引起的。我的第一个怀疑是你如何使用参数,特别是你指定的存档目录(-L)和存档文件archive.a。我想应该按照以下方式进行:

arm-none-eabi-gcc -L. -T linkerscript.ld -nostartfiles -Wl,-Map,$(TARGET).map -lc -larchive

我将要做的更改是:

  1. -L. 表示使用当前目录查找库文件进行链接。
  2. -lc 指定使用档案文件 libc.a。
  3. -larchive 指定使用档案文件 libarchive.a。

欲了解更多信息,建议查看GNU GCC参考文档


我将尝试您的建议。同时,您在哪里找到了标志 -lc?我已经搜索了GCC参考文献,但在那里找不到它。即使是谷歌也没有太大帮助来查找gcc手册中提到-lc的位置。 - maguirre
@Mischief 实际上标志是-l,我假设你有一个名为libc.a的库文件。这并不是真正的变化,这是在你问题的命令行中。 - spade78

2
--verbose 传递给 gcc,以精确查看 archive.a 在传递给链接器的库和对象列表中的位置。
您需要安排事情,使得在搜索 undefined references 对象时,archive.alibg.a 之后被搜索。
您可能可以通过在 gcc 命令行上添加 -lg,使其在默认情况下比现在更早地引入 libg.a ,并更重要的是在 archive.a 之前引入它来解决此问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接