我正在实现一个编译器,它将模拟处理器的指令集编译为x86指令中的代码。在模拟指令集上运行的物理处理器是不存在的,在x86上只是模拟。在执行编译的机器代码(模拟)时,我想确保只读取或写入为模拟指定的内存。这有两个目的:1)在指定内存区域之外的访问可能意味着我的编译器中有一个bug。我想找到这样的虫子。2)指定内存区域之外的访问也可以意味着编译的源指令有逻辑错误,因此尝试访问在我的模拟中不存在的内存地址,因此应该引起错误。
在更简单的形式中,您可以想象我的代码如下所示:
void simulate(char* designated_memory, size_t len) {
// code intended to access *designated_memory till *(designated_memory + len - 1) only
}
在x86-64和/或Linux上是否有方法强制
simulate()
只能访问自己的堆栈和designated_memory
,而任何其他访问都会生成错误。代码可能如下所示:restrict_access_to(designated_memory, designated_memory + len - 1);
simulate(designated_memory, len);
remove_access_restriction();
C语言的解决方案很好;asm也很好。
更新:
听了杰斯特的话,我来试试这个:
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/mman.h>
int main() {
size_t pagesize = sysconf(_SC_PAGESIZE);
printf("pagesize...........: %lu\n", pagesize);
char* m;
size_t len = 12345;
len = (len + pagesize - 1) / pagesize * pagesize;
posix_memalign(&m, pagesize, len);
printf("page aligned memory: %lx - %lx\n", (unsigned long) m, (unsigned long) m + len);
printf("protecting 0 till m..."); fflush(stdout);
mprotect(0, (size_t) m, PROT_NONE);
printf("done\n");
printf("protecting (m + len) till ?..."); fflush(stdout);
mprotect(m + len, 0x7fffffff, PROT_NONE);
printf("done\n");
printf("trying to modify memory..."); fflush(stdout);
*(m - 1000) = 5;
printf("done: %i\n", *(m - 1000));
free(m);
}
哪些输出:
pagesize...........: 4096
page aligned memory: 9ac000 - 9b0000
protecting 0 till m...done
protecting (m + len) till ?...done
trying to modify memory...done: 5
Segmentation fault (core dumped)
我认为这表明在允许的区域之外修改数据仍然有效,但这不应该发生。
最佳答案
我不用翻译。我使用编译器将模拟的>指令编译为x86指令。出于性能原因,我不想在编译到x86的指令中包含所有的range checking>。
因此,您的任务与qemu
非常相似,当它执行模拟(例如ARM
onx86
)时,它将arm
指令转换为x86
指令,
所以我建议你看看qemu的源代码:http://wiki.qemu.org/Main_Page
下一个与您的项目非常相似的是valrgrind
,valgrind
的工作方式与您的工作方式非常相似:
它在某种虚拟机上执行程序来检查内存访问,
为了加快速度,它使用了cpu
(http://valgrind.org/)。
最后一个解决类似问题的开源项目是
https://github.com/google/sanitizers/tree/master/address-sanitizer
是的,它是插入指令的代码,但结果比jit
快得多,
如何测试生成的代码,但将性能保持在适当的水平,您可以在本视频中找到关于valgrind
内部的想法:
https://www.youtube.com/watch?v=Q2C2lP8_tNE