2012-08-31 136 views
2

我想鏈接一個用RVCT 2.2編譯的靜態第三方庫與用GCC(arm-none-linux-gnueabi-gcc Sourcery G ++ Lite 2011.03-41)編譯的測試程序。將RVCT庫與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' 

兩個memcpymemset應該出現在libc中。 明顯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; 
} 

使用下面的命令:如果

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下載你別:

arm-none-linux-gnueabi-gcc -Wall bar.c foo.a -o bar 

這給下面的輸出(除非也使用-static)沒有RVCT。

+0

工具鏈編譯時是否支持共享庫?我記得自己曾經看到過一個問題,並且我們沒有編譯支持共享庫的工具鏈。 – jszakmeister

+0

不確定,它是CodeSourcery網站上提供的預編譯二進制文件。我可以創建共享庫,但我認爲它支持它。 – Leo

+0

你正在使用類似-nodefaultlibs的東西嗎?如果是這樣,您可能需要手動鏈接到libgcc_s。 – jszakmeister

回答

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作品得到解決。我相信如果你編譯foo。有點不同,所以它期望一個共享的C庫,那麼你可以鏈接到foo.a而不指定-static。不幸的是,我對RVCT編譯器不熟悉,或者我會告訴你如何。

FWIW,使用strace我能夠看到它確實鏈接到共享的C庫,但沒有解析鏈接。我還使用了--sysroot=/path/to/code/sourcery/toolchain/arm-none-linux-gnueabi/libc命令行選項來確保它找到了正確的C庫。

+0

太棒了!這確實似乎解釋了正在發生的事情。我將不得不調查RVCT編譯器標誌,然後我猜。 – Leo

0

這些都是由運行時ABI定義的輔助功能: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043c/IHI0043C_rtabi.pdf

針對此解決方法可能是實現自己的這些版本(使用libc中的memcpy和memset),但它也可能是有在這裏發生的更微妙的鏈接問題可能會讓你更進一步。很難說沒有訪問對象文件。

+0

奇怪的是,如果提供了'-static',GCC似乎可以解決這個問題。我現在添加了示例代碼和對象文件,以備實驗。 – Leo