2014-03-28 33 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;