I was trying to get the Microsoft compiler to generate a relocation of type IMAGE_REL_AMD64_ADDR64 for testing purposes. The compiler prefers to use relative 32-bit LEA instructions, which is understandable, but I thought the following program would require it to use a 64-bit relocation:
#include <stdio.h>
char a[5000000000];
char b[5000000000];
int main(){
printf("%p %p %p %p\n", a, b, b - a, a - b);
}
It didn't, so I tried it with MinGW (both compilers in 64-bit mode on 64-bit Windows), and got the same results, respectively:
0000000169CE5A40 000000013FC86840 FFFFFFFFD5FA0E00 000000002A05F200
000000002A46D580 000000000040E380 FFFFFFFFD5FA0E00 000000002A05F200
I then tried it with GCC on Linux and the result was more enlightening, being a linker error message: 'relocation truncated to fit: R_X86_64_32'.
So just to make sure I'm not missing something, this is a bug in both compilers, except that in the case of GCC on Linux, at least the linker notices the problem instead of silently giving a wrong answer?
And how do you get the Microsoft compiler to generate 64-bit relocations? They occur in the Microsoft standard library (which is what prompted me to try to generate some in the first place) so presumably there must be a way?