代码之家  ›  专栏  ›  技术社区  ›  Leo

将RVCT库与GCC链接

  •  2
  • Leo  · 技术社区  · 12 年前

    我正在尝试将编译的静态第三方库与 RVCT 2.2 使用编译的测试程序 GCC (arm-none-linux-gneabi-gcc源代码G++精简版2011.03-41)。

    如果我链接到 -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'
    

    二者都 memcpy memset 应存在于libc中。 清晰地 全球气候变化委员会 如果我使用 -静态的 。有人能解释一下发生了什么吗?我认为 全球气候变化委员会 动态链接到libc,除非我添加 -静态的 旗帜,但不应该 __aeabi_memcpy 以及类似的定义在共享libc库中?


    编辑:
    为了让人们自己测试,我现在创建了一个极简主义测试用例,如下所示:

    //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
    

    它给出以下输出(除非 -静态的 也被使用):

    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
    

    二进制foo.a可以从 http://dl.dropbox.com/u/14498565/foo.a 以防你没有RVCT。

    2 回复  |  直到 12 年前
        1
  •  3
  •   John Szakmeister    12 年前

    在与@Leo相处了一段时间后,我想我明白了发生了什么。看来foo.o是以一种期望 静止的 链接到 __aeabi_memcpy .看着foo.o arm-none-linux-gnueabi-objdump -t ,我看到了:

    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 在命令行中。。。这是为了向我们展示静态符号(非共享)。跑步 arm-none-linux-gnueabi-objdump -T 在foo.o上显示如下:

    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库,那么你就可以在不指定-static的情况下链接到foo.a。不幸的是,我不熟悉RVCT编译器,或者我会告诉你怎么做。

    FWIW,使用 strace 我能够看到它确实与共享的C库链接,但没有解决链接。我还使用了 --sysroot=/path/to/code/sourcery/toolchain/arm-none-linux-gnueabi/libc 命令行选项,以确保找到正确的C库。

        2
  •  0
  •   unixsmurf    12 年前

    这些是由运行时ABI定义的辅助函数: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043c/IHI0043C_rtabi.pdf

    解决方法可能是实现您自己的这些版本(使用libc-memcpy和memset),但也可能是这里存在更微妙的链接问题,可能会让您进一步陷入困境。如果不能访问对象文件,很难说。