WinAPI:是否需要在可执行的内存映射文件上调用FlushInstructionCache?

我已经写了一个简短的程序来读取一个Windows OBJ文件,并find。文本部分,并在其中运行的代码。 要做到这一点,我做了以下的Windows API函数调用( 完整代码[gist.github.com] ,对于那些感兴趣的人):

HANDLE FileHandle = CreateFile("lib.obj", GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); HANDLE MappingHandle = CreateFileMapping(FileHandle, 0, PAGE_EXECUTE_READ, 0, 0, 0); void *Address = MapViewOfFile(MappingHandle, FILE_MAP_EXECUTE | FILE_MAP_READ, 0, 0, 0); 

然后在文件中find.text部分,并将指针指向C ++中的函数指针,然后调用该函数。 这实际上似乎为我工作。

我有没有在映射到文件的虚拟内存范围上调用FlushInstructonCache错误?

我问这是因为我最近在读VirtualAlloc文档,并在底部注意到:

当创build一个可执行的区域时,一旦代码已经设置好,调用程序将负责通过对FlushInstructionCache的适当调用来确保caching一致性。 否则,尝试从新的可执行区域执行代码可能会产生不可预知的结果。

我的代码可能会导致CPU执行指令caching中的旧指令吗?

MapViewOfFile或CreateFileMapping页面上没有这样的注释。

如果您只使用MapViewOfFile将文件内容加载到内存中,则应该没有问题。

如果修改内存中的内容,则需要在执行代码之前刷新instructioncache,因为它可能以未修改的形式存在于缓存中,并且可能会在未经您修改的情况下执行。

我使用这个词可能是因为两件事:

  1. 它取决于处理器体系结构,处理器是否检测到将要执行的内存写入[某些处理器甚至没有硬件来注册写入指令高速缓存中的数据 – 因为这是非常罕见的,所以不太可能]。

  2. 因为很难预测高速缓存中可能存在什么 – 处理器有各种“巧妙”的方式来预取和一般的“填充”高速缓存。

显然, VirtualAlloc没有机会包含你想要的数据,所以在那里提到它,因为在执行之前你总是写信给它。

例如,修改包括“修正绝对地址”(如果你想完成一个加载一些复杂的项目来执行它,你必须做的事情),或者如果你写一个调试器,当你设置一个断点指令在x86上的INT 3指令。

“修改”的第二种情况是如果你卸载文件,并加载一个不同的文件(可能是“相同”的文件,但重建,例如),在这种情况下,以前执行的代码可能仍然在缓存中,你会得到神秘的“为什么我的变化没有做到我所期待的”