2

(arm-none-linux-gnueabi-gcc Sourcery G++ Lite 2011.03-41) でRVCT 2.2コンパイルされたテスト プログラムでコンパイルされた静的なサード パーティ ライブラリをリンクしようとしています。GCC

とリンクすると-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'

memcpyとの両方memsetが libc に存在する必要があります。を使用すると、明らかGCCにこれを検出して修正できます-static。誰かが何が起こっているのか説明できますか? フラグGCCを追加しない限り libc に動的にリンクすると仮定しますが、共有 libc ライブラリでも同様に定義すべきではありませんか?-static__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 がない場合は、バイナリ foo.a をhttp://dl.dropbox.com/u/14498565/foo.aからダウンロードできます。

4

2 に答える 2

3

この@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...これは、静的シンボル (非共有) を表示するためのものです。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機能する理由です。共有 C ライブラリを期待するように foo.oa を少し違った方法でコンパイルした場合、-static を指定せずに foo.a にリンクできると思います。残念ながら、私は RVCT コンパイラに詳しくありません。

FWIW、使用するstraceと、実際に共有 C ライブラリに対してリンクされていることがわかりましたが、リンクは解決されていません。また、--sysroot=/path/to/code/sourcery/toolchain/arm-none-linux-gnueabi/libcコマンド ライン オプションを使用して、正しい C ライブラリが検出されていることを確認しました。

于 2012-09-05T00:46:26.277 に答える
0

これらは、ランタイム ABI によって定義されたヘルパー関数です: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043c/IHI0043C_rtabi.pdf

これを回避するには、(libc memcpy と memset を使用して) これらの独自のバージョンを実装することもできますが、さらに微妙なリンクの問題が発生している可能性もあります。オブジェクトファイルにアクセスせずに言うのは難しい.

于 2012-08-31T12:53:03.700 に答える