我正在尝试从x86架构移植一款大型应用到arm cortex a9架构,但是在交叉编译应用程序时,使用浮点函数如modf等会出现奇怪的分段错误,其他libc++函数似乎只是处理浮点数有误,但没有崩溃(见下文)。
因此,我尝试了这个能够触发错误的小测试程序。测试程序的输出(见下文)应该能够说明我的问题。
#include <iostream>
int main(int argc, char *argv[])
{
double x = 80;
double y = 0;
std::cout << x << "\t" << y << std::endl;
return 0;
}
在 ARM Cortex A9 上编译:
@tegra$ g++ -Wall test.cpp -o test_nativ
@tegra$ ./test_nativ
80 0
跨编译
@x86$ arm-cortex_a9-linux-gnueabi-g++ test.cpp -o test_cc
@tegra$ ./test_cc
0 1.47895e-309
使用“-static”链接器选项进行交叉编译。
@x86$ arm-cortex_a9-linux-gnueabi-g++ -static test.cpp -o test_cc_static
@tegra$ ./test_cc_static
80 0
.
@x86$ arm-cortex_a9-linux-gnueabi-objdump -S test_cc
see: http://pastebin.com/3kqHHLgQ
@tegra$ objdump -S test_nativ
see: http://pastebin.com/zK35KL4X
回答一些下面的评论:
- 交叉编译器配置为小端字节序,与tegra机器上的本地编译器一样。
- 我不认为这是内存对齐问题,因为我在移植到arm时遇到了这些问题,应该向应用程序发送SIGBUS或记录到syslog中,请参阅/proc/cpu/alignment的文档。
我目前的解决方法是复制交叉编译工具链并使用LD_LIBRARY_PATH来使用它...不太好,但暂时足够好。
编辑:
谢谢你们的回答。
与此同时,我发现tegra设备上的linux分发版是使用'-mfloat-abi=softfp'编译的,尽管文档指出需要使用'-mfloat-abi=hard'编译工具链。
更改工具链取得了成功。
似乎可以使用'readelf -A'在任何系统二进制文件上查看硬件浮点和软件浮点之间的区别:
如果输出包含以下行:'Tag_ABI_VFP_args: VFP registers',则是使用'-mfloat-abi=hard'进行编译。如果缺少此行,则该二进制文件很可能是使用'-mfloat-abi=softfp'编译的。
线路'Tag_ABI_HardFP_use: SP and DP'并不表示编译器标志'-mfloat-abi=hard'。
0
是特殊的,它由所有零位表示。没有任何重新排列的方法不会导致0
。我认为更可能是ABI不匹配。 - Mark Ransom