我可以为x86-64架构中使用gcc编译器时的不同变量选择RIP相对或绝对寻址吗?

3

我编写了自己的链接脚本,将不同的变量放入两个不同的数据段(A和B)中。

A与零地址相连; B与代码相邻,位于高地址空间(高于4G,这在x86-64的常规绝对寻址中不可用)。

可以通过绝对寻址访问A,但不能通过RIP相对寻址访问; 可以通过RIP相对寻址访问B,但不能通过绝对寻址访问。

我的问题是:在gcc中是否有办法为不同的变量选择RIP相对或者绝对寻址?也许通过某些类似于#pragma的注释?


目前我们有一些使用A部分的代码,而且这些代码只允许绝对寻址。(该代码直接从一个地方复制到一个运行时堆中,并被执行) - xingchong
1个回答

1

如果不修改GCC源代码,你无法让它发出32位绝对寻址,但有些情况下gcc会使用64位绝对地址。


-mcmodel=medium将大对象放入单独的部分,使用64位绝对地址来处理大数据部分(所有对象都需要同意的大小阈值由-mlarge-data-threshold=设置)。但仍然对所有其他变量使用RIP相对寻址。

有关不同内存模型的更多信息,请参见x86-64 System V ABI文档。或者查看GCC文档以了解-mcmodel=-mlarge-data-threshold=: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
默认设置为-mcmodel=small:所有内容都在2GiB范围内,因此可以使用RIP相对寻址。对于非PIE可执行文件,这是虚拟地址空间的低2GiB,因此静态地址可以是32位绝对符号扩展立即数或disp32地址模式。

int a[1000000];
int b[1];

int fa() {   return a[0];  }
int fb() {   return b[0];  }

汇编输出( Godbolt):

# gcc9.2 -O3 -mcmodel=medium
fa():
        movabs  eax, DWORD PTR [a]     # 64-bit absolute address, special encoding for EAX
        ret
fb():
        mov     eax, DWORD PTR b[rip]
        ret

如果要加载到除了AL/AX/EAX/RAX之外的寄存器中,GCC会使用movabs r64,imm64来使用地址,然后使用mov reg,[reg]

你无法让gcc对A部分使用32位绝对寻址。它总是使用64位绝对寻址,永远不会使用[array + rdx * 4][abs foo](NASM语法)。而且永远不会使用mov edi,msg(imm32)将地址放入寄存器中,而是始终使用mov rdi,qword msg(imm64)。

GCC将b放在.lbss部分,将a放在常规的.bss部分。可能可以在上面使用__attribute__((section("name")))

        .globl  b
        .section        .lbss,"aw"           # "aw" = allocate(?), writeable
        .align 32
        .size   b, 4000000
b:
        .zero   4000000

        .globl  a
        .bss                      # shortcut for .section
        .align 4
a:
        .zero   4

不起作用的事情:

  • 在每个函数上使用__attribute__((optimize("mcmodel=large")))。实际上并不起作用,并且无论如何都是针对函数而不是变量。
  • https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html没有记录与内存模型或大小相关的x86或常见变量属性。唯一的x86特定变量属性是ms vs gcc结构布局。

    有关函数和类型的x86特定属性,但这些属性也没用。


可能的黑客攻击:

将所有Section-A变量放入一个大结构体中,比任何Section-B全局/静态对象都要大。 可能在末尾用虚拟数组进行填充以使其更大:您的链接器脚本可能可以避免为该虚拟数组分配额外空间。

然后使用-mcmodel = medium mlarge-data-threshold = 编译该大小。


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