bool EmulateInstruction::ReadRegisterDefault(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue ®_value) { StreamFile strm(stdout, false); strm.Printf(" Read Register (%s)\n", reg_info->name); lldb::RegisterKind reg_kind; uint32_t reg_num; if (GetBestRegisterKindAndNumber(reg_info, reg_kind, reg_num)) reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num); else reg_value.SetUInt64(0); return true; }
bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { if (!reg_info) return false; const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; if (IsFPR(reg)) { if (!ReadFPR()) return false; uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset; value.SetUInt64(*(uint64_t*)src); } else if (IsGPR(reg)) { bool success = ReadRegister(reg, value); if (success) { // If our return byte size was greater than the return value reg size, then // use the type specified by reg_info rather than the uint64_t default if (value.GetByteSize() > reg_info->byte_size) value.SetType(reg_info); } return success; } return false; }
Error NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset, const char* reg_name, uint32_t size, RegisterValue &value) { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); long data; Error error = NativeProcessLinux::PtraceWrapper( PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), nullptr, 0, &data); if (error.Success()) // First cast to an unsigned of the same size to avoid sign extension. value.SetUInt64(static_cast<unsigned long>(data)); if (log) log->Printf ("NativeRegisterContextLinux::%s() reg %s: 0x%lx", __FUNCTION__, reg_name, data); return error; }
bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { if (!reg_info) return false; const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; if (IsFPR(reg)) { if (!ReadFPR()) return false; } else { return ReadRegister(reg, value); } // Get pointer to m_fpr variable and set the data from it. assert (reg_info->byte_offset < sizeof m_fpr); uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset; switch (reg_info->byte_size) { case 2: value.SetUInt16(*(uint16_t *)src); return true; case 4: value.SetUInt32(*(uint32_t *)src); return true; case 8: value.SetUInt64(*(uint64_t *)src); return true; default: assert(false && "Unhandled data size."); return false; } }
bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) { if (!CacheAllRegisterValues()) return false; switch (reg_info->kinds[eRegisterKindLLDB]) { case lldb_rax_x86_64: reg_value.SetUInt64(m_context.Rax); break; case lldb_rbx_x86_64: reg_value.SetUInt64(m_context.Rbx); break; case lldb_rcx_x86_64: reg_value.SetUInt64(m_context.Rcx); break; case lldb_rdx_x86_64: reg_value.SetUInt64(m_context.Rdx); break; case lldb_rdi_x86_64: reg_value.SetUInt64(m_context.Rdi); break; case lldb_rsi_x86_64: reg_value.SetUInt64(m_context.Rsi); break; case lldb_r8_x86_64: reg_value.SetUInt64(m_context.R8); break; case lldb_r9_x86_64: reg_value.SetUInt64(m_context.R9); break; case lldb_r10_x86_64: reg_value.SetUInt64(m_context.R10); break; case lldb_r11_x86_64: reg_value.SetUInt64(m_context.R11); break; case lldb_r12_x86_64: reg_value.SetUInt64(m_context.R12); break; case lldb_r13_x86_64: reg_value.SetUInt64(m_context.R13); break; case lldb_r14_x86_64: reg_value.SetUInt64(m_context.R14); break; case lldb_r15_x86_64: reg_value.SetUInt64(m_context.R15); break; case lldb_rbp_x86_64: reg_value.SetUInt64(m_context.Rbp); break; case lldb_rsp_x86_64: reg_value.SetUInt64(m_context.Rsp); break; case lldb_rip_x86_64: reg_value.SetUInt64(m_context.Rip); break; case lldb_rflags_x86_64: reg_value.SetUInt64(m_context.EFlags); break; } return true; }
bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextDarwin_arm64::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: value.SetUInt64(gpr.x[reg - gpr_x0]); break; case gpr_w0: case gpr_w1: case gpr_w2: case gpr_w3: case gpr_w4: case gpr_w5: case gpr_w6: case gpr_w7: case gpr_w8: case gpr_w9: case gpr_w10: case gpr_w11: case gpr_w12: case gpr_w13: case gpr_w14: case gpr_w15: case gpr_w16: case gpr_w17: case gpr_w18: case gpr_w19: case gpr_w20: case gpr_w21: case gpr_w22: case gpr_w23: case gpr_w24: case gpr_w25: case gpr_w26: case gpr_w27: case gpr_w28: { ProcessSP process_sp(m_thread.GetProcess()); if (process_sp.get()) { DataExtractor regdata(&gpr.x[reg - gpr_w0], 8, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); offset_t offset = 0; uint64_t retval = regdata.GetMaxU64(&offset, 8); uint32_t retval_lower32 = static_cast<uint32_t>(retval & 0xffffffff); value.SetUInt32(retval_lower32); } } 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: value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, endian::InlHostByteOrder()); break; case fpu_s0: case fpu_s1: case fpu_s2: case fpu_s3: case fpu_s4: case fpu_s5: case fpu_s6: case fpu_s7: case fpu_s8: case fpu_s9: case fpu_s10: case fpu_s11: case fpu_s12: case fpu_s13: case fpu_s14: case fpu_s15: case fpu_s16: case fpu_s17: case fpu_s18: case fpu_s19: case fpu_s20: case fpu_s21: case fpu_s22: case fpu_s23: case fpu_s24: case fpu_s25: case fpu_s26: case fpu_s27: case fpu_s28: case fpu_s29: case fpu_s30: case fpu_s31: { ProcessSP process_sp(m_thread.GetProcess()); if (process_sp.get()) { DataExtractor regdata(&fpu.v[reg - fpu_s0], 4, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); offset_t offset = 0; value.SetFloat(regdata.GetFloat(&offset)); } } break; case fpu_d0: case fpu_d1: case fpu_d2: case fpu_d3: case fpu_d4: case fpu_d5: case fpu_d6: case fpu_d7: case fpu_d8: case fpu_d9: case fpu_d10: case fpu_d11: case fpu_d12: case fpu_d13: case fpu_d14: case fpu_d15: case fpu_d16: case fpu_d17: case fpu_d18: case fpu_d19: case fpu_d20: case fpu_d21: case fpu_d22: case fpu_d23: case fpu_d24: case fpu_d25: case fpu_d26: case fpu_d27: case fpu_d28: case fpu_d29: case fpu_d30: case fpu_d31: { ProcessSP process_sp(m_thread.GetProcess()); if (process_sp.get()) { DataExtractor regdata(&fpu.v[reg - fpu_s0], 8, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); offset_t offset = 0; value.SetDouble(regdata.GetDouble(&offset)); } } break; case fpu_fpsr: value.SetUInt32(fpu.fpsr); break; case fpu_fpcr: value.SetUInt32(fpu.fpcr); break; case exc_exception: value.SetUInt32(exc.exception); break; case exc_esr: value.SetUInt32(exc.esr); break; case exc_far: value.SetUInt64(exc.far); break; default: value.SetValueToInvalid(); return false; } return true; }
bool RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; int set = RegisterContextDarwin_arm64::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: value.SetUInt64 (gpr.x[reg - gpr_x0]); 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: value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); break; case fpu_fpsr: value.SetUInt32 (fpu.fpsr); break; case fpu_fpcr: value.SetUInt32 (fpu.fpcr); break; case exc_exception: value.SetUInt32 (exc.exception); break; case exc_esr: value.SetUInt32 (exc.esr); break; case exc_far: value.SetUInt64 (exc.far); break; default: value.SetValueToInvalid(); return false; } return true; }
Status NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info, 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 " "read directly", reg_info->name); if (IsGPR(reg)) { s390_regs regs; Status error = DoReadGPR(®s, sizeof(regs)); if (error.Fail()) return error; uint8_t *src = (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: reg_value.SetUInt32(*(uint32_t *)src); break; case 8: reg_value.SetUInt64(*(uint64_t *)src); break; default: assert(false && "Unhandled data size."); return Status("unhandled byte size: %" PRIu32, reg_info->byte_size); } return Status(); } 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 FPR, not the whole user area. uint8_t *src = (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: reg_value.SetUInt32(*(uint32_t *)src); break; case 8: reg_value.SetUInt64(*(uint64_t *)src); break; default: assert(false && "Unhandled data size."); return Status("unhandled byte size: %" PRIu32, reg_info->byte_size); } return Status(); } if (reg == lldb_last_break_s390x) { uint64_t last_break; Status error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8); if (error.Fail()) return error; reg_value.SetUInt64(last_break); return Status(); } if (reg == lldb_system_call_s390x) { uint32_t system_call; Status error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4); if (error.Fail()) return error; reg_value.SetUInt32(system_call); return Status(); } return Status("failed - register wasn't recognized"); }
lldb_private::Error NativeRegisterContextLinux_mips64::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) { Error error; if (!reg_info) { error.SetErrorString ("reg_info NULL"); return error; } const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) { // This is likely an internal register for lldb use only and should not be directly queried. error.SetErrorStringWithFormat ("register \"%s\" is an internal-only lldb register, cannot read directly", reg_info->name); return error; } if (IsMSA(reg) && !IsMSAAvailable()) { error.SetErrorString ("MSA not available on this processor"); return error; } if (IsMSA(reg) || IsFPR(reg)) { uint8_t *src; error = ReadCP1(); if (!error.Success()) { error.SetErrorString ("failed to read co-processor 1 register"); return error; } if (IsFPR(reg)) { assert (reg_info->byte_offset < sizeof(UserArea)); src = (uint8_t *)&m_fpr + reg_info->byte_offset - (sizeof(m_gpr)); } else { assert (reg_info->byte_offset < sizeof(UserArea)); src = (uint8_t *)&m_msa + reg_info->byte_offset - (sizeof(m_gpr) + sizeof(m_fpr)); } switch (reg_info->byte_size) { case 4: reg_value.SetUInt32(*(uint32_t *)src); break; case 8: reg_value.SetUInt64(*(uint64_t *)src); break; case 16: reg_value.SetBytes((const void *)src, 16, GetByteOrder()); break; default: assert(false && "Unhandled data size."); error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size); break; } } else { error = ReadRegisterRaw(reg, reg_value); } return error; }
bool RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) { if (!m_cursor_is_valid) return false; uint64_t reg_value = LLDB_INVALID_ADDRESS; switch (reg_info->kinds[eRegisterKindGeneric]) { case LLDB_REGNUM_GENERIC_PC: if (m_cursor.pc == LLDB_INVALID_ADDRESS) return false; reg_value = m_cursor.pc; break; case LLDB_REGNUM_GENERIC_FP: if (m_cursor.fp == LLDB_INVALID_ADDRESS) return false; reg_value = m_cursor.fp; break; default: return false; } switch (reg_info->encoding) { case eEncodingInvalid: case eEncodingVector: break; case eEncodingUint: case eEncodingSint: value.SetUInt(reg_value, reg_info->byte_size); return true; case eEncodingIEEE754: switch (reg_info->byte_size) { case sizeof (float): if (sizeof (float) == sizeof(uint32_t)) { value.SetUInt32(reg_value, RegisterValue::eTypeFloat); return true; } else if (sizeof (float) == sizeof(uint64_t)) { value.SetUInt64(reg_value, RegisterValue::eTypeFloat); return true; } break; case sizeof (double): if (sizeof (double) == sizeof(uint32_t)) { value.SetUInt32(reg_value, RegisterValue::eTypeDouble); return true; } else if (sizeof (double) == sizeof(uint64_t)) { value.SetUInt64(reg_value, RegisterValue::eTypeDouble); return true; } break; // TOOD: need a better way to detect when "long double" types are // the same bytes size as "double" #if !defined(__arm__) case sizeof (long double): if (sizeof (long double) == sizeof(uint32_t)) { value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble); return true; } else if (sizeof (long double) == sizeof(uint64_t)) { value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble); return true; } break; #endif } break; } return false; }