in src/InstrumentationEngine/Instruction.cpp [8:191]
HRESULT MicrosoftInstrumentationEngine::CInstruction::LogInstruction(bool ignoreTest)
{
HRESULT hr = S_OK;
tstring strIgnoreTestPrefix(ignoreTest ? _T("[TestIgnore] ") : _T(""));
tstring strInstruction(strIgnoreTestPrefix);
const size_t InstructionBufferSize = 64;
WCHAR wszInstructionBuffer[InstructionBufferSize];
ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T("IL_%04x %s"),
m_offset,
s_ilOpcodeInfo[m_opcode].m_name);
strInstruction.append(wszInstructionBuffer);
CComPtr<IOperandInstruction> pOperand;
if (SUCCEEDED(this->QueryInterface(__uuidof(IOperandInstruction), (LPVOID*)&pOperand)))
{
DWORD dwOperandSize = 0;
IfFailRet(this->GetOperandLength(&dwOperandSize));
if (dwOperandSize != 0)
{
CAutoVectorPtr<BYTE> pOperandValue;
pOperandValue.Allocate(dwOperandSize);
IfFailRet(pOperand->GetOperandValue(dwOperandSize, pOperandValue));
ILOperandType operandType;
IfFailRet(pOperand->GetOperandType(&operandType));
ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
switch(operandType)
{
case ILOperandType_Byte:
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%x"),
*(BYTE*)(pOperandValue.m_p));
break;
case ILOperandType_Int:
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%x"),
*(DWORD*)(pOperandValue.m_p));
break;
case ILOperandType_UShort:
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%x"),
*(USHORT*)(pOperandValue.m_p));
break;
case ILOperandType_Long:
// There is no format specifier for LONGLONG; use LARGE_INTEGER to break apart
// the LONGLONG and format each part appropriately.
LARGE_INTEGER value;
value.QuadPart = *(LONGLONG*)(pOperandValue.m_p);
if (value.u.HighPart != 0L)
{
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%x"),
value.u.HighPart);
strInstruction.append(wszInstructionBuffer);
ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T("%08x"),
value.u.LowPart);
}
else
{
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%x"),
value.u.LowPart);
}
break;
case ILOperandType_Single:
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%f"),
*(float*)(pOperandValue.m_p));
break;
case ILOperandType_Double:
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%f"),
*(double*)(pOperandValue.m_p));
break;
case ILOperandType_Token:
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" 0x%08x"),
*(DWORD*)(pOperandValue.m_p));
break;
default:
wcscpy_s(wszInstructionBuffer, InstructionBufferSize, _T(" (Invalid operand type)"));
break;
}
strInstruction.append(wszInstructionBuffer);
}
}
else
{
CComPtr<IBranchInstruction> pBranchInstruction;
if (SUCCEEDED(this->QueryInterface(__uuidof(IBranchInstruction), (LPVOID*)&pBranchInstruction)))
{
CComPtr<IInstruction> pBranchTarget;
IfFailRet(pBranchInstruction->GetBranchTarget(&pBranchTarget));
DWORD targetOffset = 0;
IfFailRet(pBranchTarget->GetOffset(&targetOffset));
ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T(" IL_%04x"),
targetOffset);
strInstruction.append(wszInstructionBuffer);
}
else
{
CComPtr<ISwitchInstruction> pSwitchInstruction;
if (SUCCEEDED(this->QueryInterface(__uuidof(ISwitchInstruction), (LPVOID*)&pSwitchInstruction)))
{
DWORD branchCount = 0;
IfFailRet(pSwitchInstruction->GetBranchCount(&branchCount));
strInstruction.append(_T(" ("));
for (DWORD i = 0; i < branchCount; i++)
{
DWORD offset = 0;
IfFailRet(pSwitchInstruction->GetBranchOffset(i, &offset));
ZeroMemory(wszInstructionBuffer, InstructionBufferSize);
_snwprintf_s(
wszInstructionBuffer,
InstructionBufferSize,
_TRUNCATE,
_T("IL_%04x"),
offset);
strInstruction.append(wszInstructionBuffer);
if (i < branchCount - 1)
{
strInstruction.append(_T(","));
}
}
strInstruction.append(_T(")"));
}
}
}
CLogging::LogDumpMessage(_T("%s"), strInstruction.c_str());
return hr;
}