【发布时间】:2014-01-30 20:47:29
【问题描述】:
背景
我正在编写一个框架,以实现在模拟器和未修改的主机软件中运行的 RTL 的联合模拟。主机软件是为控制实际硬件而编写的,通常以以下两种方式之一工作:
- 通过驱动程序读取/写入调用
- 使用 mmap 进行内存映射访问
前一种情况非常简单 - 编写一个库来实现与驱动程序相同的读/写调用,并在运行模拟时链接到它。这一切都非常有效,我可以运行未经修改的生产软件作为 RTL 模拟的激励。
事实证明,第二种情况比第一种要困难得多……
陷印mmap
最初我以为我可以使用LD_PRELOAD 来拦截 mmap 调用。在我的mmap 实现中,我会分配一些页面对齐的内存,然后分配mprotect 它并设置一个信号处理程序来捕获SIGSEGV。
这种方法存在很多问题:
读取与写入
我可以从siginfo_t->si_addr 确定访问的地址,但不能确定访问是读取还是写入。
捕获重复访问
在信号处理程序中,我需要取消保护内存区域,否则一旦我的处理程序退出并且主机代码将永远无法继续,我将重复SIGSEGVs。但是,如果我取消对该区域的保护,那么我的信号处理程序将不会捕获后续访问。
信号处理程序的麻烦
在模拟器驱动 RTL 并返回结果时阻塞信号处理程序违反了各种编程规则 - 特别是考虑到模拟器可以触发各种其他事件并在从该访问返回结果之前执行任意代码。
其他方法
我想知道是否可以创建一个类似于磁盘的文件对象,而不是在缓冲区上使用mprotect。我没有发现任何信息表明这是可行的。
问题
是否可以捕获对 mmap 区域的所有访问以及如何捕获?
- 访问需要阻塞一段不确定的时间(模拟器运行时)
- 读取访问需要检索我的陷阱放置的新值
假设LD_PRELOAD 和mprotect 是最佳路线:
- 我能否确定访问是读取调用还是写入调用?
- 由于必须取消
mprotect该区域,如何捕获后续访问?
相关问题
【问题讨论】:
标签: c linux system-calls mmap signal-handling