void DisassembleArgument(BYTE *ip, DWORD address, int type, WCHAR *buffer) { /* * !!! this code isn't processor portable. */ switch (type) { case InlineNone: *buffer = L'\0'; break; case ShortInlineI: swprintf(buffer, L"%d", *(char *)ip); break; case ShortInlineVar: swprintf(buffer, L"%u", *(unsigned char *)ip); break; case InlineVar: swprintf(buffer, L"%u", GET_UNALIGNED_VAL16(ip)); break; case InlineI: swprintf(buffer, L"%d", GET_UNALIGNED_VAL32(ip)); break; case InlineI8: swprintf(buffer, L"%I64d", GET_UNALIGNED_VAL64(ip)); break; case ShortInlineR: { __int32 Value = GET_UNALIGNED_VAL32(ip); swprintf(buffer, L"%g", (float &)Value); } break; case InlineR: { __int64 Value = GET_UNALIGNED_VAL64(ip); swprintf(buffer, L"%g", (double &) Value); } break; case ShortInlineBrTarget: swprintf(buffer, L"[%.4x]", address + 1 + *(char *)ip); break; case InlineBrTarget: swprintf(buffer, L"[%.4x]", address + 4 + GET_UNALIGNED_VAL32(ip)); break; case InlineSwitch: { DWORD caseCount = GET_UNALIGNED_VAL32(ip); ip += 4; address += caseCount*4 + 4; DWORD index = 0; while (index < caseCount) { int offset = GET_UNALIGNED_VAL32(ip); buffer += wcslen(buffer); swprintf(buffer, L"%d:[%.4x] ", index, address + offset); index++; ip += 4; } } break; case InlinePhi: { DWORD caseCount = *(unsigned char*)ip; ip += 1; DWORD index = 0; while (index < caseCount) { buffer += wcslen(buffer); swprintf(buffer, L"%d:[%.4x] ", index, GET_UNALIGNED_VAL16(ip)); index++; ip += 2; } } break; case InlineTok: case InlineMethod: case InlineField: case InlineType: case InlineSig: swprintf(buffer, L"%d", GET_UNALIGNED_VAL32(ip)); break; case InlineString: swprintf(buffer, L"%08x", GET_UNALIGNED_VAL32(ip)); break; default: swprintf(buffer, L"<unknown type %d>", type); } }
const BYTE* OpInfo::fetch(const BYTE* instrPtr, OpArgsVal* args) { data = &table[*instrPtr++]; AGAIN: _ASSERTE(data - table == data->opcode); switch(data->format) { case InlineNone: break; case InlineOpcode: _ASSERTE(*instrPtr + 256 < (int) (sizeof(table) / sizeof(OpInfoData))); data = &table[256 + *instrPtr++]; goto AGAIN; case ShortInlineVar: args->i = *instrPtr; instrPtr +=1; break; case InlineVar: args->i = GET_UNALIGNED_VAL16(instrPtr); instrPtr +=2; break; case ShortInlineI: case ShortInlineBrTarget: args->i = *instrPtr; instrPtr +=1; break; case ShortInlineR: { DWORD f = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=4; args->r = *((float*) (&f)); } break; case InlineRVA: case InlineI: case InlineMethod: case InlineField: case InlineType: case InlineString: case InlineSig: case InlineTok: case InlineBrTarget: args->i = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=4; break; case InlineI8: args->i8 = GET_UNALIGNED_VAL64(instrPtr); instrPtr +=8; break; case InlineR: { __int64 d = GET_UNALIGNED_VAL64(instrPtr); instrPtr +=8; instrPtr += 8; args->r = *((double*) (&d)); } break; case InlineSwitch: args->switch_.count = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=4; args->switch_.targets = (int*) instrPtr; instrPtr += (4 * args->switch_.count); break; case InlinePhi: args->phi.count = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=1; args->phi.vars = (unsigned short*) instrPtr; instrPtr += (2 * args->phi.count); break; default: #ifdef _DEBUG _ASSERTE(!"BadType"); #else __assume(0); // we are really certain the default case does not happen #endif break; } return(instrPtr); }