重定位被截断以适合:R_X86_64_32

时间:2014-08-14 17:46:33

标签: c gcc assembly extern

我有一个C驱动程序文件,它声明了一个extern函数,以便在我的asm文件中使用它。我在Windows 7 x64机器上。

我使用此命令将asm文件与NASM组合在一起:

  

nasm avxmain.asm -f win64 -o avxmain.o

然后我编译了这样的C文件:

  

gcc avxdriver.c -c -m64 -o avxdriver.o

把它们连在一起,我跑了:

  

gcc avxdriver.o avxmain.o -o final

以下是我遇到的错误:

  

avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0x50):重定位被截断为   适合:对于`.bss'

,R_X86_64_32      

avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0xb9):重定位被截断为   适合:对于`.data'

,R_X86_64_32      

avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0xc2):重定位被截断为   适合:对于`.data'

,R_X86_64_32      

avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0x14e):重定位被截断为   适合:R_X86_64_32反对`.bss'

     

collect2:错误:ld返回1退出   状态


avxdriver.c档案:

#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档案:

http://pastebin.com/CfnjbpXM

我在这里发帖是因为教授提供的评论很长。


我尝试过运行-fPIC-mcmodel=medium选项。我仍然得到同样的错误。 我完全迷失了,因为这是我应该为我的课程运行的示例项目。这个主题对我来说是全新的。我花了大约一半的时间来搜索这些错误并尝试不同的事情。我只需指出正确的方向。

2 个答案:

答案 0 :(得分:4)

问题是一般的x64指令不允许在其编码中使用直接的64位地址。有两种方法:

  1. 使用movabs rax, symbolNameHere指令将rax设置为该地址,然后使用[rax]访问该地址的数据。

  2. 使用[rel symbolNameHere]作为操作数;这会创建与symbolNameHere的PC相关引用。它被编码为执行该指令时所有rip的32位有符号偏移量。

  3. 方法1允许您对指令中的绝对地址进行编码,而方法2则是较小的代码(您可以始终执行lea rax, [rel symbolNameHere]以获得与方法1相同的效果。)

答案 1 :(得分:2)

您应该在objdump -d上使用avxmain.o来查找链接器抱怨的语句。但是很清楚哪些指令是问题所在:

xrstor     [backuparea]
vmovupd ymm0, [testdata]  
vmovupd ymm1, [testdata+32] 
xsave      [backuparea] 

正如Drew McGowen解释的那样,问题在于64位指令集无法在指令中将这些地址编码为64位值。相反,它们变为32位有符号位移,这些位移被签名扩展为64位以创建有效地址。显然,Windows在0xFFFFF88`00000000开始的地址范围内加载64位驱动程序,截断的32位位移不会将符号扩展回正确的值。

你应该能够像Drew McGowen建议的那样使用RIP相对寻址来解决这个问题。在这种情况下,汇编程序应生成PC相对(RIP相对)重定位,链接器不会抱怨:

xrstor     [rel backuparea]
vmovupd ymm0, [rel testdata]  
vmovupd ymm1, [rel + testdata+32] 
xsave      [rel backuparea]