Reputation: 676
I have a C
driver file which declares an extern
function in order to use it in my asm
file. I am on a Windows 7 x64 machine.
I assembled the asm
file with NASM
with this command:
nasm avxmain.asm -f win64 -o avxmain.o
Then I compiled the C
file like this:
gcc avxdriver.c -c -m64 -o avxdriver.o
Linking it all together, I ran:
gcc avxdriver.o avxmain.o -o final
Here are the errors I am getting:
avxmain.o:G:\Desktop\CPSC240:(.text+0x50): relocation truncated to fit: R_X86_64_32 against `.bss'
avxmain.o:G:\Desktop\CPSC240:(.text+0xb9): relocation truncated to fit: R_X86_64_32 against `.data'
avxmain.o:G:\Desktop\CPSC240:(.text+0xc2): relocation truncated to fit: R_X86_64_32 against `.data'
avxmain.o:G:\Desktop\CPSC240:(.text+0x14e): relocation truncated to fit: R_X86_64_32 against `.bss'
collect2: error: ld returned 1 exit status
avxdriver.c
file:#include <stdio.h>
#include <stdint.h>
extern double avxdemo();
int main()
{
double return_code = -99.9;
printf("%s","This program will test for the presence of AVX (Advanced Vector Extensions) also known as state component number 2.\n");
return_code = avxdemo();
printf("%s %1.12lf\n","The value returned to the driver is ", return_code);
printf("%s","The driver program will next send a zero to the operating system. Enjoy your programming.\n");
return 0;
}
avxmain.asm
file:I posted it here because it is very long due to comments provided by the professor.
I have tried running the -fPIC
and -mcmodel=medium
option. I still get the same errors.
I'm completely lost and confused since this is the sample project I am supposed to run for my class. This subject is brand new to me. I've spent about half my day searching these errors and trying different things. I just need to be pointed in the right direction.
Upvotes: 0
Views: 7763
Reputation: 39551
You should use objdump -d
on avxmain.o
to find out which statements the linker is complaining about. However it's pretty clear which instructions are the problem:
xrstor [backuparea]
vmovupd ymm0, [testdata]
vmovupd ymm1, [testdata+32]
xsave [backuparea]
The problem, as Drew McGowen explained, is that the 64-bit instruction set has no way of encoding these addresses a 64-bit values in an instruction. Instead they become 32-bit signed displacements that are signed extended to 64-bits to create the effective address. As apparently Windows loads 64-bit drivers in the address range starting at 0xFFFFF88`00000000
the truncated 32-bit displacements won't get sign extended back to the correct value.
You should be able to use RIP relative addressing, like Drew McGowen suggested, to work around the problem. In that case the assembler should generate PC relative (RIP relative) relocations that the linker won't complain about:
xrstor [rel backuparea]
vmovupd ymm0, [rel testdata]
vmovupd ymm1, [rel + testdata+32]
xsave [rel backuparea]
Upvotes: 2
Reputation: 11706
The problem is that general x64 instructions do not allow direct 64-bit addresses in their encodings. There are two ways around this:
Use the movabs rax, symbolNameHere
instruction to set rax
to the address, then use [rax]
to access data at that address.
Use [rel symbolNameHere]
as the operand; this creates a PC-relative reference to symbolNameHere
. It's encoded as a 32-bit signed offset from whatever rip
will be when that instruction is executed.
Method 1 allows you to encode the absolute address in the instruction, whereas method 2 is smaller code (you can always do lea rax, [rel symbolNameHere]
to get the same effect as method 1).
Upvotes: 4