internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory, byte[] code, int offset) { if ((code != null) && (code.Length > 4)) { return(read_prologue(frame, memory, code, offset)); } TargetAddress rbp = frame.FrameAddress; int addr_size = TargetAddressSize; Registers regs = CopyRegisters(frame.Registers); 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; return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs)); }
internal TargetClassObject GetCurrentObject(TargetMemoryAccess target, TargetLocation location) { // location.Address resolves to the address of the MonoObject, // dereferencing it once gives us the vtable, dereferencing it // twice the class. TargetAddress address; address = target.ReadAddress(location.GetAddress(target)); address = target.ReadAddress(address); TargetType current = File.MonoLanguage.ReadMonoClass(target, address); if (current == null) { return(null); } if (IsByRef && !current.IsByRef) // Unbox { location = location.GetLocationAtOffset( 2 * target.TargetMemoryInfo.TargetAddressSize); } return((TargetClassObject)current.GetObject(target, location)); }
internal override TargetType GetCurrentType(TargetMemoryAccess target) { // location.Address resolves to the address of the MonoObject, // dereferencing it once gives us the vtable, dereferencing it // twice the class. TargetAddress address; address = target.ReadAddress (Location.GetAddress (target)); address = target.ReadAddress (address); return Type.File.MonoLanguage.ReadMonoClass (target, address); }
internal override TargetType GetCurrentType(TargetMemoryAccess target) { // location.Address resolves to the address of the MonoObject, // dereferencing it once gives us the vtable, dereferencing it // twice the class. TargetAddress address; address = target.ReadAddress(Location.GetAddress(target)); address = target.ReadAddress(address); return(Type.File.MonoLanguage.ReadMonoClass(target, address)); }
public TargetAddress MonoClassGetMethod(TargetMemoryAccess memory, TargetAddress klass, int index) { TargetAddress methods = memory.ReadAddress( klass + MonoMetadataInfo.KlassMethodsOffset); if (methods.IsNull) { throw new TargetException(TargetError.ClassNotInitialized); } methods += index * memory.TargetAddressSize; return(memory.ReadAddress(methods)); }
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)); }
void GetValue(TargetMemoryAccess target, Registers regs, TargetAddress cfa, int reg, Column column) { switch (column.State) { case State.Register: { GetRegisterValue(regs, reg, column); break; } case State.SameValue: regs [GetArchRegister(reg)].Valid = true; break; case State.Undefined: break; case State.Offset: { TargetAddress addr = cfa + column.Offset; long value = target.ReadAddress(addr).Address; regs [GetArchRegister(reg)].SetValue(address, value); break; } default: throw new NotSupportedException(); } }
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)); }
internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory, ref TargetAddress lmf_address) { TargetAddress lmf = lmf_address; TargetBinaryReader reader = memory.ReadMemory(lmf, 36).GetReader(); lmf_address = reader.ReadTargetAddress(); // prev reader.Position = 16; TargetAddress ebx = reader.ReadTargetAddress(); TargetAddress edi = reader.ReadTargetAddress(); TargetAddress esi = reader.ReadTargetAddress(); TargetAddress ebp = reader.ReadTargetAddress(); TargetAddress eip = reader.ReadTargetAddress(); Registers regs = new Registers(this); regs [(int)X86_Register.RBX].SetValue(lmf + 16, ebx); regs [(int)X86_Register.RDI].SetValue(lmf + 20, edi); regs [(int)X86_Register.RSI].SetValue(lmf + 24, esi); regs [(int)X86_Register.RBP].SetValue(lmf + 28, ebp); regs [(int)X86_Register.RIP].SetValue(lmf + 32, eip); TargetAddress new_ebp = memory.ReadAddress(ebp); regs [(int)X86_Register.RBP].SetValue(ebp, new_ebp); TargetAddress new_esp = ebp + 8; regs [(int)X86_Register.RSP].SetValue(ebp, new_esp); return(CreateFrame(thread.Client, FrameType.LMF, memory, eip, new_esp, new_ebp, regs)); }
void update(TargetMemoryAccess target) { // If this is a reference type, the register just holds the // address of the actual data, so read the address from the // register and return it. if (!register.Valid) { is_valid = false; return; } long contents = register.Value; if (contents == 0) { address = TargetAddress.Null; } else { address = new TargetAddress( target.AddressDomain, contents + regoffset); } if (is_byref && is_regoffset) { address = target.ReadAddress(address); } is_valid = true; }
public TargetAddress MonoClassGetFieldType(TargetMemoryAccess memory, TargetAddress klass, int index) { int offset = index * MonoMetadataInfo.FieldInfoSize + MonoMetadataInfo.FieldInfoTypeOffset; TargetAddress fields = memory.ReadAddress( klass + MonoMetadataInfo.KlassFieldOffset); if (fields.IsNull) { throw new TargetException(TargetError.ClassNotInitialized); } return(memory.ReadAddress(fields + offset)); }
public bool MonoClassHasMethods(TargetMemoryAccess memory, TargetAddress klass) { TargetAddress methods = memory.ReadAddress( klass + MonoMetadataInfo.KlassMethodsOffset); return(!methods.IsNull); }
internal void MonoArrayTypeGetBounds(TargetMemoryAccess memory, TargetAddress data) { // // FIXME: Only check whether the low bounds are all zero // int num_sizes = memory.ReadByte(data + memory.TargetAddressSize + 1); if (num_sizes != 0) { throw new InternalError(); } int num_lobounds = memory.ReadByte(data + memory.TargetAddressSize + 2); if (num_lobounds == 0) { return; } TargetAddress array = memory.ReadAddress(data + 3 * memory.TargetAddressSize); TargetBinaryReader bounds = memory.ReadMemory(array, num_lobounds * 4).GetReader(); for (int i = 0; i < num_lobounds; i++) { int bound = bounds.ReadInt32(); if (bound != 0) { throw new InternalError(); } } }
public MonoMethodSignature GetMethodSignature(MonoLanguageBackend mono, TargetMemoryAccess memory, TargetAddress signature) { int count = memory.ReadInteger(signature + 4) & 0x0000ffff; int offset = memory.TargetAddressSize == 8 ? 16 : 12; TargetAddress ret = memory.ReadAddress(signature + offset); TargetType ret_type = mono.ReadType(memory, ret); if (count == 0) { return(new MonoMethodSignature(ret_type, new TargetType [0])); } offset += memory.TargetAddressSize; TargetReader reader = new TargetReader( memory.ReadMemory(signature + offset, count * memory.TargetAddressSize)); TargetType[] param_types = new TargetType [count]; for (int i = 0; i < count; i++) { param_types [i] = mono.ReadType(memory, reader.ReadAddress()); } return(new MonoMethodSignature(ret_type, param_types)); }
internal override TargetAddress GetAddress(TargetMemoryAccess target) { TargetAddress address = reference.GetAddress (target); if (address.IsNull) return TargetAddress.Null; else return target.ReadAddress (address); }
internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory, byte[] code, int offset) { StackFrame new_frame; if ((code != null) && (code.Length > 3)) { new_frame = read_prologue(frame, memory, code, offset); if (new_frame != null) { return(new_frame); } } TargetAddress ebp = frame.FrameAddress; new_frame = do_hacks(frame, memory); if (new_frame != null) { return(new_frame); } int addr_size = TargetAddressSize; Registers regs = new Registers(this); TargetAddress new_ebp = memory.ReadAddress(ebp); regs [(int)X86_Register.RBP].SetValue(ebp, new_ebp); TargetAddress new_eip = memory.ReadAddress(ebp + addr_size); regs [(int)X86_Register.RIP].SetValue(ebp + addr_size, new_eip); TargetAddress new_esp = ebp + 2 * addr_size; regs [(int)X86_Register.RSP].SetValue(ebp, new_esp); ebp -= addr_size; return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs)); }
internal override TargetAddress GetAddress(TargetMemoryAccess target) { TargetAddress address = reference.GetAddress(target); if (address.IsNull) { return(TargetAddress.Null); } else { return(target.ReadAddress(address)); } }
public MonoClassInfo ResolveClass(TargetMemoryAccess target, bool fail) { if (resolved) { return(class_info); } if (class_info == null) { if (class_ptr.IsNull) { return(null); } TargetAddress klass = target.ReadAddress(class_ptr); if (klass.IsNull) { return(null); } class_info = File.MonoLanguage.ReadClassInfo(target, klass); } if (class_info == null) { if (!fail) { return(null); } throw new TargetException(TargetError.ClassNotInitialized, "Class `{0}' not initialized yet.", Name); } if (class_info.HasParent) { MonoClassInfo parent_info = class_info.GetParent(target); parent_type = (IMonoStructType)parent_info.Type; parent_type.ClassInfo = parent_info; if (parent_type.ResolveClass(target, fail) == null) { return(null); } } resolved = true; return(class_info); }
// // The following API is new in `terrania'. // public GenericClassInfo GetGenericClass(TargetMemoryAccess memory, TargetAddress address) { int addr_size = memory.TargetMemoryInfo.TargetAddressSize; TargetReader reader = new TargetReader(memory.ReadMemory(address, 5 * addr_size)); TargetAddress container = reader.ReadAddress(); TargetAddress class_inst = reader.ReadAddress(); reader.ReadAddress(); /* method_inst */ reader.ReadAddress(); TargetAddress cached_class = reader.ReadAddress(); int inst_id = memory.ReadInteger(class_inst); int inst_data = memory.ReadInteger(class_inst + 4); TargetAddress inst_argv; if (MonoDebuggerInfo.MajorVersion == 80) { inst_argv = memory.ReadAddress(class_inst + 8); } else { inst_argv = class_inst + 8; } int type_argc = inst_data & 0x3fffff; TargetReader argv_reader = new TargetReader( memory.ReadMemory(inst_argv, type_argc * addr_size)); TargetAddress[] type_args = new TargetAddress [type_argc]; for (int i = 0; i < type_argc; i++) { type_args [i] = argv_reader.ReadAddress(); } TargetAddress cached_class_ptr = address + 4 * addr_size; return(new GenericClassInfo(container, type_args, cached_class_ptr, cached_class)); }
internal bool GetTrampoline(TargetMemoryAccess memory, TargetAddress address, out TargetAddress trampoline, out bool is_start) { if (!has_got || (address < plt_start) || (address > plt_end)) { is_start = false; trampoline = TargetAddress.Null; return(false); } Instruction target_insn = Architecture.ReadInstruction(memory, address); if ((target_insn == null) || !target_insn.HasInstructionSize || ((target_insn.InstructionType != Instruction.Type.Jump) && (target_insn.InstructionType != Instruction.Type.IndirectJump))) { is_start = false; trampoline = TargetAddress.Null; return(false); } TargetAddress call_target = target_insn.GetEffectiveAddress(memory); if (call_target.IsNull) { is_start = false; trampoline = TargetAddress.Null; return(false); } if (call_target != address + target_insn.InstructionSize) { is_start = false; trampoline = call_target; return(true); } is_start = true; trampoline = memory.ReadAddress(got_start + 3 * info.TargetAddressSize); return(true); }
public override TargetAddress GetEffectiveAddress(TargetMemoryAccess memory) { if (!CallTarget.IsNull) { return(CallTarget); } Registers regs = memory.GetRegisters(); long effective_displacement = Displacement; if (IndexRegister >= 0) { long index = regs [IndexRegister].GetValue(); index *= 1 << SIB.Scale; effective_displacement += index; } TargetAddress effective_address; if (is_ip_relative) { effective_address = Address + InstructionSize; } else { effective_address = new TargetAddress( memory.AddressDomain, regs [Register].GetValue()); } effective_address += effective_displacement; if (DereferenceAddress) { effective_address = memory.ReadAddress(effective_address); } return(effective_address); }
StackFrame try_syscall_trampoline(StackFrame frame, TargetMemoryAccess memory) { /* * This is a hack for system call trampolines on NPTL-enabled glibc's. */ if (frame.TargetAddress.Address != 0xffffe002) { return(null); } Registers old_regs = frame.Registers; Registers regs = CopyRegisters(old_regs); TargetAddress esp = frame.StackPointer; TargetAddress new_eip = memory.ReadAddress(esp); TargetAddress new_esp = esp + 4; TargetAddress new_ebp = frame.FrameAddress; regs [(int)X86_Register.RIP].SetValue(esp, new_eip); regs [(int)X86_Register.RBP].SetValue(new_ebp); return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs)); }
public TargetAddress MonoArrayTypeGetClass(TargetMemoryAccess memory, TargetAddress atype) { return(memory.ReadAddress(atype)); }
public TargetAddress MonoMethodGetClass(TargetMemoryAccess memory, TargetAddress method) { return(memory.ReadAddress(method + MonoMetadataInfo.MonoMethodKlassOffset)); }
internal void MonoArrayTypeGetBounds(TargetMemoryAccess memory, TargetAddress data) { // // FIXME: Only check whether the low bounds are all zero // int num_sizes = memory.ReadByte (data + memory.TargetAddressSize + 1); if (num_sizes != 0) throw new InternalError (); int num_lobounds = memory.ReadByte (data + memory.TargetAddressSize + 2); if (num_lobounds == 0) return; TargetAddress array = memory.ReadAddress (data + 3 * memory.TargetAddressSize); TargetBinaryReader bounds = memory.ReadMemory (array, num_lobounds * 4).GetReader (); for (int i = 0; i < num_lobounds; i++) { int bound = bounds.ReadInt32 (); if (bound != 0) throw new InternalError (); } }
public TargetAddress MonoClassGetGenericContainer(TargetMemoryAccess memory, TargetAddress klass) { return(memory.ReadAddress(klass + MonoMetadataInfo.KlassGenericContainerOffset)); }
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); }
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 TargetAddress MonoClassGetParent(TargetMemoryAccess memory, TargetAddress klass) { return memory.ReadAddress (klass + MonoMetadataInfo.KlassParentOffset); }
void GetValue(TargetMemoryAccess target, Registers regs, TargetAddress cfa, int reg, Column column) { switch (column.State) { case State.Register: { GetRegisterValue (regs, reg, column); break; } case State.SameValue: regs [GetArchRegister (reg)].Valid = true; break; case State.Undefined: break; case State.Offset: { TargetAddress addr = cfa + column.Offset; long value = target.ReadAddress (addr).Address; regs [GetArchRegister (reg)].SetValue (address, value); break; } default: throw new NotSupportedException (); } }
StackFrame try_syscall_trampoline(StackFrame frame, TargetMemoryAccess memory) { /* * This is a hack for system call trampolines on NPTL-enabled glibc's. */ if (frame.TargetAddress.Address != 0xffffe002) return null; Registers old_regs = frame.Registers; Registers regs = CopyRegisters (old_regs); TargetAddress esp = frame.StackPointer; TargetAddress new_eip = memory.ReadAddress (esp); TargetAddress new_esp = esp + 4; TargetAddress new_ebp = frame.FrameAddress; regs [(int)X86_Register.RIP].SetValue (esp, new_eip); regs [(int)X86_Register.RBP].SetValue (new_ebp); return CreateFrame (frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs); }
public override TargetAddress GetEffectiveAddress(TargetMemoryAccess memory) { if (!CallTarget.IsNull) return CallTarget; Registers regs = memory.GetRegisters (); long effective_displacement = Displacement; if (IndexRegister >= 0) { long index = regs [IndexRegister].GetValue (); index *= 1 << SIB.Scale; effective_displacement += index; } TargetAddress effective_address; if (is_ip_relative) effective_address = Address + InstructionSize; else effective_address = new TargetAddress ( memory.AddressDomain, regs [Register].GetValue ()); effective_address += effective_displacement; if (DereferenceAddress) effective_address = memory.ReadAddress (effective_address); return effective_address; }
StackFrame unwind_method(StackFrame frame, TargetMemoryAccess memory, byte[] code, int pos, int offset) { Registers old_regs = frame.Registers; Registers regs = new Registers (old_regs); TargetAddress ebp = new TargetAddress ( memory.AddressDomain, old_regs [(int) X86_Register.RBP].GetValue ()); int addr_size = TargetAddressSize; TargetAddress new_ebp = memory.ReadAddress (ebp); regs [(int) X86_Register.RBP].SetValue (ebp, new_ebp); TargetAddress new_eip = memory.ReadAddress (ebp + addr_size); regs [(int) X86_Register.RIP].SetValue (ebp + addr_size, new_eip); TargetAddress new_esp = ebp + 2 * addr_size; regs [(int) X86_Register.RSP].SetValue (ebp, new_esp); regs [(int) X86_Register.RSI].Valid = true; regs [(int) X86_Register.RDI].Valid = true; ebp -= addr_size; int length = System.Math.Min (code.Length, offset); while (pos < length) { byte opcode = code [pos++]; if ((opcode < 0x50) || (opcode > 0x57)) break; long value; switch (opcode) { case 0x50: /* eax */ value = (long) (uint) memory.ReadInteger (ebp); regs [(int) X86_Register.RAX].SetValue (ebp, value); break; case 0x51: /* ecx */ value = (long) (uint) memory.ReadInteger (ebp); regs [(int) X86_Register.RCX].SetValue (ebp, value); break; case 0x52: /* edx */ value = (long) (uint) memory.ReadInteger (ebp); regs [(int) X86_Register.RDX].SetValue (ebp, value); break; case 0x53: /* ebx */ value = (long) (uint) memory.ReadInteger (ebp); regs [(int) X86_Register.RBX].SetValue (ebp, value); break; case 0x56: /* esi */ value = (long) (uint) memory.ReadInteger (ebp); regs [(int) X86_Register.RSI].SetValue (ebp, value); break; case 0x57: /* edi */ value = (long) (uint) memory.ReadInteger (ebp); regs [(int) X86_Register.RDI].SetValue (ebp, value); break; } ebp -= addr_size; } return CreateFrame (frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs); }
void update(TargetMemoryAccess target) { // If this is a reference type, the register just holds the // address of the actual data, so read the address from the // register and return it. if (!register.Valid) { is_valid = false; return; } long contents = register.Value; if (contents == 0) address = TargetAddress.Null; else address = new TargetAddress ( target.AddressDomain, contents + regoffset); if (is_byref && is_regoffset) address = target.ReadAddress (address); is_valid = true; }
public TargetAddress GetObjectClass(TargetMemoryAccess memory) { return(memory.ReadAddress(MonoMetadataInfo.MonoDefaultsAddress + MonoMetadataInfo.MonoDefaultsObjectOffset)); }
StackFrame try_pthread_cond_timedwait(StackFrame frame, TargetMemoryAccess memory) { Symbol name = frame.Name; /* * This is a hack for pthread_cond_timedwait() on Red Hat 9. */ if ((name == null) || (name.Name != "pthread_cond_timedwait") || (name.Offset != 0xe5)) return null; /* * Disassemble some bytes of the method to find out whether * it's the "correct" one. */ uint data = (uint) memory.ReadInteger (name.Address); if (data != 0x53565755) return null; data = (uint) memory.ReadInteger (name.Address + 4); if (data != 0x14245c8b) return null; data = (uint) memory.ReadInteger (name.Address + 8); if (data != 0x1c246c8b) return null; data = (uint) memory.ReadInteger (frame.TargetAddress); if (data != 0x8910eb83) return null; data = (uint) memory.ReadInteger (frame.TargetAddress + 0x7b); if (data != 0x852cc483) return null; data = (uint) memory.ReadInteger (frame.TargetAddress + 0x7f); if (data != 0xc6440fc0) return null; TargetAddress esp = frame.StackPointer; Registers regs = new Registers (this); TargetAddress ebx = memory.ReadAddress (esp + 0x2c); TargetAddress esi = memory.ReadAddress (esp + 0x30); TargetAddress edi = memory.ReadAddress (esp + 0x34); TargetAddress ebp = memory.ReadAddress (esp + 0x38); TargetAddress eip = memory.ReadAddress (esp + 0x3c); regs [(int)X86_Register.RBX].SetValue (esp + 0x2c, ebx); regs [(int)X86_Register.RSI].SetValue (esp + 0x30, esi); regs [(int)X86_Register.RDI].SetValue (esp + 0x34, edi); regs [(int)X86_Register.RBP].SetValue (esp + 0x38, ebp); regs [(int)X86_Register.RIP].SetValue (esp + 0x3c, eip); esp += 0x40; regs [(int)X86_Register.RSP].SetValue (esp.Address); return CreateFrame (frame.Thread, FrameType.Normal, memory, eip, esp, ebp, regs); }
public TargetAddress GetExceptionClass(TargetMemoryAccess memory) { return(memory.ReadAddress(MonoMetadataInfo.MonoDefaultsAddress + MonoMetadataInfo.MonoDefaultsExceptionOffset)); }
public TargetAddress MonoClassGetGenericContainer(TargetMemoryAccess memory, TargetAddress klass) { return memory.ReadAddress (klass + MonoMetadataInfo.KlassGenericContainerOffset); }
public TargetAddress MonoClassGetMethod(TargetMemoryAccess memory, TargetAddress klass, int index) { TargetAddress methods = memory.ReadAddress ( klass + MonoMetadataInfo.KlassMethodsOffset); if (methods.IsNull) throw new TargetException (TargetError.ClassNotInitialized); methods += index * memory.TargetAddressSize; return memory.ReadAddress (methods); }
public MonoClassInfo ResolveClass(TargetMemoryAccess target, bool fail) { if (resolved) return class_info; if (class_info == null) { if (class_ptr.IsNull) return null; TargetAddress klass = target.ReadAddress (class_ptr); if (klass.IsNull) return null; class_info = File.MonoLanguage.ReadClassInfo (target, klass); } if (class_info == null) { if (!fail) return null; throw new TargetException (TargetError.ClassNotInitialized, "Class `{0}' not initialized yet.", Name); } if (class_info.HasParent) { MonoClassInfo parent_info = class_info.GetParent (target); parent_type = (IMonoStructType) parent_info.Type; parent_type.ClassInfo = parent_info; if (parent_type.ResolveClass (target, fail) == null) return null; } resolved = true; return class_info; }
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); }
internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory, byte[] code, int offset) { StackFrame new_frame; if ((code != null) && (code.Length > 3)) { new_frame = read_prologue (frame, memory, code, offset); if (new_frame != null) return new_frame; } TargetAddress ebp = frame.FrameAddress; new_frame = do_hacks (frame, memory); if (new_frame != null) return new_frame; int addr_size = TargetAddressSize; Registers regs = new Registers (this); TargetAddress new_ebp = memory.ReadAddress (ebp); regs [(int) X86_Register.RBP].SetValue (ebp, new_ebp); TargetAddress new_eip = memory.ReadAddress (ebp + addr_size); regs [(int) X86_Register.RIP].SetValue (ebp + addr_size, new_eip); TargetAddress new_esp = ebp + 2 * addr_size; regs [(int) X86_Register.RSP].SetValue (ebp, new_esp); ebp -= addr_size; return CreateFrame (frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs); }
internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory, ref TargetAddress lmf_address) { TargetAddress lmf = lmf_address; TargetBinaryReader reader = memory.ReadMemory (lmf, 36).GetReader (); lmf_address = reader.ReadTargetAddress (); // prev reader.Position = 16; TargetAddress ebx = reader.ReadTargetAddress (); TargetAddress edi = reader.ReadTargetAddress (); TargetAddress esi = reader.ReadTargetAddress (); TargetAddress ebp = reader.ReadTargetAddress (); TargetAddress eip = reader.ReadTargetAddress (); Registers regs = new Registers (this); regs [(int) X86_Register.RBX].SetValue (lmf + 16, ebx); regs [(int) X86_Register.RDI].SetValue (lmf + 20, edi); regs [(int) X86_Register.RSI].SetValue (lmf + 24, esi); regs [(int) X86_Register.RBP].SetValue (lmf + 28, ebp); regs [(int) X86_Register.RIP].SetValue (lmf + 32, eip); TargetAddress new_ebp = memory.ReadAddress (ebp); regs [(int) X86_Register.RBP].SetValue (ebp, new_ebp); TargetAddress new_esp = ebp + 8; regs [(int) X86_Register.RSP].SetValue (ebp, new_esp); return CreateFrame (thread.Client, FrameType.LMF, memory, eip, new_esp, new_ebp, regs); }
internal TargetClassObject GetCurrentObject(TargetMemoryAccess target, TargetLocation location) { // location.Address resolves to the address of the MonoObject, // dereferencing it once gives us the vtable, dereferencing it // twice the class. TargetAddress address; address = target.ReadAddress (location.GetAddress (target)); address = target.ReadAddress (address); TargetType current = File.MonoLanguage.ReadMonoClass (target, address); if (current == null) return null; if (IsByRef && !current.IsByRef) // Unbox location = location.GetLocationAtOffset ( 2 * target.TargetMemoryInfo.TargetAddressSize); return (TargetClassObject) current.GetObject (target, location); }
// // Fundamental types // public TargetAddress GetBooleanClass(TargetMemoryAccess memory) { return memory.ReadAddress (MonoMetadataInfo.MonoDefaultsAddress + MonoMetadataInfo.MonoDefaultsBooleanOffset); }
// This method reads the MonoDebuggerSymbolTable structure // (struct definition is in mono-debug-debugger.h) void do_read_symbol_table(TargetMemoryAccess memory) { TargetAddress symtab_address = memory.ReadAddress (info.SymbolTable); if (symtab_address.IsNull) throw new SymbolTableException ("Symbol table is null."); TargetReader header = new TargetReader ( memory.ReadMemory (symtab_address, info.SymbolTableSize)); long magic = header.BinaryReader.ReadInt64 (); if (magic != MonoDebuggerInfo.DynamicMagic) throw new SymbolTableException ( "Debugger symbol table has unknown magic {0:x}.", magic); int version = header.ReadInteger (); if (version < MonoDebuggerInfo.MinDynamicVersion) throw new SymbolTableException ( "Debugger symbol table has version {0}, but " + "expected at least {1}.", version, MonoDebuggerInfo.MinDynamicVersion); if (version > MonoDebuggerInfo.MaxDynamicVersion) throw new SymbolTableException ( "Debugger symbol table has version {0}, but " + "expected at most {1}.", version, MonoDebuggerInfo.MaxDynamicVersion); int total_size = header.ReadInteger (); if (total_size != info.SymbolTableSize) throw new SymbolTableException ( "Debugger symbol table has size {0}, but " + "expected {1}.", total_size, info.SymbolTableSize); TargetAddress corlib_address = header.ReadAddress (); TargetAddress global_data_table_ptr = header.ReadAddress (); TargetAddress data_table_list = header.ReadAddress (); TargetAddress symfile_by_index = header.ReadAddress (); if (corlib_address.IsNull) throw new SymbolTableException ("Corlib address is null."); corlib = load_symfile (memory, corlib_address); if (corlib == null) throw new SymbolTableException ("Cannot read corlib!"); TargetAddress ptr = symfile_by_index; while (!ptr.IsNull) { TargetAddress next_ptr = memory.ReadAddress (ptr); TargetAddress address = memory.ReadAddress ( ptr + memory.TargetMemoryInfo.TargetAddressSize); ptr = next_ptr; load_symfile (memory, address); } ptr = data_table_list; while (!ptr.IsNull) { TargetAddress next_ptr = memory.ReadAddress (ptr); TargetAddress address = memory.ReadAddress ( ptr + memory.TargetMemoryInfo.TargetAddressSize); ptr = next_ptr; add_data_table (memory, address); } global_data_table = new GlobalDataTable (this, global_data_table_ptr); }
public TargetAddress MonoTypeGetData(TargetMemoryAccess memory, TargetAddress type) { return memory.ReadAddress (type); }
void read_mono_debugger_info(TargetMemoryAccess memory) { runtime = MetadataHelper.Create (memory, info); trampolines = new TargetAddress [info.MonoTrampolineNum]; TargetAddress address = info.MonoTrampolineCode; for (int i = 0; i < trampolines.Length; i++) { trampolines [i] = memory.ReadAddress (address); address += memory.TargetMemoryInfo.TargetAddressSize; } symfile_by_index = new Hashtable (); symfile_by_image_addr = new Hashtable (); symfile_hash = new Hashtable (); assembly_hash = new Hashtable (); assembly_by_name = new Hashtable (); class_hash = new Hashtable (); class_info_by_addr = new Dictionary<TargetAddress,MonoClassInfo> (); }
public TargetAddress MonoTypeGetData(TargetMemoryAccess memory, TargetAddress type) { return(memory.ReadAddress(type)); }
public void Read(TargetMemoryAccess memory) { int address_size = memory.TargetMemoryInfo.TargetAddressSize; int header_size = 16 + address_size; if (first_chunk.IsNull) { first_chunk = memory.ReadAddress (TableAddress + 8); current_chunk = first_chunk; } if (current_chunk.IsNull) return; again: TargetReader reader = new TargetReader ( memory.ReadMemory (current_chunk, header_size)); reader.ReadInteger (); /* size */ int allocated_size = reader.ReadInteger (); int current_offset = reader.ReadInteger (); reader.ReadInteger (); /* dummy */ TargetAddress next = reader.ReadAddress (); read_data_items (memory, current_chunk + header_size, last_offset, current_offset); last_offset = current_offset; if (!next.IsNull && (current_offset == allocated_size)) { current_chunk = next; last_offset = 0; goto again; } }
public TargetAddress MonoMethodGetClass(TargetMemoryAccess memory, TargetAddress method) { return memory.ReadAddress (method + MonoMetadataInfo.MonoMethodKlassOffset); }
public MethodSource GetTrampoline(TargetMemoryAccess memory, TargetAddress address) { #if FIXME int insn_size; TargetAddress target; CallTargetType type = memory.Architecture.GetCallTarget ( memory, address, out target, out insn_size); if (type != CallTargetType.MonoTrampoline) return null; int token = memory.ReadInteger (target + 4); TargetAddress klass = memory.ReadAddress (target + 8); TargetAddress image = memory.ReadAddress (klass); foreach (MonoSymbolFile file in symfile_by_index.Values) { if (file.MonoImage != image) continue; return file.GetMethodByToken (token); } #endif return null; }
public TargetAddress GetDelegateClass(TargetMemoryAccess memory) { return(memory.ReadAddress(MonoMetadataInfo.MonoDefaultsAddress + MonoMetadataInfo.MonoDefaultsDelegateOffset)); }
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 bool MonoClassHasMethods(TargetMemoryAccess memory, TargetAddress klass) { TargetAddress methods = memory.ReadAddress ( klass + MonoMetadataInfo.KlassMethodsOffset); return !methods.IsNull; }
internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory, byte[] code, int offset) { if ((code != null) && (code.Length > 4)) return read_prologue (frame, memory, code, offset); TargetAddress rbp = frame.FrameAddress; int addr_size = TargetAddressSize; Registers regs = CopyRegisters (frame.Registers); 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; return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs); }
// // MonoClass // public TargetAddress MonoClassGetMonoImage(TargetMemoryAccess memory, TargetAddress klass) { return(memory.ReadAddress(klass + MonoMetadataInfo.KlassImageOffset)); }
StackFrame read_prologue(StackFrame frame, TargetMemoryAccess memory, byte[] code, int offset) { int length = code.Length; int pos = 0; if (length < 4) return null; while ((pos < length) && (code [pos] == 0x90) || (code [pos] == 0xcc)) pos++; if (pos+5 >= length) { // unknown prologue return null; } if (pos >= offset) { Registers regs = CopyRegisters (frame.Registers); TargetAddress new_rip = memory.ReadAddress (frame.StackPointer); regs [(int) X86_Register.RIP].SetValue (frame.StackPointer, new_rip); TargetAddress new_rsp = frame.StackPointer + TargetAddressSize; TargetAddress new_rbp = frame.FrameAddress; regs [(int) X86_Register.RSP].SetValue (new_rsp); return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs); } // push %ebp if (code [pos++] != 0x55) { // unknown prologue return null; } if (pos >= offset) { Registers regs = CopyRegisters (frame.Registers); int addr_size = TargetAddressSize; TargetAddress new_rbp = memory.ReadAddress (frame.StackPointer); regs [(int) X86_Register.RBP].SetValue (frame.StackPointer, new_rbp); TargetAddress new_rsp = frame.StackPointer + addr_size; TargetAddress new_rip = memory.ReadAddress (new_rsp); regs [(int) X86_Register.RIP].SetValue (new_rsp, new_rip); new_rsp -= addr_size; regs [(int) X86_Register.RSP].SetValue (new_rsp); return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs); } if (code [pos++] != 0x48) { // unknown prologue return null; } // mov %ebp, %esp if (((code [pos] != 0x8b) || (code [pos+1] != 0xec)) && ((code [pos] != 0x89) || (code [pos+1] != 0xe5))) { // unknown prologue return null; } pos += 2; if (pos >= offset) return null; return unwind_method (frame, memory, code, pos, offset); }
public TargetAddress MonoClassGetFieldType(TargetMemoryAccess memory, TargetAddress klass, int index) { int offset = index * MonoMetadataInfo.FieldInfoSize + MonoMetadataInfo.FieldInfoTypeOffset; TargetAddress fields = memory.ReadAddress ( klass + MonoMetadataInfo.KlassFieldOffset); if (fields.IsNull) throw new TargetException (TargetError.ClassNotInitialized); return memory.ReadAddress (fields + offset); }
StackFrame read_prologue(StackFrame frame, TargetMemoryAccess memory, byte[] code, int offset) { int length = code.Length; int pos = 0; if (length < 4) { return(null); } while ((pos < length) && (code [pos] == 0x90) || (code [pos] == 0xcc)) { pos++; } if (pos + 5 >= length) { // unknown prologue return(null); } if (pos >= offset) { Registers regs = CopyRegisters(frame.Registers); TargetAddress new_rip = memory.ReadAddress(frame.StackPointer); regs [(int)X86_Register.RIP].SetValue(frame.StackPointer, new_rip); TargetAddress new_rsp = frame.StackPointer + TargetAddressSize; TargetAddress new_rbp = frame.FrameAddress; regs [(int)X86_Register.RSP].SetValue(new_rsp); return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs)); } // push %ebp if (code [pos++] != 0x55) { // unknown prologue return(null); } if (pos >= offset) { Registers regs = CopyRegisters(frame.Registers); int addr_size = TargetAddressSize; TargetAddress new_rbp = memory.ReadAddress(frame.StackPointer); regs [(int)X86_Register.RBP].SetValue(frame.StackPointer, new_rbp); TargetAddress new_rsp = frame.StackPointer + addr_size; TargetAddress new_rip = memory.ReadAddress(new_rsp); regs [(int)X86_Register.RIP].SetValue(new_rsp, new_rip); new_rsp -= addr_size; regs [(int)X86_Register.RSP].SetValue(new_rsp); return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs)); } if (code [pos++] != 0x48) { // unknown prologue return(null); } // mov %ebp, %esp if (((code [pos] != 0x8b) || (code [pos + 1] != 0xec)) && ((code [pos] != 0x89) || (code [pos + 1] != 0xe5))) { // unknown prologue return(null); } pos += 2; if (pos >= offset) { return(null); } return(unwind_method(frame, memory, code, pos, offset)); }