2017-08-03 19 views
1

リンカスクリプトを使用してアドレス空間にシンボルをレイアウトする場合、ldは に、 の構文を持つ静的ライブラリからの特定のシンボルを参照できます。GNUゴールドリンカーを使用したスタティックライブラリの特定のシンボルの参照

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

goldではなくldを使用して、そのような指示を無視しているようです。 リンク処理は成功します。ただし、特定の場所に特定の シンボルを配置してgoldとし、結果のシンボルレイアウト を使用してnmを使用するか、またはマップファイルを参照する場合、シンボルは予定されている の位置にありません。

gcc 5.4.0のentretyに、 という静的にコンパイルされたダミーのhelloワールドプログラムを使用して小さなテストケースを作成しました。 Cライブラリはmusl libc(公式のgitリポジトリの マスターブランチの最後のコミット)です。 binutilsについては、公式のgitリポジトリのmasterブランチで最後にコミットした も使用します。

Iは、静的 ライブラリ(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:(-Map ld/goldフラグを使用して得られた)私は、マップファイルをチェックしていコンパイルとリンクした後

# 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) 

.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は することができますが、次の構文を持つ静的 ライブラリ内の特定のオブジェクト・ファイルから特定のシンボルを参照してください。 a:object_file.o(セクション。シンボル名)

これは構文が意味するものではありません。リンカスクリプトで ".section.symbol_name"が表示されている場合(またはreadelfまたは セクションのobjdumpリスト)、それはセクション全体の名前で、 という名前のセクションしか表示されませんコンパイル時に -ffunction-sectionsオプションを使用してください。あなたのスクリプト がldで動作し、 金で完全なファイル名のワイルドカードを使用した場合、あなたのmuslライブラリは確かに -funcation-sectionsでコンパイルされているようですが、それは常に システムライブラリ用。したがって、リンカーは実際には "exit"という名前のシンボルを定義する ".text"という名前の セクションを探していません。代わりに という名前のセクションを探しています。 ".text.exit"微妙な 違いが、あなたはそれに気づくべきです。今

、どちらも金でこれらの作品の中: MUSL/libに/ libc.aは:exit.o(.text.exit)。 musl/lib/libc.a(.text.exit);

これは動作します: *(.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コンパイルフラグもチェックしていましたが、実際にはこれらの関数セクションが含まれています。 –

関連する問題