private static void CheckOperand(DebugInstruction ins, int operandCount, params Type[] types) { if (ins.Operands.Count != operandCount) { throw new DebugInstructionException(ins, string.Format("Expecting {0} operands", operandCount)); } for (var i = 0; i < ins.Operands.Count; i++) { try { if (types[i].IsInstanceOfType(ins.Operands[i])) { continue; } Convert.ChangeType(ins.Operands[i], types[i]); } catch (Exception) { throw new DebugInstructionException(ins, string.Format("Expecting '{0}' Type (or compatible) for Operands[{1}]", types[i], i)); } } }
public virtual void Collect(DebugInstruction instruction) { Collect(instruction.Operands); }
private void ReadDebugInfo(BinaryReader reader, MethodDefinition mdef, uint debugOffset) { reader.PreserveCurrentPosition(debugOffset, () => { var debugInfo = new DebugInfo(mdef.Body); mdef.Body.DebugInfo = debugInfo; var lineStart = reader.ReadULEB128(); debugInfo.LineStart = lineStart; var parametersSize = reader.ReadULEB128(); for (var i = 0; i < parametersSize; i++) { var index = reader.ReadULEB128P1(); string name = null; if (index != DexConsts.NoIndex && index >= 0) name = Dex.Strings[(int)index]; debugInfo.Parameters.Add(name); } while (true) { var ins = new DebugInstruction {OpCode = (DebugOpCodes) reader.ReadByte()}; debugInfo.DebugInstructions.Add(ins); uint registerIndex; long nameIndex; string name; switch (ins.OpCode) { case DebugOpCodes.AdvancePc: // uleb128 addr_diff var addrDiff = reader.ReadULEB128(); ins.Operands.Add(addrDiff); break; case DebugOpCodes.AdvanceLine: // sleb128 line_diff var lineDiff = reader.ReadSLEB128(); ins.Operands.Add(lineDiff); break; case DebugOpCodes.EndLocal: case DebugOpCodes.RestartLocal: // uleb128 register_num registerIndex = reader.ReadULEB128(); ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]); break; case DebugOpCodes.SetFile: // uleb128p1 name_idx nameIndex = reader.ReadULEB128P1(); name = null; if (nameIndex != DexConsts.NoIndex && nameIndex >= 0) name = Dex.Strings[(int)nameIndex]; ins.Operands.Add(name); break; case DebugOpCodes.StartLocalExtended: case DebugOpCodes.StartLocal: // StartLocalExtended : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx, uleb128p1 sig_idx // StartLocal : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx var isExtended = ins.OpCode == DebugOpCodes.StartLocalExtended; registerIndex = reader.ReadULEB128(); ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]); nameIndex = reader.ReadULEB128P1(); name = null; if (nameIndex != DexConsts.NoIndex && nameIndex >= 0) name = Dex.Strings[(int)nameIndex]; ins.Operands.Add(name); var typeIndex = reader.ReadULEB128P1(); TypeReference type = null; if (typeIndex != DexConsts.NoIndex && typeIndex >= 0) type = Dex.TypeReferences[(int)typeIndex]; ins.Operands.Add(type); if (isExtended) { var signatureIndex = reader.ReadULEB128P1(); string signature = null; if (signatureIndex != DexConsts.NoIndex && signatureIndex >= 0) signature = Dex.Strings[(int)signatureIndex]; ins.Operands.Add(signature); } break; case DebugOpCodes.EndSequence: return; //case DebugOpCodes.Special: // between 0x0a and 0xff (inclusive) //case DebugOpCodes.SetPrologueEnd: //case DebugOpCodes.SetEpilogueBegin: //default: // break; } } }); }
private void ReadDebugInfo(BinaryReader reader, MethodDefinition mdef, uint debugOffset) { reader.PreserveCurrentPosition(debugOffset, () => { var debugInfo = new DebugInfo(mdef.Body); mdef.Body.DebugInfo = debugInfo; var lineStart = reader.ReadULEB128(); debugInfo.LineStart = lineStart; var parametersSize = reader.ReadULEB128(); for (var i = 0; i < parametersSize; i++) { var index = reader.ReadULEB128P1(); string name = null; if (index != DexConsts.NoIndex && index >= 0) { name = Dex.Strings[(int)index]; } debugInfo.Parameters.Add(name); } while (true) { var ins = new DebugInstruction { OpCode = (DebugOpCodes)reader.ReadByte() }; debugInfo.DebugInstructions.Add(ins); uint registerIndex; long nameIndex; string name; switch (ins.OpCode) { case DebugOpCodes.AdvancePc: // uleb128 addr_diff var addrDiff = reader.ReadULEB128(); ins.Operands.Add(addrDiff); break; case DebugOpCodes.AdvanceLine: // sleb128 line_diff var lineDiff = reader.ReadSLEB128(); ins.Operands.Add(lineDiff); break; case DebugOpCodes.EndLocal: case DebugOpCodes.RestartLocal: // uleb128 register_num registerIndex = reader.ReadULEB128(); ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]); break; case DebugOpCodes.SetFile: // uleb128p1 name_idx nameIndex = reader.ReadULEB128P1(); name = null; if (nameIndex != DexConsts.NoIndex && nameIndex >= 0) { name = Dex.Strings[(int)nameIndex]; } ins.Operands.Add(name); break; case DebugOpCodes.StartLocalExtended: case DebugOpCodes.StartLocal: // StartLocalExtended : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx, uleb128p1 sig_idx // StartLocal : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx var isExtended = ins.OpCode == DebugOpCodes.StartLocalExtended; registerIndex = reader.ReadULEB128(); ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]); nameIndex = reader.ReadULEB128P1(); name = null; if (nameIndex != DexConsts.NoIndex && nameIndex >= 0) { name = Dex.Strings[(int)nameIndex]; } ins.Operands.Add(name); var typeIndex = reader.ReadULEB128P1(); TypeReference type = null; if (typeIndex != DexConsts.NoIndex && typeIndex >= 0) { type = Dex.TypeReferences[(int)typeIndex]; } ins.Operands.Add(type); if (isExtended) { var signatureIndex = reader.ReadULEB128P1(); string signature = null; if (signatureIndex != DexConsts.NoIndex && signatureIndex >= 0) { signature = Dex.Strings[(int)signatureIndex]; } ins.Operands.Add(signature); } break; case DebugOpCodes.EndSequence: return; //case DebugOpCodes.Special: // between 0x0a and 0xff (inclusive) //case DebugOpCodes.SetPrologueEnd: //case DebugOpCodes.SetEpilogueBegin: //default: // break; } } }); }
public DebugInstructionException(DebugInstruction instruction, String message) : base(message) { Instruction = instruction; }