我有一个x86_64指令"vgatherqpd %ymm7,(%r9,%ymm1,8),%ymm3"
,我需要在Linux的信号处理程序中构建运行时的内存地址。信号处理程序ucontext uc_mcontext.gregs[XED_REG_R9]
给出了%r9
中包含的值。
但是,如何获得%ymm1
中包含的值?Linux似乎有一个sys/ucontext.h文件,其中有struct _libc_fpxreg
和_libc_xmmreg
字段,但我不确定如何理解它们。此外,没有reg_ymm。
感谢帮助解决这个问题。
1条答案
按热度按时间zpqajqem1#
在信号处理程序中获取avx寄存器
内核通过信号处理程序的第三个参数使所有寄存器对用户空间可用。然而,它并不像阅读结构字段那样清晰,主要是因为
struct _libc_fpxreg
是一个转移注意力的信息。由于我们对YMM寄存器感兴趣,这意味着我们运行的cpu将具有
xsave
,这是内核将用来存储FPU上下文的。下面我将集中讨论这一点,请记住,如果你想在旧的cpu上尝试这一点,你必须修改代码一点。xsave
xsave
由多个块组成,每个块对应于它所处理的特定cpu功能,具体取决于cpu。第一个块包含良好的旧x87 FPU堆栈和XMM寄存器,长度为512个字节。在块的末尾有一个保留空间,内核用它来跟踪缓冲区的大小和有效性,您也可以用它来验证它。请参阅struct _fpx_sw_bytes
。下一个块是一个头,后面是扩展,首先是ymm扩展,它存储ymm寄存器的高半部分(低半部分存储在第一块的xmm部分,就像它们共享处理器上的空间一样。
您可以在我之前链接的结构下面的结构中看到详细信息,但是架构编程手册(至少来自AMD)中没有确切描述。因此,我认为最好不要去管它的结构,而是使用cpu指令
xrstor
来读取它--毕竟它最清楚里面有什么。缓冲区位于何处
因为cpu要求
xsave
缓冲区是64字节对齐的,所以它最好不要是ucontext_t
这样的另一个结构的一部分。内核使用一些动态填充在堆栈上为它分配对齐的存储空间,并将指向它的指针存储到ucontext_t
结构(即uc_mcontext.fpregs
)。有关填充指针的分配和其他函数,请参见get_sigframe()
。但这还不是全部。如果您在64位模式下,此指针实际上就是您所需要的全部。在32位模式下,此指针指向传统的x87
fsave
缓冲区(与struct _libc_fpxreg
相同),xsave
缓冲区紧随其后。因此,必须将其大小添加到值中。代码
最后,从被中断的代码中获取
ymm0
如下所示:字符串