【发布时间】:2018-08-15 00:36:32
【问题描述】:
我目前正在使用 Pin,我想获取存储指令正在写入的值。我面临的问题是,即使我可以在写指令之前插入一个回调(使用 IPOINT_BEFORE)并从将要写入的内存地址中获取一个值,但它显然不是正确的,因为写入没有还没有发生。我不能同时使用 IARG_MEMORYWRITE_EA 和 IPOINT_AFTER 作为参数。
当有加载指令时,我设法让它工作,因为该值已经在内存中。代码如下。
void Read(THREADID tid, ADDRINT addr, ADDRINT inst){
PIN_GetLock(&globalLock, 1);
ADDRINT * addr_ptr = (ADDRINT*)addr;
ADDRINT value;
PIN_SafeCopy(&value, addr_ptr, sizeof(ADDRINT));
fprintf(stderr,"Read: ADDR, VAL: %lx, %lu\n", addr, value);
.
.
.
PIN_ReleaseLock(&globalLock);
}
VOID instrumentTrace(TRACE trace, VOID *v)
{
for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {
if(INS_IsMemoryRead(ins)) {
INS_InsertCall(ins,
IPOINT_BEFORE,
(AFUNPTR)Read,
IARG_THREAD_ID,
IARG_MEMORYREAD_EA,
IARG_INST_PTR,
IARG_END);
} else if(INS_IsMemoryWrite(ins)) {
INS_InsertCall(ins,
IPOINT_BEFORE,
(AFUNPTR)Write,
IARG_THREAD_ID,//thread id
IARG_MEMORYWRITE_EA,//address being accessed
IARG_INST_PTR,//instruction address of write
IARG_END);
}
}
}
}
如何获取存储指令写入内存的值?
【问题讨论】:
-
在多线程代码中,您一次从内存位置读取的值不一定与您让指令实际执行时出现在寄存器中的值相同。当然,当指令不是简单的
mov寄存器的加载或存储时,加载/存储数据永远不会出现在架构寄存器中。例如add [rsi], eax存储添加结果(在一个隐藏的内部临时文件中加载并生成它之后)。 -
我想做的是维护一个虚拟缓存。我已经在使用Cache Simulator 来跟踪所有行的标签和一致性状态。但我必须用检测程序使用的值实际填充该虚拟缓存。对于阅读,我已经可以做到这一点。您对如何获取存储指令将写入的值有任何建议吗?我想,我不一定需要在写完之后从内存中获取它。如果有办法获取存储指令将写入的数据对我来说很好。
-
IDK,我根本没用过 PIN。但是您确定需要为缓存模拟有效数据吗?如果只想模拟缓存命中/未命中,则根本不需要跟踪数据内容,只需跟踪每行的标记/MESIF 状态。除非您尝试模拟 silent store optimizations 或其他会产生与数据相关的缓存变脏或失效的东西。
-
不管怎样,你想用你维护的这个“虚拟缓存”做什么?如果您确实需要数据,不同的用例可能会或可能不会关心读取实际加载/存储数据与之前/之后的内存内容之间的竞争条件。
-
我需要数据用于在处于无效状态的行与将由一致性协议带来的正确行之间进行交叉检查。我尝试捕获写指令的寄存器值,但同样并非所有指令都使用寄存器。其中一些具有直接价值。
标签: c++ intel instrumentation intel-pin