2016-12-13 10 views
0

グローバルオフセットテーブルなしで複数のPICファイルをコンパイルする際に問題が発生しています。GOTなしの位置独立コードの使用

アセンブリはGOTへの参照が含まれていない次のパラメータを使用してonefile.c最初のファイルのコンパイル:

アームなし、EABI-gcc.exe first.c -nosdlib -fPIE -marchを=のARMv7-A -o first.o

first.c

void function(); 
int main(); 

int main() 
{ 
    void* function_pointer; 
    function_pointer = &function; 
} 

void function() 
{ 

} 

アセンブリ:

.text:00008000 ; int __cdecl main(int argc, const char **argv, const char **envp) 
.text:00008000     EXPORT main 
.text:00008000 main 
.text:00008000 
.text:00008000 var_8   = -8 
.text:00008000 var_s0   = 0 
.text:00008000 
.text:00008000     STR    R11, [SP,#-4+var_s0]! 
.text:00008004     ADD    R11, SP, #0 
.text:00008008     SUB    SP, SP, #0xC 
.text:0000800C     LDR    R3, =(function - 0x8018) 
.text:00008010     ADD    R3, PC, R3 ; function 
.text:00008014     STR    R3, [R11,#var_8] 
.text:00008018     MOV    R3, #0 
.text:0000801C     MOV    R0, R3 
.text:00008020     SUB    SP, R11, #0 
.text:00008024     LDR    R11, [SP+var_s0],#4 
.text:00008028     BX    LR 
.text:00008028 ; End of function main 

アドレス0x8010では、レジスタR3はGOTを使用せずに関数 "関数"のアドレスを持っています。

しかし、複数の.cにファイルを分割した.hは結果が

アームなし-EABI-gcc.exe twofiles1.c twofiles2.c -nostdlib -fPIE -march =を変更しているファイルARMv7--o twofiles.o

twofiles1.c:

#include "twofiles1.h" 

int main() 
{ 
    void* function_pointer; 
    function_pointer = &function; 
} 

twofiles1.h:

#include "twofiles2.h" 

int main(); 

twofiles2.c:

void function() 
{ 

} 

twofiles2.h:

void function(); 

アセンブリ:機能 "機能" のアドレスがでを計算する方法

.text:00008000 ; int __cdecl main(int argc, const char **argv, const char **envp) 
.text:00008000     EXPORT main 
.text:00008000 main 
.text:00008000 
.text:00008000 var_8   = -8 
.text:00008000 var_s0   = 0 
.text:00008000 
.text:00008000     STR    R11, [SP,#-4+var_s0]! 
.text:00008004     ADD    R11, SP, #0 
.text:00008008     SUB    SP, SP, #0xC 
.text:0000800C     LDR    R2, =(_GLOBAL_OFFSET_TABLE_ - 0x8018) 
.text:00008010     ADD    R2, PC, R2 ; _GLOBAL_OFFSET_TABLE_ 
.text:00008014     LDR    R3, =(function_ptr - 0x18054) 
.text:00008018     LDR    R3, [R2,R3] ; function 
.text:0000801C     STR    R3, [R11,#var_8] 
.text:00008020     MOV    R3, #0 
.text:00008024     MOV    R0, R3 
.text:00008028     SUB    SP, R11, #0 
.text:0000802C     LDR    R11, [SP+var_s0],#4 
.text:00008030     BX    LR 
.text:00008030 ; End of function main 

お知らせ GOT。それは私が控えたいものです 最初の結果と同じアセンブリを達成する解決策はありますか?

+0

。 –

答えて

0

コンパイラは一度に1つのモジュールを参照するので、異なるコンパイル単位でGOTを使用するように指示します。 PICコードGCC manについて

-fpic

を言うターゲットマシンのためにサポートされている場合、共有ライブラリでの使用に適した位置独立コード(PIC)を生成します。 このようなコードは、グローバルオフセットテーブル(GOT)を通じてすべての定数アドレスにアクセスします。ダイナミックローダは、プログラムの起動時にGOTエントリを解決します(ダイナミックローダはGCCの一部ではなく、オペレーティングシステムの一部です)。リンクされた実行可能ファイルのGOTサイズがマシン固有の最大サイズを超えている場合、リンカから-fpicが機能しないことを示すエラーメッセージが表示されます。その場合は、代わりに-fPICを使用して再コンパイルしてください。 (これらの最大値はSPARCでは8k、AArch64では28k、m68kとRS/6000では32kです。x86にはこのような制限はありません) 位置独立コードは特別なサポートが必要なため、特定のマシンでのみ動作します。 x86の場合、GCCはSystem VのPICをサポートしますが、Sun 386iはサポートしません。 IBM RS/6000用に生成されるコードは、常に位置に依存しません。あなたはGOTを避けることができ、単一の翻訳単位としてプログラムをコンパイルする場合のみ

重点鉱山

+0

ファイルを分割してもGOTを使用しない便利な方法はありますか? – Halastra

+0

AFAIKいいえ、ありません。 – LPs

関連する問題