1254721Semaste//===-- RegisterContext.cpp -------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Target/RegisterContext.h" 10314564Sdim#include "lldb/Core/Module.h" 11314564Sdim#include "lldb/Core/Value.h" 12314564Sdim#include "lldb/Expression/DWARFExpression.h" 13254721Semaste#include "lldb/Target/ExecutionContext.h" 14314564Sdim#include "lldb/Target/Process.h" 15254721Semaste#include "lldb/Target/StackFrame.h" 16314564Sdim#include "lldb/Target/Target.h" 17254721Semaste#include "lldb/Target/Thread.h" 18321369Sdim#include "lldb/Utility/DataExtractor.h" 19321369Sdim#include "lldb/Utility/Endian.h" 20344779Sdim#include "lldb/Utility/RegisterValue.h" 21344779Sdim#include "lldb/Utility/Scalar.h" 22254721Semaste 23254721Semasteusing namespace lldb; 24254721Semasteusing namespace lldb_private; 25254721Semaste 26314564SdimRegisterContext::RegisterContext(Thread &thread, uint32_t concrete_frame_idx) 27314564Sdim : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx), 28314564Sdim m_stop_id(thread.GetProcess()->GetStopID()) {} 29254721Semaste 30309124SdimRegisterContext::~RegisterContext() = default; 31254721Semaste 32314564Sdimvoid RegisterContext::InvalidateIfNeeded(bool force) { 33314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 34314564Sdim bool invalidate = force; 35314564Sdim uint32_t process_stop_id = UINT32_MAX; 36254721Semaste 37314564Sdim if (process_sp) 38314564Sdim process_stop_id = process_sp->GetStopID(); 39314564Sdim else 40314564Sdim invalidate = true; 41254721Semaste 42314564Sdim if (!invalidate) 43314564Sdim invalidate = process_stop_id != GetStopID(); 44314564Sdim 45314564Sdim if (invalidate) { 46314564Sdim InvalidateAllRegisters(); 47314564Sdim SetStopID(process_stop_id); 48314564Sdim } 49254721Semaste} 50254721Semaste 51254721Semasteconst RegisterInfo * 52314564SdimRegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, 53314564Sdim uint32_t start_idx) { 54314564Sdim if (reg_name.empty()) 55314564Sdim return nullptr; 56254721Semaste 57314564Sdim const uint32_t num_registers = GetRegisterCount(); 58314564Sdim for (uint32_t reg = start_idx; reg < num_registers; ++reg) { 59314564Sdim const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); 60314564Sdim 61314564Sdim if (reg_name.equals_lower(reg_info->name) || 62314564Sdim reg_name.equals_lower(reg_info->alt_name)) 63314564Sdim return reg_info; 64314564Sdim } 65314564Sdim return nullptr; 66254721Semaste} 67254721Semaste 68309124Sdimuint32_t 69314564SdimRegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch, 70314564Sdim RegisterInfo *reg_info) { 71314564Sdim ExecutionContext exe_ctx(CalculateThread()); 72309124Sdim 73314564Sdim // In MIPS, the floating point registers size is depends on FR bit of SR 74341825Sdim // register. if SR.FR == 1 then all floating point registers are 64 bits. 75314564Sdim // else they are all 32 bits. 76309124Sdim 77314564Sdim int expr_result; 78314564Sdim uint32_t addr_size = arch.GetAddressByteSize(); 79314564Sdim const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes; 80314564Sdim const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; 81314564Sdim 82314564Sdim DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len, 83314564Sdim arch.GetByteOrder(), addr_size); 84314564Sdim ModuleSP opcode_ctx; 85360784Sdim DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr); 86314564Sdim Value result; 87321369Sdim Status error; 88327952Sdim if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr, 89360784Sdim eRegisterKindDWARF, nullptr, nullptr, result, 90360784Sdim &error)) { 91314564Sdim expr_result = result.GetScalar().SInt(-1); 92314564Sdim switch (expr_result) { 93314564Sdim case 0: 94314564Sdim return 4; 95314564Sdim case 1: 96314564Sdim return 8; 97314564Sdim default: 98314564Sdim return reg_info->byte_size; 99309124Sdim } 100314564Sdim } else { 101314564Sdim printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString()); 102314564Sdim return reg_info->byte_size; 103314564Sdim } 104309124Sdim} 105309124Sdim 106314564Sdimconst RegisterInfo *RegisterContext::GetRegisterInfo(lldb::RegisterKind kind, 107314564Sdim uint32_t num) { 108314564Sdim const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num); 109314564Sdim if (reg_num == LLDB_INVALID_REGNUM) 110314564Sdim return nullptr; 111314564Sdim return GetRegisterInfoAtIndex(reg_num); 112258054Semaste} 113258054Semaste 114314564Sdimconst char *RegisterContext::GetRegisterName(uint32_t reg) { 115314564Sdim const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); 116314564Sdim if (reg_info) 117314564Sdim return reg_info->name; 118314564Sdim return nullptr; 119254721Semaste} 120254721Semaste 121314564Sdimuint64_t RegisterContext::GetPC(uint64_t fail_value) { 122314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 123314564Sdim LLDB_REGNUM_GENERIC_PC); 124314564Sdim uint64_t pc = ReadRegisterAsUnsigned(reg, fail_value); 125296417Sdim 126314564Sdim if (pc != fail_value) { 127314564Sdim TargetSP target_sp = m_thread.CalculateTarget(); 128314564Sdim if (target_sp) { 129314564Sdim Target *target = target_sp.get(); 130314564Sdim if (target) 131341825Sdim pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode); 132296417Sdim } 133314564Sdim } 134296417Sdim 135314564Sdim return pc; 136254721Semaste} 137254721Semaste 138314564Sdimbool RegisterContext::SetPC(uint64_t pc) { 139314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 140314564Sdim LLDB_REGNUM_GENERIC_PC); 141314564Sdim bool success = WriteRegisterFromUnsigned(reg, pc); 142314564Sdim if (success) { 143314564Sdim StackFrameSP frame_sp( 144314564Sdim m_thread.GetFrameWithConcreteFrameIndex(m_concrete_frame_idx)); 145314564Sdim if (frame_sp) 146314564Sdim frame_sp->ChangePC(pc); 147314564Sdim else 148314564Sdim m_thread.ClearStackFrames(); 149314564Sdim } 150314564Sdim return success; 151254721Semaste} 152254721Semaste 153314564Sdimbool RegisterContext::SetPC(Address addr) { 154314564Sdim TargetSP target_sp = m_thread.CalculateTarget(); 155314564Sdim Target *target = target_sp.get(); 156258054Semaste 157314564Sdim lldb::addr_t callAddr = addr.GetCallableLoadAddress(target); 158314564Sdim if (callAddr == LLDB_INVALID_ADDRESS) 159314564Sdim return false; 160258054Semaste 161314564Sdim return SetPC(callAddr); 162258054Semaste} 163258054Semaste 164314564Sdimuint64_t RegisterContext::GetSP(uint64_t fail_value) { 165314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 166314564Sdim LLDB_REGNUM_GENERIC_SP); 167314564Sdim return ReadRegisterAsUnsigned(reg, fail_value); 168254721Semaste} 169254721Semaste 170314564Sdimbool RegisterContext::SetSP(uint64_t sp) { 171314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 172314564Sdim LLDB_REGNUM_GENERIC_SP); 173314564Sdim return WriteRegisterFromUnsigned(reg, sp); 174254721Semaste} 175254721Semaste 176314564Sdimuint64_t RegisterContext::GetFP(uint64_t fail_value) { 177314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 178314564Sdim LLDB_REGNUM_GENERIC_FP); 179314564Sdim return ReadRegisterAsUnsigned(reg, fail_value); 180254721Semaste} 181254721Semaste 182314564Sdimbool RegisterContext::SetFP(uint64_t fp) { 183314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 184314564Sdim LLDB_REGNUM_GENERIC_FP); 185314564Sdim return WriteRegisterFromUnsigned(reg, fp); 186254721Semaste} 187254721Semaste 188314564Sdimuint64_t RegisterContext::GetReturnAddress(uint64_t fail_value) { 189314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 190314564Sdim LLDB_REGNUM_GENERIC_RA); 191314564Sdim return ReadRegisterAsUnsigned(reg, fail_value); 192254721Semaste} 193254721Semaste 194314564Sdimuint64_t RegisterContext::GetFlags(uint64_t fail_value) { 195314564Sdim uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, 196314564Sdim LLDB_REGNUM_GENERIC_FLAGS); 197314564Sdim return ReadRegisterAsUnsigned(reg, fail_value); 198254721Semaste} 199254721Semaste 200314564Sdimuint64_t RegisterContext::ReadRegisterAsUnsigned(uint32_t reg, 201314564Sdim uint64_t fail_value) { 202314564Sdim if (reg != LLDB_INVALID_REGNUM) 203314564Sdim return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg), fail_value); 204314564Sdim return fail_value; 205254721Semaste} 206254721Semaste 207314564Sdimuint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info, 208314564Sdim uint64_t fail_value) { 209314564Sdim if (reg_info) { 210314564Sdim RegisterValue value; 211314564Sdim if (ReadRegister(reg_info, value)) 212314564Sdim return value.GetAsUInt64(); 213314564Sdim } 214314564Sdim return fail_value; 215254721Semaste} 216254721Semaste 217314564Sdimbool RegisterContext::WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval) { 218314564Sdim if (reg == LLDB_INVALID_REGNUM) 219314564Sdim return false; 220314564Sdim return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg), uval); 221254721Semaste} 222254721Semaste 223314564Sdimbool RegisterContext::WriteRegisterFromUnsigned(const RegisterInfo *reg_info, 224314564Sdim uint64_t uval) { 225314564Sdim if (reg_info) { 226314564Sdim RegisterValue value; 227314564Sdim if (value.SetUInt(uval, reg_info->byte_size)) 228314564Sdim return WriteRegister(reg_info, value); 229314564Sdim } 230314564Sdim return false; 231254721Semaste} 232254721Semaste 233314564Sdimbool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) { 234314564Sdim uint32_t num_register_sets = context->GetRegisterSetCount(); 235314564Sdim // We don't know that two threads have the same register context, so require 236314564Sdim // the threads to be the same. 237314564Sdim if (context->GetThreadID() != GetThreadID()) 238314564Sdim return false; 239314564Sdim 240314564Sdim if (num_register_sets != GetRegisterSetCount()) 241314564Sdim return false; 242314564Sdim 243314564Sdim RegisterContextSP frame_zero_context = m_thread.GetRegisterContext(); 244314564Sdim 245314564Sdim for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx) { 246314564Sdim const RegisterSet *const reg_set = GetRegisterSet(set_idx); 247314564Sdim 248314564Sdim const uint32_t num_registers = reg_set->num_registers; 249314564Sdim for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) { 250314564Sdim const uint32_t reg = reg_set->registers[reg_idx]; 251314564Sdim const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); 252314564Sdim if (!reg_info || reg_info->value_regs) 253314564Sdim continue; 254314564Sdim RegisterValue reg_value; 255314564Sdim 256314564Sdim // If we can reconstruct the register from the frame we are copying from, 257341825Sdim // then do so, otherwise use the value from frame 0. 258314564Sdim if (context->ReadRegister(reg_info, reg_value)) { 259314564Sdim WriteRegister(reg_info, reg_value); 260314564Sdim } else if (frame_zero_context->ReadRegister(reg_info, reg_value)) { 261314564Sdim WriteRegister(reg_info, reg_value); 262314564Sdim } 263254721Semaste } 264314564Sdim } 265314564Sdim return true; 266254721Semaste} 267254721Semaste 268314564Sdimlldb::tid_t RegisterContext::GetThreadID() const { return m_thread.GetID(); } 269254721Semaste 270314564Sdimuint32_t RegisterContext::NumSupportedHardwareBreakpoints() { return 0; } 271254721Semaste 272314564Sdimuint32_t RegisterContext::SetHardwareBreakpoint(lldb::addr_t addr, 273314564Sdim size_t size) { 274314564Sdim return LLDB_INVALID_INDEX32; 275254721Semaste} 276254721Semaste 277314564Sdimbool RegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) { return false; } 278254721Semaste 279314564Sdimuint32_t RegisterContext::NumSupportedHardwareWatchpoints() { return 0; } 280254721Semaste 281314564Sdimuint32_t RegisterContext::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, 282314564Sdim bool read, bool write) { 283314564Sdim return LLDB_INVALID_INDEX32; 284254721Semaste} 285254721Semaste 286314564Sdimbool RegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) { 287314564Sdim return false; 288254721Semaste} 289254721Semaste 290314564Sdimbool RegisterContext::HardwareSingleStep(bool enable) { return false; } 291254721Semaste 292321369SdimStatus RegisterContext::ReadRegisterValueFromMemory( 293321369Sdim const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, 294321369Sdim RegisterValue ®_value) { 295321369Sdim Status error; 296314564Sdim if (reg_info == nullptr) { 297314564Sdim error.SetErrorString("invalid register info argument."); 298314564Sdim return error; 299314564Sdim } 300254721Semaste 301314564Sdim // Moving from addr into a register 302314564Sdim // 303314564Sdim // Case 1: src_len == dst_len 304314564Sdim // 305314564Sdim // |AABBCCDD| Address contents 306314564Sdim // |AABBCCDD| Register contents 307314564Sdim // 308314564Sdim // Case 2: src_len > dst_len 309314564Sdim // 310321369Sdim // Status! (The register should always be big enough to hold the data) 311314564Sdim // 312314564Sdim // Case 3: src_len < dst_len 313314564Sdim // 314314564Sdim // |AABB| Address contents 315314564Sdim // |AABB0000| Register contents [on little-endian hardware] 316314564Sdim // |0000AABB| Register contents [on big-endian hardware] 317314564Sdim if (src_len > RegisterValue::kMaxRegisterByteSize) { 318314564Sdim error.SetErrorString("register too small to receive memory data"); 319314564Sdim return error; 320314564Sdim } 321254721Semaste 322314564Sdim const uint32_t dst_len = reg_info->byte_size; 323314564Sdim 324314564Sdim if (src_len > dst_len) { 325314564Sdim error.SetErrorStringWithFormat( 326314564Sdim "%u bytes is too big to store in register %s (%u bytes)", src_len, 327314564Sdim reg_info->name, dst_len); 328314564Sdim return error; 329314564Sdim } 330314564Sdim 331314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 332314564Sdim if (process_sp) { 333314564Sdim uint8_t src[RegisterValue::kMaxRegisterByteSize]; 334314564Sdim 335314564Sdim // Read the memory 336314564Sdim const uint32_t bytes_read = 337314564Sdim process_sp->ReadMemory(src_addr, src, src_len, error); 338314564Sdim 339314564Sdim // Make sure the memory read succeeded... 340314564Sdim if (bytes_read != src_len) { 341314564Sdim if (error.Success()) { 342314564Sdim // This might happen if we read _some_ bytes but not all 343314564Sdim error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, 344314564Sdim src_len); 345314564Sdim } 346314564Sdim return error; 347254721Semaste } 348254721Semaste 349341825Sdim // We now have a memory buffer that contains the part or all of the 350341825Sdim // register value. Set the register value using this memory data. 351314564Sdim // TODO: we might need to add a parameter to this function in case the byte 352314564Sdim // order of the memory data doesn't match the process. For now we are 353341825Sdim // assuming they are the same. 354314564Sdim reg_value.SetFromMemoryData(reg_info, src, src_len, 355314564Sdim process_sp->GetByteOrder(), error); 356314564Sdim } else 357314564Sdim error.SetErrorString("invalid process"); 358314564Sdim 359314564Sdim return error; 360254721Semaste} 361254721Semaste 362321369SdimStatus RegisterContext::WriteRegisterValueToMemory( 363314564Sdim const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, 364314564Sdim const RegisterValue ®_value) { 365314564Sdim uint8_t dst[RegisterValue::kMaxRegisterByteSize]; 366254721Semaste 367321369Sdim Status error; 368254721Semaste 369314564Sdim ProcessSP process_sp(m_thread.GetProcess()); 370314564Sdim if (process_sp) { 371254721Semaste 372314564Sdim // TODO: we might need to add a parameter to this function in case the byte 373314564Sdim // order of the memory data doesn't match the process. For now we are 374341825Sdim // assuming they are the same. 375254721Semaste 376314564Sdim const uint32_t bytes_copied = reg_value.GetAsMemoryData( 377314564Sdim reg_info, dst, dst_len, process_sp->GetByteOrder(), error); 378254721Semaste 379314564Sdim if (error.Success()) { 380314564Sdim if (bytes_copied == 0) { 381314564Sdim error.SetErrorString("byte copy failed."); 382314564Sdim } else { 383314564Sdim const uint32_t bytes_written = 384314564Sdim process_sp->WriteMemory(dst_addr, dst, bytes_copied, error); 385314564Sdim if (bytes_written != bytes_copied) { 386314564Sdim if (error.Success()) { 387314564Sdim // This might happen if we read _some_ bytes but not all 388314564Sdim error.SetErrorStringWithFormat("only wrote %u of %u bytes", 389314564Sdim bytes_written, bytes_copied); 390314564Sdim } 391254721Semaste } 392314564Sdim } 393254721Semaste } 394314564Sdim } else 395314564Sdim error.SetErrorString("invalid process"); 396254721Semaste 397314564Sdim return error; 398254721Semaste} 399254721Semaste 400314564Sdimbool RegisterContext::ReadAllRegisterValues( 401314564Sdim lldb_private::RegisterCheckpoint ®_checkpoint) { 402314564Sdim return ReadAllRegisterValues(reg_checkpoint.GetData()); 403258884Semaste} 404258884Semaste 405314564Sdimbool RegisterContext::WriteAllRegisterValues( 406314564Sdim const lldb_private::RegisterCheckpoint ®_checkpoint) { 407314564Sdim return WriteAllRegisterValues(reg_checkpoint.GetData()); 408258884Semaste} 409258884Semaste 410314564SdimTargetSP RegisterContext::CalculateTarget() { 411314564Sdim return m_thread.CalculateTarget(); 412254721Semaste} 413254721Semaste 414314564SdimProcessSP RegisterContext::CalculateProcess() { 415314564Sdim return m_thread.CalculateProcess(); 416254721Semaste} 417254721Semaste 418314564SdimThreadSP RegisterContext::CalculateThread() { 419314564Sdim return m_thread.shared_from_this(); 420254721Semaste} 421254721Semaste 422314564SdimStackFrameSP RegisterContext::CalculateStackFrame() { 423341825Sdim // Register contexts might belong to many frames if we have inlined functions 424341825Sdim // inside a frame since all inlined functions share the same registers, so we 425341825Sdim // can't definitively say which frame we come from... 426314564Sdim return StackFrameSP(); 427254721Semaste} 428254721Semaste 429314564Sdimvoid RegisterContext::CalculateExecutionContext(ExecutionContext &exe_ctx) { 430314564Sdim m_thread.CalculateExecutionContext(exe_ctx); 431254721Semaste} 432254721Semaste 433314564Sdimbool RegisterContext::ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk, 434314564Sdim uint32_t source_regnum, 435314564Sdim lldb::RegisterKind target_rk, 436314564Sdim uint32_t &target_regnum) { 437314564Sdim const uint32_t num_registers = GetRegisterCount(); 438314564Sdim for (uint32_t reg = 0; reg < num_registers; ++reg) { 439314564Sdim const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); 440254721Semaste 441314564Sdim if (reg_info->kinds[source_rk] == source_regnum) { 442314564Sdim target_regnum = reg_info->kinds[target_rk]; 443314564Sdim return (target_regnum != LLDB_INVALID_REGNUM); 444254721Semaste } 445314564Sdim } 446314564Sdim return false; 447254721Semaste} 448