in ProfilingAPI/ReJITEnterLeaveHooks/ILRewriter.cpp [229:366]
HRESULT ImportIL(LPCBYTE pIL)
{
m_pOffsetToInstr = new ILInstr*[m_CodeSize + 1];
IfNullRet(m_pOffsetToInstr);
ZeroMemory(m_pOffsetToInstr, m_CodeSize * sizeof(ILInstr*));
// Set the sentinel instruction
m_pOffsetToInstr[m_CodeSize] = &m_IL;
m_IL.m_opcode = -1;
bool fBranch = false;
unsigned offset = 0;
while (offset < m_CodeSize)
{
unsigned startOffset = offset;
unsigned opcode = pIL[offset++];
if (opcode == CEE_PREFIX1)
{
if (offset >= m_CodeSize)
{
assert(false);
return COR_E_INVALIDPROGRAM;
}
opcode = 0x100 + pIL[offset++];
}
if ((CEE_PREFIX7 <= opcode) && (opcode <= CEE_PREFIX2))
{
// NOTE: CEE_PREFIX2-7 are currently not supported
assert(false);
return COR_E_INVALIDPROGRAM;
}
if (opcode >= CEE_COUNT)
{
assert(false);
return COR_E_INVALIDPROGRAM;
}
BYTE flags = s_OpCodeFlags[opcode];
int size = (flags & OPCODEFLAGS_SizeMask);
if (offset + size > m_CodeSize)
{
assert(false);
return COR_E_INVALIDPROGRAM;
}
ILInstr * pInstr = NewILInstr();
IfNullRet(pInstr);
pInstr->m_opcode = opcode;
InsertBefore(&m_IL, pInstr);
m_pOffsetToInstr[startOffset] = pInstr;
switch (flags)
{
case 0:
break;
case 1:
pInstr->m_Arg8 = *(UNALIGNED INT8 *)&(pIL[offset]);
break;
case 2:
pInstr->m_Arg16 = *(UNALIGNED INT16 *)&(pIL[offset]);
break;
case 4:
pInstr->m_Arg32 = *(UNALIGNED INT32 *)&(pIL[offset]);
break;
case 8:
pInstr->m_Arg64 = *(UNALIGNED INT64 *)&(pIL[offset]);
break;
case 1 | OPCODEFLAGS_BranchTarget:
pInstr->m_Arg32 = offset + 1 + *(UNALIGNED INT8 *)&(pIL[offset]);
fBranch = true;
break;
case 4 | OPCODEFLAGS_BranchTarget:
pInstr->m_Arg32 = offset + 4 + *(UNALIGNED INT32 *)&(pIL[offset]);
fBranch = true;
break;
case 0 | OPCODEFLAGS_Switch:
{
if (offset + sizeof(INT32) > m_CodeSize)
{
assert(false);
return COR_E_INVALIDPROGRAM;
}
unsigned nTargets = *(UNALIGNED INT32 *)&(pIL[offset]);
pInstr->m_Arg32 = nTargets;
offset += sizeof(INT32);
unsigned base = offset + nTargets * sizeof(INT32);
for (unsigned iTarget = 0; iTarget < nTargets; iTarget++)
{
if (offset + sizeof(INT32) > m_CodeSize)
{
assert(false);
return COR_E_INVALIDPROGRAM;
}
pInstr = NewILInstr();
IfNullRet(pInstr);
pInstr->m_opcode = CEE_SWITCH_ARG;
pInstr->m_Arg32 = base + *(UNALIGNED INT32 *)&(pIL[offset]);
offset += sizeof(INT32);
InsertBefore(&m_IL, pInstr);
}
fBranch = true;
break;
}
default:
assert(false);
break;
}
offset += size;
}
assert(offset == m_CodeSize);
if (fBranch)
{
// Go over all control flow instructions and resolve the targets
for (ILInstr * pInstr = m_IL.m_pNext; pInstr != &m_IL; pInstr = pInstr->m_pNext)
{
if (s_OpCodeFlags[pInstr->m_opcode] & OPCODEFLAGS_BranchTarget)
pInstr->m_pTarget = GetInstrFromOffset(pInstr->m_Arg32);
}
}
return S_OK;
}