2014-03-28 71 views
2

我試圖讓Microsoft編譯器爲測試目的生成IMAGE_REL_AMD64_ADDR64類型的重定位。編譯器傾向於使用相對32位LEA指令,這是可以理解的,但我認爲下面的程序將要求它使用一個64位的搬遷:IMAGE_REL_AMD64_ADDR64 64位重定位

#include <stdio.h> 

char a[5000000000]; 
char b[5000000000]; 

int main(){ 
    printf("%p %p %p %p\n", a, b, b - a, a - b); 
} 

它沒有,所以我試了一下MinGW的(在64位模式的編譯器對64位Windows),並得到了相同的結果,分別爲:

0000000169CE5A40 000000013FC86840 FFFFFFFFD5FA0E00 000000002A05F200 
000000002A46D580 000000000040E380 FFFFFFFFD5FA0E00 000000002A05F200 

然後我與海灣合作委員會試圖在Linux上,結果是更多的啓發,是一個連接錯誤消息:'重新定位被截斷爲適合:R_X86_64_32'。

所以爲了確保我沒有錯過任何東西,這是兩個編譯器中的一個錯誤,除了在Linux上的GCC的情況下,至少鏈接器注意到問題而不是默默地給出錯誤的答案?

你如何讓微軟編譯器生成64位重定位?它們出現在微軟的標準庫中(這促使我試圖首先產生一些),所以推測必須有辦法?

回答

1

請注意,錯誤是可以理解的,因爲編譯器不知道偏移量最終會超過32位;基本上它是獨立編譯和鏈接模型與x64指令集的怪癖之間的交互。

無論如何,事實證明,你可以得到實際的64位重定位。

char *p = a;