Leo
Leo

Reputation: 2388

Linking RVCT libraries with GCC

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.

Upvotes: 2

Views: 3314

Answers (2)

John Szakmeister
John Szakmeister

Reputation: 47062

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 with arm-none-linux-gnueabi-objdump -t, I see this:

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

Note the -t in the command line... that's for showing us the static symbols (non-shared). Running arm-none-linux-gnueabi-objdump -T on foo.o shows this:

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

So __aeabi_memcpy is looking to be resolved via a static link, which is why using -static works. 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 strace I 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/libc command line option to make sure it was finding the correct C library.

Upvotes: 3

unixsmurf
unixsmurf

Reputation: 6234

These are helper functions defined by the runtime ABI: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043c/IHI0043C_rtabi.pdf

A workaround for this could be to implement your own versions of these (using the libc memcpy and memset), but it may also be that there are more subtle linking issues going on here that could trip you up further on. Difficult to say without access to the object files.

Upvotes: 0

Related Questions