我想在x86 / x86_64上使用禁止的未对齐内存访问来模拟系统。 是否有一些调试工具或特殊模式来执行此操作?
在使用为SPARC或其他类似CPU设计的软件(C / C ++)时,我想在几台x86 / x86_64 PC上运行许多(CPU密集型)测试。但是我对Sparc的访问是有限的。
据我所知,Sparc总是检查内存读写中的对齐是否自然(从任何地址读取一个字节,但只有当地址可以被4整除时才允许读取4字节字)。
可能是Valgrind还是PIN有这样的模式?还是特殊的编译模式? 我正在寻找Linux非商业工具,但也允许使用Windows工具。
或者可能是EFLAGS中有秘密的CPU标志?
答案 0 :(得分:7)
我刚刚阅读了与维基百科文章Does unaligned memory access always cause bus errors?相关的问题Segmentation Fault。
在文章中,有一个非常罕见的Intel processor flags AC aka对齐检查的精彩提醒。
以下是如何启用它(来自Segmentation Fault):
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\norl $0x40000,(%esp)\npopf");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("pushf\norl $0x40000,(%rsp)\npopf");
# endif
#endif
一旦启用它就像/proc/cpu/alignment
中的ARM对齐设置一样工作,请参阅答案How to trap unaligned memory access?以获取示例。
此外,如果您正在使用GCC,我建议您启用-Wcast-align
警告。在为具有严格对齐要求(例如ARM)的目标构建时,GCC将报告可能导致未对齐内存访问的位置。
答案 1 :(得分:5)
这很棘手,我没有亲自完成,但我认为你可以通过以下方式完成:
x86_64 CPU(特别是我已经检查过Intel Corei7,但我猜其他人也有)有一个性能计数器MISALIGN_MEM_REF,用于计算未对齐的内存引用。
首先,您可以运行您的程序并使用Linux下的“perf”工具来计算您的代码所执行的错位访问次数。
更棘手和有趣的黑客是编写一个内核模块,该模块对性能计数器进行编程,以便在溢出时生成中断并使其溢出第一个未对齐的加载/存储。在内核模块中响应此中断,但向您的进程发送信号。
这实际上会将x86_64转变为不支持未对齐访问的核心。
这不会很简单 - 除了代码之外,系统库还使用未对齐的访问,因此将它们与您自己的代码分开会很棘手。
答案 2 :(得分:4)
GCC 和 Clang 都内置了 UndefinedBehaviorSanitizer。其中一项检查 alignment
可以通过 -fsanitize=alignment
启用。它将发出代码以在运行时检查指针对齐情况,并在取消引用未对齐的指针时中止。
答案 3 :(得分:0)
也许你可以通过所有对齐的动作以某种方式编译到SSE。使用movaps
进行的未对齐访问是非法的,可能会在其他架构上进行非法的未对齐访问。