public MonoVariable(string name, TargetType type, bool is_local, bool is_byref, Method method, VariableInfo info, int start_scope_offset, int end_scope_offset) : this(name, type, is_local, is_byref, method, info) { if (is_local) { start_scope = method.StartAddress + start_scope_offset; end_scope = method.StartAddress + end_scope_offset; } else if (method.HasMethodBounds) { start_scope = method.MethodStartAddress; end_scope = method.MethodEndAddress; } else { start_scope = method.StartAddress; end_scope = method.EndAddress; } if (has_liveness_info) { if (start_liveness < start_scope) start_liveness = start_scope; if (end_liveness > end_scope) end_liveness = end_scope; } else { start_liveness = start_scope; end_liveness = end_scope; has_liveness_info = true; } }
private MonoStringType(MonoSymbolFile file, Cecil.TypeDefinition typedef, int object_size, int size) : base(file, typedef, "string", FundamentalKind.String, size) { this.ObjectSize = object_size; this.CreateString = file.MonoLanguage.MonoDebuggerInfo.CreateString; }
public MonoGenericInstanceType(MonoClassType container, TargetType[] type_args, TargetAddress class_ptr) : base(container.File.MonoLanguage) { this.Container = container; this.type_args = type_args; this.class_ptr = class_ptr; struct_type = new MonoStructType (container.File, this, container.Type); StringBuilder sb = new StringBuilder (container.BaseName); sb.Append ('<'); for (int i = 0; i < type_args.Length; i++) { if (i > 0) sb.Append (','); sb.Append (type_args [i].Name); } sb.Append ('>'); full_name = sb.ToString (); bool is_compiler_generated; DebuggerBrowsableState? browsable_state; MonoSymbolFile.CheckCustomAttributes (container.Type, out browsable_state, out debugger_display, out type_proxy, out is_compiler_generated); }
public AppDomainInfo GetAppDomainInfo(MonoLanguageBackend mono, TargetMemoryAccess memory, TargetAddress address) { int addr_size = memory.TargetMemoryInfo.TargetAddressSize; TargetReader reader = new TargetReader (memory.ReadMemory (address, 12 * addr_size)); return new AppDomainInfo (mono, memory, reader); }
internal static string ReadString(MonoLanguageBackend mono, TargetMemoryAccess target, TargetAddress address) { if (address.IsNull) return null; TargetLocation location = new AbsoluteTargetLocation (address); MonoStringObject so = new MonoStringObject (mono.BuiltinTypes.StringType, location); return (string) so.DoGetObject (target); }
protected MonoClassInfo(MonoSymbolFile file, Cecil.TypeDefinition typedef, TargetMemoryAccess target, TargetAddress klass) { this.SymbolFile = file; this.KlassAddress = klass; this.CecilType = typedef; parent_klass = MetadataHelper.MonoClassGetParent (target, klass); GenericClass = MetadataHelper.MonoClassGetGenericClass (target, klass); GenericContainer = MetadataHelper.MonoClassGetGenericContainer (target, klass); }
public CapturedVariable(ScopeInfo scope, Method method, string name, string field_name) { this.scope = scope; this.name = name; this.field_name = field_name; start_scope = method.StartAddress; end_scope = method.EndAddress; start_liveness = method.MethodStartAddress; end_liveness = method.MethodEndAddress; }
public static MonoClassInfo ReadClassInfo(MonoLanguageBackend mono, TargetMemoryAccess target, TargetAddress klass) { TargetAddress image = mono.MetadataHelper.MonoClassGetMonoImage (target, klass); MonoSymbolFile file = mono.GetImage (image); if (file == null) throw new InternalError (); int token = mono.MetadataHelper.MonoClassGetToken (target, klass); if ((token & 0xff000000) != 0x02000000) throw new InternalError (); Cecil.TypeDefinition typedef; typedef = (Cecil.TypeDefinition) file.ModuleDefinition.LookupByToken ( Cecil.Metadata.TokenType.TypeDef, token & 0x00ffffff); if (typedef == null) throw new InternalError (); MonoClassInfo info = new MonoClassInfo (file, typedef, target, klass); if ((file == mono.BuiltinTypes.Corlib) && (typedef.FullName == "System.Decimal")) { MonoFundamentalType ftype = mono.BuiltinTypes.DecimalType; if (ftype.ClassType == null) { MonoClassType ctype = new MonoClassType (file, typedef, info); ((IMonoStructType) ctype).ClassInfo = info; ftype.SetClass (ctype); } info.struct_type = (IMonoStructType) ftype.ClassType; info.type = ftype; } else if (info.IsGenericClass) { info.struct_type = (IMonoStructType) file.MonoLanguage.ReadGenericClass ( target, info.GenericClass, false); info.type = info.struct_type.Type; } else { info.type = file.LookupMonoType (typedef); if (info.type is TargetClassType) info.struct_type = (IMonoStructType) info.type; else info.struct_type = (IMonoStructType) info.type.ClassType; } info.struct_type.ClassInfo = info; return info; }
public MonoVariable(string name, TargetType type, bool is_local, bool is_byref, Method method, VariableInfo info) { this.name = name; this.type = type; this.info = info; this.is_byref = is_byref; start_scope = method.StartAddress; end_scope = method.EndAddress; if (info.HasLivenessInfo) { start_liveness = method.StartAddress + info.BeginLiveness; end_liveness = method.StartAddress + info.EndLiveness; has_liveness_info = true; } else { start_liveness = method.MethodStartAddress; end_liveness = method.MethodEndAddress; has_liveness_info = false; } }
internal override StackFrame CreateFrame(Thread thread, FrameType type, TargetMemoryAccess memory, Registers regs) { TargetAddress address = new TargetAddress ( memory.AddressDomain, regs [(int) X86_Register.RIP].GetValue ()); TargetAddress stack_pointer = new TargetAddress ( memory.AddressDomain, regs [(int) X86_Register.RSP].GetValue ()); TargetAddress frame_pointer = new TargetAddress ( memory.AddressDomain, regs [(int) X86_Register.RBP].GetValue ()); return CreateFrame (thread, type, memory, address, stack_pointer, frame_pointer, regs); }
internal MonoFunctionType ReadMonoMethod(TargetMemoryAccess memory, TargetAddress address) { int token = MetadataHelper.MonoMethodGetToken (memory, address); TargetAddress klass = MetadataHelper.MonoMethodGetClass (memory, address); TargetAddress image = MetadataHelper.MonoClassGetMonoImage (memory, klass); MonoSymbolFile file = GetImage (image); if (file == null) return null; return file.GetFunctionByToken (token); }
internal bool IsTrampolineAddress(TargetAddress address) { foreach (TargetAddress trampoline in trampolines) { if (address == trampoline) return true; } return false; }
internal abstract Inferior.CallbackFrame GetCallbackFrame(TargetAddress stack_pointer, bool exact_match);
// <summary> // Checks whether the variable is alive at @address, but without actually // trying to access the variable. The implementation just checks the data // from the symbol file and - if appropriate - from the JIT to find out // whether the specified address is within the variable's live range. // </summary> public abstract bool IsAlive(TargetAddress address);
internal abstract StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess target, ref TargetAddress lmf_address);
StackFrame unwind_method(StackFrame frame, TargetMemoryAccess memory, byte[] code, int pos, int offset) { Registers old_regs = frame.Registers; Registers regs = CopyRegisters (old_regs); if (!old_regs [(int) X86_Register.RBP].Valid) return null; TargetAddress rbp = new TargetAddress ( memory.AddressDomain, old_regs [(int) X86_Register.RBP].Value); int addr_size = TargetAddressSize; TargetAddress new_rbp = memory.ReadAddress (rbp); regs [(int) X86_Register.RBP].SetValue (rbp, new_rbp); TargetAddress new_rip = memory.ReadAddress (rbp + addr_size); regs [(int) X86_Register.RIP].SetValue (rbp + addr_size, new_rip); TargetAddress new_rsp = rbp + 2 * addr_size; regs [(int) X86_Register.RSP].SetValue (rbp, new_rsp); rbp -= addr_size; int length = System.Math.Min (code.Length, offset); while (pos < length) { byte opcode = code [pos++]; long value; if ((opcode == 0x41) && (pos < length)) { byte opcode2 = code [pos++]; if ((opcode2 < 0x50) || (opcode2 > 0x57)) break; switch (opcode2) { case 0x50: /* r8 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R8].SetValue (rbp, value); break; case 0x51: /* r9 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R9].SetValue (rbp, value); break; case 0x52: /* r10 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R10].SetValue (rbp, value); break; case 0x53: /* r11 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R11].SetValue (rbp, value); break; case 0x54: /* r12 */ value = (long) memory.ReadAddress (rbp).Address; regs [(int) X86_Register.R12].SetValue (rbp, value); break; case 0x55: /* r13 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R13].SetValue (rbp, value); break; case 0x56: /* r14 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R14].SetValue (rbp, value); break; case 0x57: /* r15 */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.R15].SetValue (rbp, value); break; } } else { if ((opcode < 0x50) || (opcode > 0x57)) break; switch (opcode) { case 0x50: /* rax */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.RAX].SetValue (rbp, value); break; case 0x51: /* rcx */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.RCX].SetValue (rbp, value); break; case 0x52: /* rdx */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.RDX].SetValue (rbp, value); break; case 0x53: /* rbx */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.RBX].SetValue (rbp, value); break; case 0x56: /* rsi */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.RSI].SetValue (rbp, value); break; case 0x57: /* rdi */ value = memory.ReadLongInteger (rbp); regs [(int) X86_Register.RDI].SetValue (rbp, value); break; } } rbp -= addr_size; } return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs); }
public abstract TargetAddress ReadAddress(TargetAddress address);
public abstract long ReadLongInteger(TargetAddress address);
public abstract int ReadInteger(TargetAddress address);
public abstract byte ReadByte(TargetAddress address);
public abstract CommandResult CallMethod(TargetAddress method, TargetAddress method_argument, TargetObject object_argument);
public abstract CommandResult CallMethod(TargetAddress method, long arg1, long arg2, long arg3, string string_arg);
public abstract CommandResult CallMethod(TargetAddress method, long arg1, long arg2);
internal override void Hack_ReturnNull(Inferior inferior) { Registers regs = inferior.GetRegisters (); TargetAddress rsp = new TargetAddress ( inferior.AddressDomain, regs [(int) X86_Register.RSP].GetValue ()); TargetAddress rip = inferior.ReadAddress (rsp); rsp += TargetAddressSize; regs [(int) X86_Register.RIP].SetValue (rip); regs [(int) X86_Register.RSP].SetValue (rsp); regs [(int) X86_Register.RAX].SetValue (TargetAddress.Null); inferior.SetRegisters (regs); }
internal override bool IsSyscallInstruction(TargetMemoryAccess memory, TargetAddress address) { try { return (memory.ReadByte (address - 2) == 0x0f) && (memory.ReadByte (address - 1) == 0x05); } catch { return false; } }
public abstract string ReadString(TargetAddress address);
// <summary> // Returns whether the instruction at target address @address is a `syscall' // instruction. // </summary> internal abstract bool IsSyscallInstruction(TargetMemoryAccess memory, TargetAddress address);
public abstract TargetBlob ReadMemory(TargetAddress address, int size);
public abstract Symbol SimpleLookup(TargetAddress address, bool exact_match);
public abstract byte[] ReadBuffer(TargetAddress address, int size);
internal abstract Instruction ReadInstruction(TargetMemoryAccess memory, TargetAddress address);
public abstract void WriteBuffer(TargetAddress address, byte[] buffer);
internal bool IsDelegateTrampoline(TargetAddress address) { if (global_data_table == null) return false; return global_data_table.IsDelegateInvoke (address); }
public abstract void WriteByte(TargetAddress address, byte value);
internal MonoClassInfo ReadClassInfo(TargetMemoryAccess memory, TargetAddress klass) { if (class_info_by_addr.ContainsKey (klass)) return class_info_by_addr [klass]; MonoClassInfo info = MonoClassInfo.ReadClassInfo (this, memory, klass); class_info_by_addr.Add (klass, info); return info; }
public abstract void WriteInteger(TargetAddress address, int value);
internal void RegisterMethodLoadHandler(TargetAccess target, TargetAddress info, int index, MethodLoadedHandler handler) { if (!info.IsNull) method_from_jit_info (target, info, handler); else method_load_handlers.Add (index, handler); }
public abstract void WriteLongInteger(TargetAddress address, long value);
internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory, ref TargetAddress lmf_address) { TargetAddress lmf = lmf_address; TargetBinaryReader reader = memory.ReadMemory (lmf_address, 88).GetReader (); lmf_address = reader.ReadTargetAddress (); // prev reader.ReadTargetAddress (); reader.ReadTargetAddress (); // method TargetAddress rip = reader.ReadTargetAddress (); if (lmf_address.IsNull) return null; TargetAddress rbx = reader.ReadTargetAddress (); TargetAddress rbp = reader.ReadTargetAddress (); TargetAddress rsp = reader.ReadTargetAddress (); TargetAddress r12 = reader.ReadTargetAddress (); TargetAddress r13 = reader.ReadTargetAddress (); TargetAddress r14 = reader.ReadTargetAddress (); TargetAddress r15 = reader.ReadTargetAddress (); Registers regs = new Registers (this); if ((lmf_address.Address & 1) == 0) { rip = memory.ReadAddress (rsp - 8); regs [(int) X86_Register.RIP].SetValue (rsp - 8, rip); regs [(int) X86_Register.RBP].SetValue (lmf + 40, rbp); } else { TargetAddress new_rbp = memory.ReadAddress (rbp); regs [(int) X86_Register.RIP].SetValue (lmf + 24, rip); regs [(int) X86_Register.RBP].SetValue (rbp, new_rbp); rbp = new_rbp; lmf_address--; } regs [(int) X86_Register.RBX].SetValue (lmf + 32, rbx); regs [(int) X86_Register.RSP].SetValue (lmf + 48, rsp); regs [(int) X86_Register.R12].SetValue (lmf + 56, r12); regs [(int) X86_Register.R13].SetValue (lmf + 64, r13); regs [(int) X86_Register.R14].SetValue (lmf + 72, r14); regs [(int) X86_Register.R15].SetValue (lmf + 80, r15); return CreateFrame (thread.Client, FrameType.LMF, memory, rip, rsp, rbp, regs); }
public abstract void WriteAddress(TargetAddress address, TargetAddress value);
internal override bool IsRetInstruction(TargetMemoryAccess memory, TargetAddress address) { return memory.ReadByte (address) == 0xc3; }
public abstract int GetInstructionSize(TargetAddress address);
StackFrame try_unwind_sigreturn(StackFrame frame, TargetMemoryAccess memory) { byte[] data = memory.ReadMemory (frame.TargetAddress, 9).Contents; /* * Check for signal return trampolines: * * mov __NR_rt_sigreturn, %eax * syscall */ if ((data [0] != 0x48) || (data [1] != 0xc7) || (data [2] != 0xc0) || (data [3] != 0x0f) || (data [4] != 0x00) || (data [5] != 0x00) || (data [6] != 0x00) || (data [7] != 0x0f) || (data [8] != 0x05)) return null; TargetAddress stack = frame.StackPointer; /* See `struct sigcontext' in <asm/sigcontext.h> */ int[] regoffsets = { (int) X86_Register.R8, (int) X86_Register.R9, (int) X86_Register.R10, (int) X86_Register.R11, (int) X86_Register.R12, (int) X86_Register.R13, (int) X86_Register.R14, (int) X86_Register.R15, (int) X86_Register.RDI, (int) X86_Register.RSI, (int) X86_Register.RBP, (int) X86_Register.RBX, (int) X86_Register.RDX, (int) X86_Register.RAX, (int) X86_Register.RCX, (int) X86_Register.RSP, (int) X86_Register.RIP, (int) X86_Register.EFLAGS }; Registers regs = CopyRegisters (frame.Registers); int offset = 0x28; /* The stack contains the `struct ucontext' from <asm/ucontext.h>; the * `struct sigcontext' starts at offset 0x28 in it. */ foreach (int regoffset in regoffsets) { TargetAddress new_value = memory.ReadAddress (stack + offset); regs [regoffset].SetValue (new_value); offset += 8; } TargetAddress rip = new TargetAddress ( memory.AddressDomain, regs [(int) X86_Register.RIP].GetValue ()); TargetAddress rsp = new TargetAddress ( memory.AddressDomain, regs [(int) X86_Register.RSP].GetValue ()); TargetAddress rbp = new TargetAddress ( memory.AddressDomain, regs [(int) X86_Register.RBP].GetValue ()); Symbol name = new Symbol ("<signal handler>", rip, 0); return new StackFrame ( frame.Thread, FrameType.Signal, rip, rsp, rbp, regs, frame.Thread.NativeLanguage, name); }
public abstract AssemblerLine DisassembleInstruction(Method method, TargetAddress address);
public override bool CheckBreakpointHit(Thread target, TargetAddress address) { return(true); }
public override TargetPointerObject GetObject(TargetAddress address) { return(new NativePointerObject(this, new AbsoluteTargetLocation(address))); }
internal Instruction ReadInstruction(TargetMemoryAccess memory, TargetAddress address) { return(opcodes.ReadInstruction(memory, address)); }
public Symbol SimpleLookup(TargetAddress address, bool exact_match) { foreach (SymbolFile symfile in symbol_files) { Symbol name = symfile.SimpleLookup (address, exact_match); if (name != null) return name; } return null; }
public TargetAddress MonoClassGetParent(TargetMemoryAccess memory, TargetAddress klass) { return(memory.ReadAddress(klass + MonoMetadataInfo.KlassParentOffset)); }
internal override Instruction ReadInstruction(TargetMemoryAccess memory, TargetAddress address) { return X86_Instruction.DecodeInstruction (this, memory, address); }
public override TargetPointerObject GetObject(TargetAddress address) { return new MonoPointerObject (this, new AbsoluteTargetLocation (address)); }
public AbsoluteTargetLocation(TargetAddress address) { this.address = address; }
// <summary> // Checks whether the variable is accessible in the lexical scope around // address @address, but without actually trying to access the variable. // </summary> public abstract bool IsInScope(TargetAddress address);
public abstract TargetReader GetReader(TargetAddress address);
// // ISymbolLookup // public Method Lookup(TargetAddress address) { foreach (SymbolFile symfile in symbol_files) { if (!symfile.SymbolsLoaded) continue; Method method = symfile.SymbolTable.Lookup (address); if (method != null) return method; } return null; }
// <summary> // Insert a breakpoint at address @address. // // Returns a number which may be passed to RemoveBreakpoint() to remove // the breakpoint. // </summary> internal abstract void InsertBreakpoint(BreakpointHandle handle, TargetAddress address, int domain);
protected void create_type(TargetMemoryAccess memory, TargetAddress klass) { class_type = file.MonoLanguage.CreateCoreType (file, typedef, memory, klass); file.MonoLanguage.AddCoreType (typedef, this, class_type, klass); }
internal Instruction_X86_64(X86_Opcodes opcodes, TargetAddress address) : base(opcodes, address) { }
public abstract TrampolineType CheckTrampoline(TargetMemoryAccess memory, out TargetAddress trampoline);
public override bool InterpretInstruction(Inferior inferior) { switch (InstructionType) { case Type.IndirectJump: case Type.Jump: { TargetAddress target = GetEffectiveAddress(inferior); Registers regs = inferior.GetRegisters(); regs [(int)X86_Register.RIP].SetValue(target); inferior.SetRegisters(regs); return(true); } case Type.IndirectCall: case Type.Call: { TargetAddress target = GetEffectiveAddress(inferior); Registers regs = inferior.GetRegisters(); TargetAddress rip = new TargetAddress( inferior.AddressDomain, regs [(int)X86_Register.RIP].Value); TargetAddress rsp = new TargetAddress( inferior.AddressDomain, regs [(int)X86_Register.RSP].Value); inferior.WriteAddress(rsp - 8, rip + InstructionSize); regs [(int)X86_Register.RSP].SetValue(rsp - 8); regs [(int)X86_Register.RIP].SetValue(target); inferior.SetRegisters(regs); return(true); } case Type.Ret: { Registers regs = inferior.GetRegisters(); TargetAddress rsp = new TargetAddress( inferior.AddressDomain, regs [(int)X86_Register.RSP].Value); TargetAddress rip = inferior.ReadAddress(rsp); rsp += 8 + Displacement; regs [(int)X86_Register.RSP].SetValue(rsp); regs [(int)X86_Register.RIP].SetValue(rip); inferior.SetRegisters(regs); return(true); } case Type.Interpretable: { Registers regs = inferior.GetRegisters(); TargetAddress rsp = new TargetAddress( inferior.AddressDomain, regs [(int)X86_Register.RSP].Value); TargetAddress rbp = new TargetAddress( inferior.AddressDomain, regs [(int)X86_Register.RBP].Value); TargetAddress rip = new TargetAddress( inferior.AddressDomain, regs [(int)X86_Register.RIP].Value); if (Code [0] == 0x55) /* push %rbp */ { inferior.WriteAddress(rsp - 8, rbp); regs [(int)X86_Register.RSP].SetValue(rsp - 8); regs [(int)X86_Register.RIP].SetValue(rip + 1); inferior.SetRegisters(regs); return(true); } return(false); } default: return(false); } }