对于纯 C 代码,未定义对 `__aeabi_unwind_cpp_pr1' 的引用

问题描述 投票:0回答:2

我正在为 ARM926 构建裸机代码,我需要生成的输出尽可能紧凑。

尽管尽了最大努力,我仍然收到此错误:

yocto/poky/build-idprint/tmp/work/idprint-poky-linux-gnueabi/idpr/1.0-r0/
recipe-sysroot/usr/lib/libc.a(raise.o):
(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr1'

在我的

Makefile
中我放置了这个链接器标志:

LD_OPT    = -Wl,-gc-sections -Wl,-build-id=none -flto
LD_LINK   = -static -nostartfiles -nostdlib -Wl,--start-group,-lgcc,-lc,--end-group
LDFLAGS   = -T $(BINARY).ld -Xlinker -Map=$(BINARY).map $(LD_OPT)

链接命令是

$(LINK.cc) $(OBJS) $(LD_LINK) src/lib_dummies.o -o $(BINARY).elf

最后我有一个尽可能简单的自定义链接器脚本:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(fiq_main)

SECTIONS
{
  . = 0x0;
  .text : {
    KEEP(*(.textEntry));
    *(.text*)
    *(.text .gnu.linkonce.t.*)
  }
  . = ALIGN(1024);
  _bss_start = .;
  .data : { *(.data) }
  .bss : { *(.bss) }
  _bss_end = .;
}

我在代码中添加了一个自定义虚拟对象

__aeabi_unwind_cpp_pr1
(受 libgcc 源代码启发),但没有帮助。

我在网络上阅读了相当多的页面,但没有一个页面解释了我为什么

libgcc
试图将
C++
函数链接到我的仅
C
项目。 好的,
$(LINK.cc)
被评估为
arm-poky-linux-gnueabi-g++
,但我仍然认为尝试将
C++
函数链接到
libgcc
没有任何意义。如果我链接
libstdc++
,那就有意义了。此外,$(LD) 由于其他原因失败(找不到
-lgcc
)。

我找不到任何优化标志来帮助我解决这个问题。

看,我的代码不添加任何不需要的东西非常重要。 一切开始只是因为我需要使用整数除法(未解决

__aeabi_idiv
...)


为了简单起见,我省略了优化标志,但如果需要,请告诉我,我会添加它们。

任何帮助将不胜感激。 谢谢。

c linker linker-errors
2个回答
1
投票

嗯,

经过很长时间的战斗,我最终得到了一个相对简单的解决方案。 在我的 Makefile 中,我将

LD_LINK
行更改为:

LD_LINK   = -static -nostartfiles -nostdlib -lgcc

(已删除

-Wl,--start-group,-lgcc,-lc,--end-group

这让我发现了

undefined reference to raise
。 然后我将这几行添加到汇编源文件中:

    .global raise

raise:
    b raise

注:

我尝试在 C 中创建一个

raise
函数,但是由于名称修改,并且尽管我尝试过任何技巧,链接器永远找不到它。

如果有人能向我展示如何在普通 C 中做到这一点,我会非常高兴。

奖金:

我的最终二进制文件比我之前得到的要小,而这正是我所需要的!


0
投票

就我而言,我发现这个问题仅存在于arm32上,而不存在于aarch64上。即使使用纯 C 代码构建也会发生这种情况(因此显然没有 C++ 例外)。链接器抱怨缺少 __aeabi_unwind_cpp_prX,但实际上,它们永远不会通过反汇编二进制文件来调用。链接器中可能有错误?无论如何,解决方案是定义它们的存根符号,它们将成为孤儿符号。

© www.soinside.com 2019 - 2024. All rights reserved.