我试图让Microsoft编译器生成IMAGE_REL_AMD64_ADDR64类型的重定位以进行测试。编译器更喜欢使用相对的32位LEA指令,这是可以理解的,但我认为以下程序要求它使用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位Windows上64位模式下的两个编译器),并分别得到相同的结果:
0000000169CE5A40 000000013FC86840 FFFFFFFFD5FA0E00 000000002A05F200
000000002A46D580 000000000040E380 FFFFFFFFD5FA0E00 000000002A05F200
然后我在Linux上使用GCC尝试了它,结果更具启发性,是一个链接器错误消息:'重定位被截断为适合:R_X86_64_32'。
所以只是为了确保我没有遗漏某些内容,这是两个编译器中的错误,除了在Linux上的GCC情况下,至少链接器会注意到问题而不是默默地给出错误的答案?
您如何让Microsoft编译器生成64位重定位?它们出现在Microsoft标准库中(这促使我尝试首先生成一些)所以大概必须有办法吗?
答案 0 :(得分:1)
请注意,这个错误是可以理解的,因为编译器并不知道偏移量最终会超过32位;基本上它是单独的编译和链接模型与x64指令集的怪癖之间的交互。
无论如何,事实证明你可以通过例如
获得实际的64位重定位char *p = a;