2017-08-03 200 views
1

使用鏈接描述文件在地址空間中佈置符號時,ld允許 引用來自靜態庫的特定符號,其語法如下 :使用GNU gold鏈接器引用靜態庫中的特定符號

archive.a:object_file.o(.section.symbol_name) 

使用gold而不是ld,似乎這樣的指令被忽略。 鏈接過程成功。但是,當使用此指令將特定 符號放在特定位置gold並使用nm檢查生成的符號佈局 或查看映射文件時,符號不在預期的 位置中。

我用一個虛擬hello世界程序製作了一個小測試用例,其靜態編譯爲 ,其gcc版本爲5.4.0。 C庫是musl libc(最後一次在官方git倉庫的 master分支上提交)。對於binutils,我還使用官方git倉庫master分支上的 最後一次提交。

我使用鏈接腳本從靜態 庫(MUSL C庫:libc.a)放置一個特定符號(.text.exit)在地址空間 這是一個特定的位置:在.text部分中的第一位置。

我的鏈接腳本是:

ENTRY(_start) 
SECTIONS 
{ 
    . = 0x10000; 
    .text : 
    { 
     /* Forcing .text.exit in the first position in .text section */ 
     musl/lib/libc.a:exit.o(.text.exit); 
     *(.text*); 
    } 
    . = 0x8000000; 
    .data : { *(.data*) } 
    .rodata : { *(.rodata*) } 
    .bss : { *(.bss*) } 
} 

我的Makefile:

# Set this to 1 to link with gold, 0 to link with ld 
GOLD=1 

SRC=test.c 
OBJ=test.o 
LIBS=musl/lib/crt1.o \ 
    musl/lib/libc.a \ 
    musl/lib/crtn.o 
CC=gcc 
CFLAGS=-nostdinc -I musl/include -I musl/obj/include 
BIN=test 
LDFLAGS=-static 
SCRIPT=linker-script.x 
MAP=map 

ifeq ($(GOLD), 1) 
LD=binutils-gdb/gold/ld-new 
else 
LD=binutils-gdb/ld/ld-new 
endif 

all: 
    $(CC) $(CFLAGS) -c $(SRC) -o $(OBJ) 
    $(LD) --output $(BIN) $(LDFLAGS) $(OBJ) $(LIBS) -T $(SCRIPT) \ 
     -Map $(MAP) 

clean: 
    rm -rf $(OBJ) $(BIN) $(MAP) 

(使用-Map ld/gold標誌獲得)來編譯和鏈接我檢查的地圖文件後看看.text.exit的位置。使用ld作爲 鏈接器,它確實在文本部分的第一個位置。使用gold,它不是 (它存在於地址空間的更遠處,就好像我的指令不是考慮到 一樣)。

現在,雖然既不gold這些工作:

musl/lib/libc.a:exit.o(.text.exit); 
musl/lib/libc.a(.text.exit) 

這工作:

*(.text.exit); 

的是,在gold缺少功能?或者我做錯了什麼,也許有 使用gold在 存檔中引用特定目標文件的特定符號的另一種方法?

回答

0

當使用鏈接腳本鋪設在地址空間符號,LD允許 指從一個特定的對象文件來靜態 庫裏面的語法如下特定符號:

存檔。答:object_file.o(.section僞。symbol_name)

這不完全是什麼語法的含義。當在鏈接描述文件中(或者在某個節點的重新下載或 objdump列表中)看到 「.section.symbol_name」,這是該節的全名,而 只有當您看到類似名稱的節時編譯時使用 -ffunction-sections選項。鑑於您的腳本 適用於ld,並且如果您只使用完整文件名通配符,則看起來您的musl庫確實是使用 -ffunction-sections編譯的,但這並不總是假設爲 true用於系統庫。因此,鏈接器並不是真的在搜索名爲「.text」的 節,該節定義了一個名爲「exit」的符號 - 相反,它只是尋找名爲「.text.exit」的節。微妙的 區別,但你應該知道它。

現在,雖然這些工作都沒有金: musl/lib/libc.a:exit.o(.text.exit); musl/lib/libc.a(.text.exit);

This works: *(.text.exit);

這是黃金缺失的功能嗎?或者我做錯了什麼,也許有 另一種方式來引用一個 存檔使用黃金中的特定對象文件的特定符號?

如果你看一下導致-Map輸出文件,我懷疑你會看到 目標文件的名稱被寫成「MUSL/lib目錄/文件libc.a(exit.o)」。 這就是您需要在腳本中使用的拼寫,並且因爲括號內有 ,所以您需要引用它。這:

"musl/lib/libc.a(exit.o)"(.text.exit) 

應該工作。如果你想要的東西,會在這兩個接頭工作,嘗試 是這樣的:

"musl/lib/libc.a*exit.o*"(.text.exit) 

或只是

"*exit.o*"(.text.exit) 
+0

非常感謝您使用引號語法工作。我還檢查了musl編譯標誌,實際上,這些包括-ffunction-sections。 –

相關問題