在x86-64架构上,使用自定义调用约定的GCC修改/自定义目标

4
我想知道是否能够(在合理的时间内)修改现有的gcc编译目标或定义一个新的编译目标。目标是进行轻微的修改,例如更改返回函数结果的寄存器或使用不同于x86-64标准SystemV ABI的寄存器传递参数。
例如,如果我希望将函数返回值的寄存器从RAX更改为R8,或者使用YMM0和YMM1返回64字节结构体,而不需要自己使用x86汇编代码来实现。
(背景)我正在开发一个小型自编写操作系统,因此我想知道是否可以不遵循System-V ABI或Microsoft用于Windows的ABI。与现有库和其他东西的兼容性并不重要,因为操作系统中的每行代码都是由我编写的。我只使用gcc、ld和objdump。没有gdb等调试工具。
如果可能,在gcc源代码或配置文件中应该在哪里进行这样的修改?我已经克隆了gcc git存储库,但找不到这样修改的起点。

gcc有命令行选项可以将寄存器设置为易失性/非易失性(如 -fcall-used-reg),但没有其他更改调用约定的选项。我不知道这有多容易/难以调整。 我猜换一个返回值寄存器可能很容易。 使用一对向量寄存器也可能不太麻烦; x86-64 SysV对一对xmm寄存器就是这样做的(但出于某种原因没有更宽的)。 - Peter Cordes
1个回答

4

这些内容有点理论化,因为我从未尝试过完全自定义。但我认为这将是一个合理的项目。

GCC内部文档记录在GCC内部手册中。你可能不需要详细阅读所有内容,但至少应该尝试了解基本结构概述。它高度可配置。

调用约定在“机器描述”中配置,这是后端的一部分。对于你想要进行的更改类型来说最重要的部分是关于堆栈布局和调用约定的描述。例如,你可以使用TARGET_FUNCTION_VALUE hook更改函数返回标量值的方式,尽管你可能还需要修改机器描述的其他部分以正确处理寄存器分配。

我建议从一个非常小的修改开始,并彻底测试它(至少通过验证汇编程序输出是否符合预期)。然后,你可以根据需要实现其他修改。在开发更改时,请保留一组测试用例;这些测试用例将非常有用,以确保更改不会与彼此产生意外的相互作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接