我正在尝试将使用RVCT 2.2
编译的静态第三方库与使用GCC
编译的测试程序链接(arm-none-linux-gnueabi-gcc Sourcery G ++ Lite 2011.03-41)。< / p>
如果我与-static
链接,一切正常。但是,如果我不使用-static
,我会收到很多抱怨,如下所示:
foolib.a(foo.o): In function `foofunc':
foo.c:(.text+0x4c8): undefined reference to `__aeabi_memcpy'
foolib.a(bar.o): In function `barfunc':
bar.c:(.text+0xa54): undefined reference to `__aeabi_memclr4'
libc中应包含memcpy
和memset
。
显然GCC
可以以某种方式检测并修复此问题,如果我使用-static
。有人可以解释发生了什么吗?我假设GCC
动态链接到libc,除非我添加-static
标志,但不应该在共享libc库中定义__aeabi_memcpy
和类似的东西?
编辑:
为了让人们自己测试一下,我现在创建了一个简约的测试用例,如下所示:
//foo.c
#include <string.h>
void foo(void *dst, void *src, int num) {
memcpy(dst, src, num);
}
使用RVCT 2.2编译和存档此文件,如下所示:
armcc.exe --arm -c --apcs=/noswst/interwork foo.c -o foo.o
armar.exe --create foo.a foo.o
然后将该库与以下测试程序链接:
//bar.c
#include <stdio.h>
extern void foo(void *dst, void *src, int num);
int main(int argc, char *argv[]) {
int a[10], b[10], i;
for (i = 0; i < 10; i++) {
a[i] = i;
}
foo(b, a, sizeof(a));
for (i = 0; i < 10; i++) {
if (a[i] != b[i]) {
printf("Diff at %d: %d != %d\n", i, a[i], b[i]);
return 1;
}
}
printf("Success!\n");
return 0;
}
使用以下命令:
arm-none-linux-gnueabi-gcc -Wall bar.c foo.a -o bar
其中提供以下输出(除非还使用-static
):
foo.a(foo.o): In function `foo':
foo.c:(.text+0x0): undefined reference to `__aeabi_memcpy'
arm-none-linux-gnueabi/bin/ld: bar: hidden symbol `__aeabi_memcpy' isn't defined
arm-none-linux-gnueabi/bin/ld: final link failed: Nonrepresentable section on output
collect2: ld returned 1 exit status
如果您没有RVCT,可以从http://dl.dropbox.com/u/14498565/foo.a下载二进制文件foo.a。
答案 0 :(得分:3)
在这个@Leo花了一些时间之后,我想我明白发生了什么。似乎foo.o的编译方式需要 static 链接到__aeabi_memcpy
。用arm-none-linux-gnueabi-objdump -t
查看foo.o,我看到了:
foo.o: file format elf32-littlearm
SYMBOL TABLE:
00000000 l df *ABS* 00000000 foo.c
00000000 l d .text 00000000 .text
00000000 l *ABS* 00000000 BuildAttributes$$THUMB_ISAv1$ARM_ISAv4$M$PE$A:L22$X:L11$S22$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OSPACE$EBA8$REQ8$PRES8$EABIv2
00000000 l O .debug_frame$$$.text 00000000 C$debug_frame$$$.text7
00000000 w F *UND* 00000000 .hidden Lib$$Request$$armlib
00000000 F *UND* 00000000 .hidden __aeabi_memcpy
00000000 g F .text 00000004 .hidden foo
注意命令行中的-t
...用于向我们显示静态符号(非共享)。在foo.o上运行arm-none-linux-gnueabi-objdump -T
会显示:
foo.o: file format elf32-littlearm
/home/jszakmeister/.local/sourcery-arm-gnueabi/bin/arm-none-linux-gnueabi-objdump: foo.o: not a dynamic object
DYNAMIC SYMBOL TABLE:
no symbols
所以__aeabi_memcpy
希望通过静态链接解决,这就是使用-static
的原因。我相信如果你编译foo.o有点不同,所以它需要一个共享的C库,那么你可以链接到foo.a而不指定-static。不幸的是,我不熟悉RVCT编译器,或者我会告诉你如何。
FWIW,使用strace
我能够看到它确实链接到共享C库,但没有解析链接。我还使用了--sysroot=/path/to/code/sourcery/toolchain/arm-none-linux-gnueabi/libc
命令行选项来确保它找到了正确的C库。
答案 1 :(得分:0)
这些是运行时ABI定义的辅助函数: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043c/IHI0043C_rtabi.pdf
解决这个问题的方法可能是实现你自己的这些版本(使用libc memcpy和memset),但也可能是这里有更多微妙的链接问题,可能会让你更进一步。很难说无法访问目标文件。