bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) { // Since we cannot only write a single register value to the inferior, we need to make sure // our cached copy of the register values are fresh. Otherwise when writing EAX, for example, // we may also overwrite some other register with a stale value. if (!CacheAllRegisterValues()) return false; switch (reg_info->kinds[eRegisterKindLLDB]) { case lldb_eax_i386: m_context.Eax = reg_value.GetAsUInt32(); break; case lldb_ebx_i386: m_context.Ebx = reg_value.GetAsUInt32(); break; case lldb_ecx_i386: m_context.Ecx = reg_value.GetAsUInt32(); break; case lldb_edx_i386: m_context.Edx = reg_value.GetAsUInt32(); break; case lldb_edi_i386: m_context.Edi = reg_value.GetAsUInt32(); break; case lldb_esi_i386: m_context.Esi = reg_value.GetAsUInt32(); break; case lldb_ebp_i386: m_context.Ebp = reg_value.GetAsUInt32(); break; case lldb_esp_i386: m_context.Esp = reg_value.GetAsUInt32(); break; case lldb_eip_i386: m_context.Eip = reg_value.GetAsUInt32(); break; case lldb_eflags_i386: m_context.EFlags = reg_value.GetAsUInt32(); break; } // Physically update the registers in the target process. TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); }
bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = GetSetForNativeRegNum(reg); if (set == -1) return false; if (ReadRegisterSet(set, false) != KERN_SUCCESS) return false; switch (reg) { case gpr_x0: case gpr_x1: case gpr_x2: case gpr_x3: case gpr_x4: case gpr_x5: case gpr_x6: case gpr_x7: case gpr_x8: case gpr_x9: case gpr_x10: case gpr_x11: case gpr_x12: case gpr_x13: case gpr_x14: case gpr_x15: case gpr_x16: case gpr_x17: case gpr_x18: case gpr_x19: case gpr_x20: case gpr_x21: case gpr_x22: case gpr_x23: case gpr_x24: case gpr_x25: case gpr_x26: case gpr_x27: case gpr_x28: case gpr_fp: case gpr_sp: case gpr_lr: case gpr_pc: case gpr_cpsr: gpr.x[reg - gpr_x0] = value.GetAsUInt64(); break; case fpu_v0: case fpu_v1: case fpu_v2: case fpu_v3: case fpu_v4: case fpu_v5: case fpu_v6: case fpu_v7: case fpu_v8: case fpu_v9: case fpu_v10: case fpu_v11: case fpu_v12: case fpu_v13: case fpu_v14: case fpu_v15: case fpu_v16: case fpu_v17: case fpu_v18: case fpu_v19: case fpu_v20: case fpu_v21: case fpu_v22: case fpu_v23: case fpu_v24: case fpu_v25: case fpu_v26: case fpu_v27: case fpu_v28: case fpu_v29: case fpu_v30: case fpu_v31: ::memcpy(fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize()); break; case fpu_fpsr: fpu.fpsr = value.GetAsUInt32(); break; case fpu_fpcr: fpu.fpcr = value.GetAsUInt32(); break; case exc_exception: exc.exception = value.GetAsUInt32(); break; case exc_esr: exc.esr = value.GetAsUInt32(); break; case exc_far: exc.far = value.GetAsUInt64(); break; default: return false; } return WriteRegisterSet(set) == KERN_SUCCESS; }
bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; if (IsGPR(reg)) return WriteRegister(reg, value); if (IsFPR(reg, GetFPRType())) { switch (reg) { default: if (reg_info->encoding != eEncodingVector) return false; if (reg >= fpu_stmm0 && reg <= fpu_stmm7) ::memcpy (m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); if (reg >= fpu_xmm0 && reg <= fpu_xmm15) ::memcpy (m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); if (reg >= fpu_ymm0 && reg <= fpu_ymm15) { if (GetFPRType() != eXSAVE) return false; // the target processor does not support AVX // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes ::memcpy (m_ymm_set.ymm[reg - fpu_ymm0].bytes, value.GetBytes(), value.GetByteSize()); if (false == CopyYMMtoXSTATE(reg, GetByteOrder())) return false; } break; case fpu_dp: m_fpr.xstate.fxsave.dp = value.GetAsUInt64(); break; case fpu_fcw: m_fpr.xstate.fxsave.fcw = value.GetAsUInt16(); break; case fpu_fsw: m_fpr.xstate.fxsave.fsw = value.GetAsUInt16(); break; case fpu_ip: m_fpr.xstate.fxsave.ip = value.GetAsUInt64(); break; case fpu_fop: m_fpr.xstate.fxsave.fop = value.GetAsUInt16(); break; case fpu_ftw: m_fpr.xstate.fxsave.ftw = value.GetAsUInt16(); break; case fpu_mxcsr: m_fpr.xstate.fxsave.mxcsr = value.GetAsUInt32(); break; case fpu_mxcsrmask: m_fpr.xstate.fxsave.mxcsrmask = value.GetAsUInt32(); break; } if (WriteFPR()) { if (IsAVX(reg)) return CopyYMMtoXSTATE(reg, GetByteOrder()); return true; } } return false; }
Status NativeRegisterContextLinux_s390x::WriteRegister( const RegisterInfo *reg_info, const RegisterValue ®_value) { if (!reg_info) return Status("reg_info NULL"); const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) return Status("register \"%s\" is an internal-only lldb register, cannot " "write directly", reg_info->name); if (IsGPR(reg)) { s390_regs regs; Status error = DoReadGPR(®s, sizeof(regs)); if (error.Fail()) return error; uint8_t *dst = (uint8_t *)®s + reg_info->byte_offset; assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs)); switch (reg_info->byte_size) { case 4: *(uint32_t *)dst = reg_value.GetAsUInt32(); break; case 8: *(uint64_t *)dst = reg_value.GetAsUInt64(); break; default: assert(false && "Unhandled data size."); return Status("unhandled byte size: %" PRIu32, reg_info->byte_size); } return DoWriteGPR(®s, sizeof(regs)); } if (IsFPR(reg)) { s390_fp_regs fp_regs; Status error = DoReadFPR(&fp_regs, sizeof(fp_regs)); if (error.Fail()) return error; // byte_offset is just the offset within fp_regs, not the whole user area. uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset; assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs)); switch (reg_info->byte_size) { case 4: *(uint32_t *)dst = reg_value.GetAsUInt32(); break; case 8: *(uint64_t *)dst = reg_value.GetAsUInt64(); break; default: assert(false && "Unhandled data size."); return Status("unhandled byte size: %" PRIu32, reg_info->byte_size); } return DoWriteFPR(&fp_regs, sizeof(fp_regs)); } if (reg == lldb_last_break_s390x) { return Status("The last break address is read-only"); } if (reg == lldb_system_call_s390x) { uint32_t system_call = reg_value.GetAsUInt32(); return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4); } return Status("failed - register wasn't recognized"); }
lldb_private::Error NativeRegisterContextLinux_mips64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) { Error error; assert (reg_info && "reg_info is null"); const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg_index == LLDB_INVALID_REGNUM) return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>"); if (IsMSA(reg_index) && !IsMSAAvailable()) { error.SetErrorString ("MSA not available on this processor"); return error; } if (IsFPR(reg_index) || IsMSA(reg_index)) { uint8_t *dst; uint64_t *src; // Initialise the FP and MSA buffers by reading all co-processor 1 registers ReadCP1(); if (IsFPR(reg_index)) { assert (reg_info->byte_offset < sizeof(UserArea)); dst = (uint8_t *)&m_fpr + reg_info->byte_offset - (sizeof(m_gpr)); } else { assert (reg_info->byte_offset < sizeof(UserArea)); dst = (uint8_t *)&m_msa + reg_info->byte_offset - (sizeof(m_gpr) + sizeof(m_fpr)); } switch (reg_info->byte_size) { case 4: *(uint32_t *)dst = reg_value.GetAsUInt32(); break; case 8: *(uint64_t *)dst = reg_value.GetAsUInt64(); break; case 16: src = (uint64_t *)reg_value.GetBytes(); *(uint64_t *)dst = *src; *(uint64_t *)(dst + 8) = *(src + 1); break; default: assert(false && "Unhandled data size."); error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size); break; } error = WriteCP1(); if (!error.Success()) { error.SetErrorString ("failed to write co-processor 1 register"); return error; } } else { error = WriteRegisterRaw(reg_index, reg_value); } return error; }
bool RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg); if (set == -1) return false; if (ReadRegisterSet(set, false) != 0) return false; switch (reg) { case gpr_rax: case gpr_rbx: case gpr_rcx: case gpr_rdx: case gpr_rdi: case gpr_rsi: case gpr_rbp: case gpr_rsp: case gpr_r8: case gpr_r9: case gpr_r10: case gpr_r11: case gpr_r12: case gpr_r13: case gpr_r14: case gpr_r15: case gpr_rip: case gpr_rflags: case gpr_cs: case gpr_fs: case gpr_gs: (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64(); break; case fpu_fcw: fpu.fcw = value.GetAsUInt16(); break; case fpu_fsw: fpu.fsw = value.GetAsUInt16(); break; case fpu_ftw: fpu.ftw = value.GetAsUInt8(); break; case fpu_fop: fpu.fop = value.GetAsUInt16(); break; case fpu_ip: fpu.ip = value.GetAsUInt32(); break; case fpu_cs: fpu.cs = value.GetAsUInt16(); break; case fpu_dp: fpu.dp = value.GetAsUInt32(); break; case fpu_ds: fpu.ds = value.GetAsUInt16(); break; case fpu_mxcsr: fpu.mxcsr = value.GetAsUInt32(); break; case fpu_mxcsrmask: fpu.mxcsrmask = value.GetAsUInt32(); break; case fpu_stmm0: case fpu_stmm1: case fpu_stmm2: case fpu_stmm3: case fpu_stmm4: case fpu_stmm5: case fpu_stmm6: case fpu_stmm7: ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); break; case fpu_xmm0: case fpu_xmm1: case fpu_xmm2: case fpu_xmm3: case fpu_xmm4: case fpu_xmm5: case fpu_xmm6: case fpu_xmm7: case fpu_xmm8: case fpu_xmm9: case fpu_xmm10: case fpu_xmm11: case fpu_xmm12: case fpu_xmm13: case fpu_xmm14: case fpu_xmm15: ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); return false; case exc_trapno: exc.trapno = value.GetAsUInt32(); break; case exc_err: exc.err = value.GetAsUInt32(); break; case exc_faultvaddr: exc.faultvaddr = value.GetAsUInt64(); break; default: return false; } return WriteRegisterSet(set) == 0; }
bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) { // Since we cannot only write a single register value to the inferior, we need to make sure // our cached copy of the register values are fresh. Otherwise when writing EAX, for example, // we may also overwrite some other register with a stale value. if (!CacheAllRegisterValues()) return false; uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; switch (reg) { case lldb_eax_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX", reg_value.GetAsUInt32()); m_context.Eax = reg_value.GetAsUInt32(); break; case lldb_ebx_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX", reg_value.GetAsUInt32()); m_context.Ebx = reg_value.GetAsUInt32(); break; case lldb_ecx_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX", reg_value.GetAsUInt32()); m_context.Ecx = reg_value.GetAsUInt32(); break; case lldb_edx_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX", reg_value.GetAsUInt32()); m_context.Edx = reg_value.GetAsUInt32(); break; case lldb_edi_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI", reg_value.GetAsUInt32()); m_context.Edi = reg_value.GetAsUInt32(); break; case lldb_esi_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI", reg_value.GetAsUInt32()); m_context.Esi = reg_value.GetAsUInt32(); break; case lldb_ebp_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP", reg_value.GetAsUInt32()); m_context.Ebp = reg_value.GetAsUInt32(); break; case lldb_esp_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP", reg_value.GetAsUInt32()); m_context.Esp = reg_value.GetAsUInt32(); break; case lldb_eip_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP", reg_value.GetAsUInt32()); m_context.Eip = reg_value.GetAsUInt32(); break; case lldb_eflags_i386: WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS", reg_value.GetAsUInt32()); m_context.EFlags = reg_value.GetAsUInt32(); break; default: WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to unknown register %u", reg_value.GetAsUInt32(), reg); } // Physically update the registers in the target process. TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); }
bool RegisterContextDarwin_i386::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = GetSetForNativeRegNum (reg); if (set == -1) return false; if (ReadRegisterSet(set, false) != 0) return false; switch (reg) { case gpr_eax: case gpr_ebx: case gpr_ecx: case gpr_edx: case gpr_edi: case gpr_esi: case gpr_ebp: case gpr_esp: case gpr_ss: case gpr_eflags: case gpr_eip: case gpr_cs: case gpr_ds: case gpr_es: case gpr_fs: case gpr_gs: (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32(); break; case fpu_fcw: fpu.fcw = value.GetAsUInt16(); break; case fpu_fsw: fpu.fsw = value.GetAsUInt16(); break; case fpu_ftw: fpu.ftw = value.GetAsUInt8(); break; case fpu_fop: fpu.fop = value.GetAsUInt16(); break; case fpu_ip: fpu.ip = value.GetAsUInt32(); break; case fpu_cs: fpu.cs = value.GetAsUInt16(); break; case fpu_dp: fpu.dp = value.GetAsUInt32(); break; case fpu_ds: fpu.ds = value.GetAsUInt16(); break; case fpu_mxcsr: fpu.mxcsr = value.GetAsUInt32(); break; case fpu_mxcsrmask: fpu.mxcsrmask = value.GetAsUInt32(); break; case fpu_stmm0: case fpu_stmm1: case fpu_stmm2: case fpu_stmm3: case fpu_stmm4: case fpu_stmm5: case fpu_stmm6: case fpu_stmm7: // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() // must be used for these registers ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); return false; case fpu_xmm0: case fpu_xmm1: case fpu_xmm2: case fpu_xmm3: case fpu_xmm4: case fpu_xmm5: case fpu_xmm6: case fpu_xmm7: // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() // must be used for these registers ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); return false; case exc_trapno: exc.trapno = value.GetAsUInt32(); break; case exc_err: exc.err = value.GetAsUInt32(); break; case exc_faultvaddr: exc.faultvaddr = value.GetAsUInt32(); break; default: return false; } return WriteRegisterSet(set) == 0; }