I am trying to link a static third party library compiled with RVCT 2.2 with a test program compiled with GCC (arm-none-linux-gnueabi-gcc Sourcery G++ Lite 2011.03-41).
If I link with -static, everything works as it should. If I do not use -static however, I get lots of complaints like the following:
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'
Both memcpy and memset should be present in libc.
Clearly GCC can somehow detect and fix this if I use -static. Can someone explain what is happening? I assume that GCC dynamically links to libc unless I add the -static flag, but shouldn’t __aeabi_memcpy and similar be defined in the shared libc library as well?
EDIT:
In order to let people test this themselves I have now created a minimalistic test case like follows:
//foo.c
#include <string.h>
void foo(void *dst, void *src, int num) {
memcpy(dst, src, num);
}
This file is compiled and archived with RVCT 2.2 as follows:
armcc.exe --arm -c --apcs=/noswst/interwork foo.c -o foo.o
armar.exe --create foo.a foo.o
This library is then linked with the following test program:
//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;
}
Using the following command:
arm-none-linux-gnueabi-gcc -Wall bar.c foo.a -o bar
Which gives the following output (unless -static is also used):
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
The binary foo.a can be downloaded from http://dl.dropbox.com/u/14498565/foo.a in case you don’t have RVCT.
After spending some time with this @Leo, I think I understand what’s going on. It appears that foo.o was compiled in a way that expects a static link to
__aeabi_memcpy. Looking at foo.o witharm-none-linux-gnueabi-objdump -t, I see this:Note the
-tin the command line… that’s for showing us the static symbols (non-shared). Runningarm-none-linux-gnueabi-objdump -Ton foo.o shows this:So
__aeabi_memcpyis looking to be resolved via a static link, which is why using-staticworks. I believe if you compiled foo.o a little differently, so that it expects a shared C library, then you could link to foo.a without specifying -static. Unfortunately, I’m not familiar with the RVCT compiler, or I’d tell you how.FWIW, using
straceI was able to see that it is indeed linking against the shared C library, but not resolving the link. I also used the--sysroot=/path/to/code/sourcery/toolchain/arm-none-linux-gnueabi/libccommand line option to make sure it was finding the correct C library.