HW寄存器值(R15)在对外部库的函数调用期间未保存



我的代码是用C++编写的,并使用gcc版本4.7.2编译。它与用C编写的第三方库相链接,并用gcc 4.5.2编译。我的代码调用了一个函数initStuff((。在调试过程中,我发现调用initStuff((之前R15寄存器的值与该函数返回时的值不同。作为一个快速破解我做了:

asm(" mov %%r15, %0" : "=r" ( saveR15 ) );
initStuff();
asm(" mov %0, %%r15;" : : "r" (saveR15) );

这似乎目前有效。谁该受到谴责?我如何才能发现这是编译器问题,还是兼容性问题?

x86-64上的

gcc遵循System V ABI,后者将r15定义为被调用者保存的寄存器;任何使用这个寄存器的函数都应该保存和恢复它。

因此,如果这个第三方功能没有这样做,它就不符合ABI,除非有文件证明,否则这是罪魁祸首。AFAIK ABI的这一部分一直是稳定的,所以如果编译器生成的代码(带有默认选项(无法保存和恢复r15,那将是一个编译器错误。更有可能的是,第三方代码的某些部分使用汇编语言并且有缺陷,或者可以想象它是用非标准编译器选项构建的。

您可以深入研究它,或者作为一种变通方法,围绕它编写一个保存和恢复r15的包装器。您当前的解决方法并不安全,因为编译器可能会根据周围的代码重新排序您的asm语句。相反,您应该将对initStuff的调用放在带有save和restore的单个asm块中(声明它会破坏所有调用方保存的寄存器(,或者写一个";裸的";执行保存/恢复和调用的程序集包装,并改为调用它。(确保保持堆栈对齐。(

相关内容

  • 没有找到相关文章