3

IARG_MEMORYREAD_EA のタイプは、PIN で ADDRINT として定義されます。メモリの IARG_MEMORYREAD_EA ロケーションに保存されているデータをフェッチする必要があります。私が理解している限り、特定のアドレスの場所からデータを取得する最も適切な方法は、使用例が次のような PIN_SafeCopy 関数を使用することです。

ADDRINT DoLoad(REG reg, ADDRINT * addr)
{
    *out << "Emulate loading from addr " << addr << " to " << REG_StringShort(reg) << endl;
    ADDRINT value;
    PIN_SafeCopy(&value, addr, sizeof(ADDRINT));
    return value;
}

IARG_MEMORYREAD_EA をこの関数に直接渡そうとすると、コンパイラは型が一致しないと言います(ADDRINT * and ADDRINT)。明らかにそうではありませんが、この機能をどのように使用すればよいかわかりませんでした。

私の現在のコードは次のとおりです。

INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessMemIns,
 IARG_CONTEXT,
 IARG_INST_PTR,
 IARG_MEMORYREAD_EA,
 IARG_MEMORYREAD2_EA,
 IARG_MEMORYREAD_SIZE,
 IARG_MEMORYWRITE_EA,
 IARG_MEMORYWRITE_SIZE,
 IARG_BOOL, INS_IsBranchOrCall(ins),
 IARG_BRANCH_TAKEN,
 IARG_UINT32,  INS_Category(ins),
 IARG_UINT32, INS_RegR(ins, 0),
 IARG_UINT32, INS_RegR(ins, 1),
 IARG_UINT32, INS_RegR(ins, 2),
 IARG_UINT32, INS_RegR(ins, 3),
 IARG_UINT32, INS_RegW(ins, 0),
 IARG_UINT32, INS_RegW(ins, 1),
 IARG_UINT32, INS_RegW(ins, 2),
 IARG_UINT32, INS_RegW(ins, 3),
 IARG_END);

ProcessMemIns は次のとおりです。

VOID ProcessMemIns(
    CONTEXT * context,
    ADDRINT ip,
    ADDRINT raddr, ADDRINT raddr2, UINT32 rlen,
    ADDRINT waddr, UINT32  wlen,
    BOOL    isbranch,
    BOOL    isbranchtaken,
    UINT32  category,
    UINT32  rr0,
    UINT32  rr1,
    UINT32  rr2,
    UINT32  rr3,
    UINT32  rw0,
    UINT32  rw1,
    UINT32  rw2,
    UINT32  rw3)
{ // for memory address and register index, '0' means invalid
  if (pthreadsim->first_instrs < pthreadsim->skip_first)
  {
    pthreadsim->first_instrs++;
    return;
  }
  else if (pthreadsim->first_instrs == pthreadsim->skip_first)
  {
    pthreadsim->first_instrs++;
    pthreadsim->initiate(context);
  }

  /* Log for addresses and data */
  uint64_t data1 = -1, data2 = -1, data3 = -1;
  if (raddr > 0) {
    PIN_SafeCopy(&data1, raddr , sizeof(uint64_t));
    cout << "1A:" << hex << raddr << ",D:" << hex << data1 << endl;
  } 
  if (raddr2 > 0) {
    PIN_SafeCopy(&data1, raddr2 , sizeof(uint64_t));
    cout << "2A:" << hex << raddr2 << ",D:" << hex << data2 << endl;
  } 
  if (waddr > 0) {
    PIN_SafeCopy(&data1, waddr , sizeof(uint64_t));
    cout << "3A:" << hex << waddr << ",D:" << hex << data3 << endl;
  } 

  pthreadsim->process_ins(
    context,
    ip,
    raddr, raddr2, rlen,
    waddr,         wlen,
    isbranch,
    isbranchtaken,
    category,
    rr0, rr1, rr2, rr3,
    rw0, rw1, rw2, rw3);
}

予想どおり、コンパイラから次のエラー メッセージが表示されます。invalid conversion from ‘LEVEL_BASE::ADDRINT {aka long unsigned int}’ to ‘const VOID* {aka const void*}’ [-fpermissive]

PIN_SafeCopy() に IARG_MEMORYREAD_EA を使用するより適切な方法はありますか? または、ポインターを定義して PIN_SafeCopy() に使用する必要がありますか?

4

1 に答える 1

3

Intel PIN のドキュメントには、これは であると記載されていますIARG_MEMORYREAD_EAが、では奇妙に...を使用ADDRINTしていることには同意します。PIN_SafeCopyADDRINT*

OTOH、anADDRINTはアドレスを表す型であり、IARG_MEMORYREAD_EAこれがメモリ読み取りの実効アドレスであることがわかっている場合 (したがって、ほとんどの場合、ADDRINT は有効なポインターです)。

を単に に置き換えDoLoad()ます。ADDRINT*ADDRINT

C スタイルのキャストまたは : のいずれかでto をPIN_SafeCopyキャストしますが、既にポインターであることはわかっていますが、型が間違っています。これが、キャストが必要な理由です。ADDRINTvoid*reinterpet_cast<>

于 2015-04-08T12:15:44.280 に答える