Search code examples
intel-pin

Intel Pin:Invalid REG for IARG_REG_VALUE reg: xmm0


I'm making a program to trace the program, but I am having trouble with the error like the title. Is there anyone who can understand something?

INS_InsertCall(ins, action, AFUNPTR(RegOpnd::at_call),
            IARG_PTR, data,
            IARG_PTR, this,
            IARG_REG_VALUE, reg_,
            IARG_END);

I checked that IARG_REG_VALUE was not compatible with xmm registers. How can I get the information?


Solution

  • As the documentation says:

    this cannot be used to retrieve the value of registers whose size is larger than ADDRINT (e.g. x87 FPU/XMM/YMM/ZMM/opmask)

    You have two options, either:

    • Test for the type of the register and use IARG_REG_CONST_REFERENCE (or IARG_REG_REFERENCE if you wish to modify the register).
    • Get the CPU context (using IARG_CONST_CONTEXT or IARG_CONTEXT if you wish to modify any register in it) and inspect the registers in the context.

    I guess that the first option is the more meaningful one, so it should go approximately like the code below:

    Warning: code below has not been tested / compiled...

    Instrumentation:

    const unsigned int opnd_count =  INS_OperandCount(ins);
    for(unsigned int i=0; i < opnd_count;i++)
    {
        if (INS_OperandIsReg(ins,i))
        {
            REG r = INS_OperandReg(ins,i);
            if ((r))
            {
                INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)xmm_arg, 
                               IARG_REG_CONST_REFERENCE, r,
                               IARG_REG_REFERENCE, r, // you might remove this one if you don't modify the reg.
                               IARG_UINT32, i,
                               IARG_UINT32, (r-REG_XMM_BASE), // note: REG_XMM_BASE = REG_XMM0
                               IARG_END);
            }
    
        }
    }
    

    Analysis:

    // regConstRef: const reference on the register
    // regRef: reference on the register
    // opnd_indx: operand index (0 for the 1st inst. op.; 1 for the 2nd inst. op.)
    // regno: register number: 0 = XMM0; 1 = XMM1, etc.
    VOID xmm_arg(PIN_REGISTER* regConstRef, PIN_REGISTER* regRef, UINT32 opnd_indx, UINT32 regno)
    {
        // just "dump" the register
        std::cout << "XMM" << regno << " operand_index: " << opnd_indx << " ";
        for(unsigned int i=0;i< MAX_DWORDS_PER_PIN_REG;i++)
        {
            std::cout << std::setw(10) << regConstRef->dword[i] << " ";
        }  
        std::cout << std::endl;
    }