You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.4 KiB
167 lines
4.4 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
/*
|
|
* Verify the memory addressing for BT, BTC, BTR, BTS instructions.
|
|
* This tool expects the specific test code in btc_app.cpp, since it
|
|
* assumes that all of the relevant instructions access a single array.
|
|
*/
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "pin.H"
|
|
using std::ofstream;
|
|
using std::string;
|
|
using std::endl;
|
|
|
|
KNOB<string> KnobOutput(KNOB_MODE_WRITEONCE,"pintool", "o", "ea_verifier_bt.out", "Name for log file");
|
|
|
|
static ofstream out;
|
|
static ADDRINT baseAddr = 0;
|
|
static int errors = 0;
|
|
static int tests = 0;
|
|
|
|
static void printHex (ADDRINT p)
|
|
{
|
|
UINT32 fieldWidth = (sizeof(ADDRINT) == 4) ? 8 : 12;
|
|
|
|
out << std::setw(fieldWidth) << std::hex << p << std::dec ;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* We simply allocate space for the dis-assembled instruction strings and
|
|
* let them leak.
|
|
*/
|
|
static char const * formatInstruction(INS ins)
|
|
{
|
|
ADDRINT ip = INS_Address(ins);
|
|
string formatted = hexstr(ip) + " " + INS_Disassemble(ins);
|
|
char * res = new char [formatted.length()+1];
|
|
|
|
strcpy (res, formatted.c_str());
|
|
|
|
return res;
|
|
}
|
|
|
|
static int byteOffset(UINT32 size, INT32 bitIndex)
|
|
{
|
|
INT32 bitBits = (size == 2) ? 4 : (size == 4) ? 5 : 6;
|
|
|
|
return (bitIndex >> bitBits)*size;
|
|
}
|
|
|
|
static VOID ProcessAddress (ADDRINT name, UINT32 size, ADDRINT ea, INT32 bitIndex)
|
|
{
|
|
// Work out the base address of the array being accessed
|
|
if (baseAddr == 0)
|
|
{
|
|
baseAddr = ea - byteOffset(size,bitIndex);
|
|
return;
|
|
}
|
|
|
|
tests++;
|
|
// Check that the position agrees with what we think it should be.
|
|
if (baseAddr+byteOffset(size,bitIndex) != ea)
|
|
{
|
|
errors++;
|
|
out << (const char *)name << ": Bad EA "; printHex(ea);
|
|
out << " Expected "; printHex (baseAddr+byteOffset(size,bitIndex));
|
|
out << " Bit offset " << bitIndex << " Access size " << size << endl;
|
|
}
|
|
}
|
|
|
|
static VOID Instrument(INS ins)
|
|
{
|
|
UINT32 op = INS_Opcode(ins);
|
|
|
|
switch (op)
|
|
{
|
|
case XED_ICLASS_BT:
|
|
case XED_ICLASS_BTC:
|
|
case XED_ICLASS_BTR:
|
|
case XED_ICLASS_BTS:
|
|
// Filter out the BTs we want to look at, we don't expect any in system libraries,
|
|
// but we have seen a bt reg,reg on FC12
|
|
if (INS_IsMemoryRead(ins) && !INS_OperandIsImmediate(ins,1))
|
|
break;
|
|
// Fall through and ignore non mem,reg operations.
|
|
default:
|
|
return;
|
|
}
|
|
|
|
INS_InsertCall(ins, IPOINT_BEFORE,
|
|
AFUNPTR(ProcessAddress),
|
|
IARG_ADDRINT, ADDRINT (formatInstruction(ins)),
|
|
IARG_MEMORYREAD_SIZE,
|
|
IARG_MEMORYOP_EA, 0,
|
|
IARG_REG_VALUE, INS_OperandReg(ins, 1),
|
|
IARG_END);
|
|
}
|
|
|
|
static BOOL traceFromExecutable(TRACE trace)
|
|
{
|
|
RTN rtn = TRACE_Rtn(trace);
|
|
if (!RTN_Valid(rtn))
|
|
return FALSE;
|
|
SEC sec = RTN_Sec(rtn);
|
|
if (!SEC_Valid(sec))
|
|
return FALSE;
|
|
IMG img = SEC_Img(sec);
|
|
if (!IMG_Valid(img))
|
|
return FALSE;
|
|
return IMG_IsMainExecutable(img);
|
|
}
|
|
|
|
VOID Trace(TRACE trace, VOID *v)
|
|
{
|
|
// Only instrument the main executable, we're not interested in anything in dynamic libraries.
|
|
if (!traceFromExecutable(trace))
|
|
return;
|
|
|
|
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))
|
|
{
|
|
Instrument(ins);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AtEnd(INT32 code, VOID *arg)
|
|
{
|
|
out << "Target exited with code : " << code << endl;
|
|
out << errors << " BTx addressing errors in " << tests << " tests" << endl;
|
|
out.close();
|
|
if (tests == 0)
|
|
exit(-1);
|
|
else
|
|
exit(errors);
|
|
}
|
|
|
|
int main(int argc, char * argv[])
|
|
{
|
|
PIN_InitSymbols();
|
|
PIN_Init(argc, argv);
|
|
|
|
out.open(KnobOutput.Value().c_str());
|
|
|
|
TRACE_AddInstrumentFunction(Trace, 0);
|
|
PIN_AddFiniFunction(AtEnd, 0);
|
|
|
|
// Never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|