2017-12-10 23 views
1

リンクの問題に直面しています。私はそれを説明します:オブジェクトのリンク順序の問題

a.c:

extern void b(void); 
int main() { 
    a(); 
    return 0; 
} 

void a() { 
    b(); 
} 

b.S:

.extern a 
b: 
    jmp a 

がどんなに私がリンクします場合

gcc a.o b.o -o c 

または

gcc b.o a.o -o c 

未解決のシンボルが表示されます。これらのファイルをリンクするにはどうすればいいですか?私はそれらをマージすることはできません。例は無意味かもしれませんが、ポイントを示しています。私は何をアーカイブしようとしますか?

+0

いくつか質問があります:(a)そのターゲットは何ですか? yasm、nasm、それにgasのようなものはありません。 (b) 'a.c'でvoid a()を宣言する必要があります。そうしないと、コンパイルされません。 (c) 'b()'をC関数に変更し、あなたのリンクコマンドを試してみるとうまくいきます。私が知っている限り、あなたがリンクするために話している種類の依存関係を得る唯一の時間は、静的ライブラリのリンカの振る舞いです。問題の実例を示すために質問を更新できますか? – lockcmpxchg8b

+0

それはgnu asです。 私は大きく成長したオペレーティングシステムを書いており、このような例を作ることを考えました。 –

+0

sry、私の問題は私の最初の調査が明白であったことでした。適切なLinuxに移動すると、あなたのサンプルをうまく組み立てることができます。以下の解決策。 TL; DR:問題は、「b」がグローバルではないということです。 – lockcmpxchg8b

答えて

3

最初の調査:

a.c

extern void b(void); 
void a(void); 

int main() { 
    a(); 
    return 0; 
} 

void a() { 
    b(); 
} 

b.S

.extern a 
b: 
    jmp a 

b.c

void a(void); 

void b(void) 
{ 
    a(); 
} 

出力

$ gcc -c a.c 
$ gcc -c b.c -o b_gcc.o 
$ as b.S -o b_as.o 
$ gcc a.o b_gcc.o -o test_gcc 
$ gcc a.o b_as.o -o test_as 
a.o: In function `a': 
a.c:(.text+0x15): undefined reference to `b' 
collect2: error: ld returned 1 exit status 

だから何ができますか?なぜGCCでは大丈夫ですか?GASでは大丈夫ですか?

$ objdump -t b_gcc.o > syms_gcc 
$ objdump -t b_as.o > syms_as 
$ diff syms_gcc syms_as 
2c2 
< b_gcc.o:  file format elf64-x86-64 
--- 
> b_as.o:  file format elf64-x86-64 
5d4 
< 0000000000000000 l df *ABS* 0000000000000000 b.c 
9,12c8 
< 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 
< 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 
< 0000000000000000 l d .comment 0000000000000000 .comment 
< 0000000000000000 g  F .text 000000000000000b b 
--- 
> 0000000000000000 l  .text 0000000000000000 b 

わかりましたので、gccbグローバルシンボルになります。

$ as b.S -o b_as2.o 
$ gcc a.o b_as2.o 
$ 

成功:b.S.global bを試すことができます。したがってgcc/ldは、スタティックライブラリにないものに対してマルチパスシンボルの解像度を行います。しかしはグローバルシンボルを探します。最終的にはb.Sです:

.extern a 
.global b 
b: 
    jmp a 
+0

私のOSをリンクする際の問題を解決しました。ありがとう! –

+0

また、AT&Tの代わりにintelish構文を使用しませんでしたか? –

関連する問題