什么是__aeabi_unwind_cpp_pr1',我该如何避免呢?

问题描述 投票:5回答:4

我有一堆arm组件,C和C ++文件。 gcc正在尝试链接它们,但这些是用于嵌入式项目的。

我没有使用任何外部库,所有正在使用的代码都是由我编写的。似乎发生了错误,因为我在int kernel_main(void)中定义了一个名为main.c的函数,该函数试图调用set_LED(int value)中定义的mailbox.cpp,其中包含头mailbox.h(我确实在main.c文件中包含了头文件)。

确切的错误是:

undefined reference to `__aeabi_unwind_cpp_pr1'

我创建项目的方式是: - 将所有源文件(.s,.c,.cpp)编译为目标文件(.o)而不链接(-c),然后使用自定义链接器将它们全部链接在一起脚本。

编辑:我将添加一些信息以使事情更清楚。

首先更改所有文件,以便所有文件都是C文件(没有cpp扩展名)产生:

undefined reference to `set_LED'

问题本身不太可能是名称错误,它可能与CPP和C差异无关。

问题很可能是链接器问题

这是构建过程:

编译c文件,例如:

arm-none-eabi-g++ -O0 -march=armv8-a source/MainFiles/mailbox.cpp -nostartfiles -c -o objects/MainFiles/mailbox.o

(除了使用g ++而不是gcc之外,编译C ++文件是完全相同的)

链接一切:

arm-none-eabi-ld object1 object2... -o build/kernel.elf -T ./source/kernel.ld -I include_directory_1 -I include_directory_2 -L include_directory_1 -L indlude_directory_2

包含目录是当前目录下的所有目录

编辑:错误回来了。忽略与名称重整相关的此问题的部分。我需要解决的错误是:

./objects/Hardware/mailbox.o:(.ARM.exidx+0x18): undefined reference to `__aeabi_unwind_cpp_pr1'

到目前为止,我所知道的是,这与解除堆栈和异常有关。似乎函数是在libgcc中定义的。但是我使用了-nostdlib,我省略了它,并且在这两种情况下错误仍然存​​在。我尽可能地尝试将文件扩展名更改为.c,并尽可能将.cpp更改为.cpp,总是存在错误。

只有我有1个cpp文件并且我的其余文件都是C文件(这不再是真的,我试过),它才得到修复。再次触发错误的原因是我正在重构代码,我想将一些函数移动到新文件中。

换句话说,在不删除单个文件的情况下,在mailbox.cpp中声明一个名为wait(uint32_t time)的函数,可以在一个名为time.c(或cpp)的文件中声明它,并使用它的相应头声明并在mailbox.cpp中包含标题。注意我在移动函数时不删除文件我只是删除每个文件中的函数声明。

添加这样的存根:

void __aeabi_unwind_cpp_pr1()
{

}

修复问题和代码工作。但我不喜欢这个解决方案。我不想在我的代码中神秘地调用无用的存根。我不需要也不想在我当前的实现中使用这个函数,如何告诉编译器或链接器他们要省略他们正在做什么需要这个函数?

c++ c gcc
4个回答
1
投票

您可以参考此函数,该函数属于GCC的C ++运行时。这是异常处理的一部分。无论你做什么,听起来有点疯狂,但无论如何,如果你真的知道自己在做什么,你可以做到这一点。您必须链接到C ++运行时库。而已。链接“libstdc ++”。

关于set_LED我也相信它只是关于C ++的修改,正如Justin J在另一个答案中提到的那样。


1
投票

我在混合使用C和C ++时已经看到了这一点。由于名称重整,符号将在内部具有不同的名称,具体取决于源文件的类型。

如果'set_LED'的源是一个c文件,请在原型周围的标题中使用以下内容,看看它是否有帮助。

#ifdef __cplusplus
extern "C" {
#endif

// function prototypes here

#ifdef __cplusplus
}
#endif

1
投票

解决方案非常简单。事实证明,默认情况下启用了异常(生成调用__eabi_unwind_cpp_pr1的代码)。要禁用它们,只需将:-fno-exceptions作为参数传递给gcc / g ++编译器,问题就解决了。


-2
投票

还请在-fno-exceptions中添加前缀“-shared”,不带引号。我正在使用ARM GCC版本

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