2016-12-24 10 views
2

私はトピックを読んでいますGCC -fPIC optiong ++ -fPICは位置独立コードを生成しません

私はtestlib.cppを作成しました。

int foo(int num) 
{ 
    int result; 

    if (num != 0) 
    { 
     result = 1; 
    } 
    else 
    { 
     result = 2; 
    } 

    return result; 
} 

Iは G ++ -c -o testlib.o testlib.cpp とTESTLIBの G ++ -fPIC -C -o testlib.o testlib.cpp 対応objdumpsほどコンパイル.oのは同じです:

objdumpの-d testlib.o -Mインテル

testlib.o:  file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z3fooi>: 
    0: 55      push ebp 
    1: 89 e5     mov ebp,esp 
    3: 83 ec 10    sub esp,0x10 
    6: 83 7d 08 00    cmp DWORD PTR [ebp+0x8],0x0 
    a: 74 09     je  15 <_Z3fooi+0x15> 
    c: c7 45 fc 01 00 00 00 mov DWORD PTR [ebp-0x4],0x1 
    13: eb 07     jmp 1c <_Z3fooi+0x1c> 
    15: c7 45 fc 02 00 00 00 mov DWORD PTR [ebp-0x4],0x2 
    1c: 8b 45 fc    mov eax,DWORD PTR [ebp-0x4] 
    1f: c9      leave 
    20: c3      ret 

そして、引数のアドレスは、-fPICでコンパイルするときに、jeコマンドが位置に依存しないようにジャンプすることが期待されました。したがって、2つのobjダンプは異なるはずです。私は間違って何を理解するのですか?

+0

x86ショート・ジャンプ(<±127バイト)は常に位置関係にあります - つまり、32ビット・モードでのジャンプは明示的な完全なアドレスを使用して書き込むことができますが、2ではなく5バイト、善意の精神でこのような指示を出すだろう。 –

+0

@MatteoItalia、ご意見ありがとうございます!申し訳ありませんが、私はそれを投票しましたが、私のスマートフォンで私の投票を元に戻すので、SOがそれを禁じているので、もう一度アップフォートすることはできません。 :((( – JenyaKh

+1

心配しないでください、それはいつも起こります=) –

答えて

2

-fPICは、デフォルトでは、より新しいgccバージョンでオンです。コードもオプションを指定しない位置に依存しないです:

eb 07     jmp 1c <_Z3fooi+0x1c> 

これは分解がシンボルを印刷し、その明確にするためのオフセットた場合でも、2バイトのオペコードを見て、独立した立場です。

コンパイラは、そのオプションのどんなショートジャンプに対しても、位置に依存しないコードを生成する可能性が非常に高いことに注意してください。

このフラグはあまり役に立ちません。しかし-fno-PICスイッチでPICを無効にすることができます。

+1

答えをありがとう、ありがとう、私はそれが位置独立コードであることを理解しました: "74 09"はさらに09バイトをジャンプし、 "eb 07"しかし、今、私はg ++ -fno-pic -c -o testlib.o testlib.cppとしてコンパイルしようとしましたが、同じobjdumpを得ています。なぜ、-fno-picが機能しないのですか? – JenyaKh

+0

あなたが '-fno-PIC'を試したことがありますか?またジャンプには当てはまらないかもしれませんか? –

+0

@ Jean-FrançoisFabre" -fPICは新しいgccバージョンではデフォルトでオンになっています " - プルーフリンク – yugr

2

GCCコンパイラは意図的に位置を生成する機能を持っていません。依存コードです。そのような能力は実際上全く意味を持たないであろう。

GCCが実行できることは、実際には位置非依存コード(-fPICオプション付き)、または「何でも」コード(-fPICオプションなし)のいずれかを生成します。 「何でも」モードを使用すると、コンパイラは位置依存の問題を無視し、コード生成に関する他の考慮事項の決定に基づいています。これは、-fPICを要求していなくても、ポジションに依存しないコードを純粋に "事故"に終わらせる可能性があることを意味します。位置非依存コードが他の理由(等)

違いを観察したい場合は、より代表的な例が必要です。あなたの例では、すべてのジャンプがジャンプの近くにあります。それらは当然、相対(オフセットベース)のジャンプ命令によって実装されます。感知できるコンパイラは、このような状況でこのような相対ジャンプを使用します。そして、その副作用は、明示的に要求していなくても、位置に依存しないコードで終わることです。この場合、位置独立性は「無料」になる。

違いを観察したい場合は、位置独立性が「無料」にならない例が必要です。あなたは、位置独立性と他の重要な要因(効率やサイズなど)との間に明確なトレードオフを伴うものが必要です。あなたがそのような例を考え出すと、-fPICの違いがわかります。

+0

ありがとうございました。それは非常に賢明です。しかし、他の答えでは、-fno-PICコンパイラオプションを使用して位置依存コードを取得することが提案されています。私はそれを試みましたが、それは助けになりませんでした。この点について何かコメントしていただけますか?私は本当に位置依存コードを見たいと思っています。 – JenyaKh

+1

@JenyaKh:私が上で述べたように、あなたの例では不可能です。 GCCからリクエストすることができます:「ポジションに依存しないコードが必要です」(-fpic、-fPIC、位置独立性保証)、または「私は気にしません」(-fno-pic '、' -fno-PIC'、位置独立性は保証されません)。どんなオプションを使用しても、これらの2つのモードを切り替えるだけです。 GCCに何らかの形で意図的に生成されたコードを強制的に "位置依存"にさせるオプションはありません。このようなオプションは全く意味をなさないでしょう。違いを見たい場合は、別の例が必要です。 – AnT

+0

さて、説明をいただきありがとうございます! – JenyaKh

関連する問題