private void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP) { if (debugRecords != null) { InstructionInfoFactory factory = new InstructionInfoFactory(); InstructionInfo info = factory.GetInfo(instr); ulong codeOffset = instr.IP - baseInstrIP; debugRecords.Update(codeOffset); Variable variable = null; foreach (UsedMemory usedMemInfo in info.GetUsedMemory()) { string baseRegister = usedMemInfo.Base.ToString(); int displacement; unchecked { displacement = (int)usedMemInfo.Displacement; } Dictionary <int, Variable> offsetToVariableMap; if (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap)) { if (offsetToVariableMap.TryGetValue(displacement, out variable)) { output.Write($"; [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}"); } } } foreach (UsedRegister usedMemInfo in info.GetUsedRegisters()) { if (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variable)) { output.Write($"; {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}"); } } } }
void CheckEqual(ref InstructionInfo info1, ref InstructionInfo info2, bool hasRegs2, bool hasMem2) { if (hasRegs2) { Assert.Equal(info1.GetUsedRegisters(), info2.GetUsedRegisters(), UsedRegisterEqualityComparer.Instance); } else { Assert.Empty(info2.GetUsedRegisters()); } if (hasMem2) { Assert.Equal(info1.GetUsedMemory(), info2.GetUsedMemory(), UsedMemoryEqualityComparer.Instance); } else { Assert.Empty(info2.GetUsedMemory()); } #pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(info1.IsPrivileged, info2.IsPrivileged); Assert.Equal(info1.IsStackInstruction, info2.IsStackInstruction); Assert.Equal(info1.IsSaveRestoreInstruction, info2.IsSaveRestoreInstruction); Assert.Equal(info1.Encoding, info2.Encoding); Assert.Equal(info1.CpuidFeatures, info2.CpuidFeatures); Assert.Equal(info1.FlowControl, info2.FlowControl); #pragma warning restore CS0618 // Type or member is obsolete Assert.Equal(info1.Op0Access, info2.Op0Access); Assert.Equal(info1.Op1Access, info2.Op1Access); Assert.Equal(info1.Op2Access, info2.Op2Access); Assert.Equal(info1.Op3Access, info2.Op3Access); Assert.Equal(info1.Op4Access, info2.Op4Access); #pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(info1.RflagsRead, info2.RflagsRead); Assert.Equal(info1.RflagsWritten, info2.RflagsWritten); Assert.Equal(info1.RflagsCleared, info2.RflagsCleared); Assert.Equal(info1.RflagsSet, info2.RflagsSet); Assert.Equal(info1.RflagsUndefined, info2.RflagsUndefined); Assert.Equal(info1.RflagsModified, info2.RflagsModified); #pragma warning restore CS0618 // Type or member is obsolete }
void CheckEqual(ref InstructionInfo info1, ref InstructionInfo info2, bool hasRegs2, bool hasMem2) { if (hasRegs2) { Assert.Equal(info1.GetUsedRegisters(), info2.GetUsedRegisters(), UsedRegisterEqualityComparer.Instance); } else { Assert.Empty(info2.GetUsedRegisters()); } if (hasMem2) { Assert.Equal(info1.GetUsedMemory(), info2.GetUsedMemory(), UsedMemoryEqualityComparer.Instance); } else { Assert.Empty(info2.GetUsedMemory()); } Assert.Equal(info1.ProtectedMode, info2.ProtectedMode); Assert.Equal(info1.Privileged, info2.Privileged); Assert.Equal(info1.StackInstruction, info2.StackInstruction); Assert.Equal(info1.SaveRestoreInstruction, info2.SaveRestoreInstruction); Assert.Equal(info1.Encoding, info2.Encoding); Assert.Equal(info1.CpuidFeature, info2.CpuidFeature); Assert.Equal(info1.FlowControl, info2.FlowControl); Assert.Equal(info1.Op0Access, info2.Op0Access); Assert.Equal(info1.Op1Access, info2.Op1Access); Assert.Equal(info1.Op2Access, info2.Op2Access); Assert.Equal(info1.Op3Access, info2.Op3Access); Assert.Equal(info1.Op4Access, info2.Op4Access); Assert.Equal(info1.RflagsRead, info2.RflagsRead); Assert.Equal(info1.RflagsWritten, info2.RflagsWritten); Assert.Equal(info1.RflagsCleared, info2.RflagsCleared); Assert.Equal(info1.RflagsSet, info2.RflagsSet); Assert.Equal(info1.RflagsUndefined, info2.RflagsUndefined); Assert.Equal(info1.RflagsModified, info2.RflagsModified); }
void CheckEqual(ref InstructionInfo info1, ref InstructionInfo info2, bool hasRegs2, bool hasMem2) { if (hasRegs2) { Assert.Equal(info1.GetUsedRegisters(), info2.GetUsedRegisters(), UsedRegisterEqualityComparer.Instance); } else { Assert.Empty(info2.GetUsedRegisters()); } if (hasMem2) { Assert.Equal(info1.GetUsedMemory(), info2.GetUsedMemory(), UsedMemoryEqualityComparer.Instance); } else { Assert.Empty(info2.GetUsedMemory()); } Assert.Equal(info1.Op0Access, info2.Op0Access); Assert.Equal(info1.Op1Access, info2.Op1Access); Assert.Equal(info1.Op2Access, info2.Op2Access); Assert.Equal(info1.Op3Access, info2.Op3Access); Assert.Equal(info1.Op4Access, info2.Op4Access); }
private void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP) { if (debugRecords != null) { HashSet <Variable> variables; InstructionInfoFactory factory = new InstructionInfoFactory(); InstructionInfo info = factory.GetInfo(instr); ulong codeOffset = instr.IP - baseInstrIP; debugRecords.Update(codeOffset); foreach (UsedMemory usedMemInfo in info.GetUsedMemory()) { string baseRegister = usedMemInfo.Base.ToString(); int displacement; unchecked { displacement = (int)usedMemInfo.Displacement; } Dictionary <int, HashSet <Variable> > offsetToVariableMap; if (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap)) { if (offsetToVariableMap.TryGetValue(displacement, out variables)) { output.Write($";"); foreach (Variable variable in variables) { output.Write($" [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}"); } } } } foreach (UsedRegister usedMemInfo in info.GetUsedRegisters()) { // TODO, if the code is accessing EAX but the debug info maps to RAX, then this match is going to fail. if (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variables)) { output.Write($";"); foreach (Variable variable in variables) { output.Write($" {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}"); } } } } }