brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.6 KiB · c4f9c92 Raw
468 lines · cpp
1//===-- RegisterContext.cpp -----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Target/RegisterContext.h"10#include "lldb/Core/Module.h"11#include "lldb/Core/Value.h"12#include "lldb/Expression/DWARFExpression.h"13#include "lldb/Target/ExecutionContext.h"14#include "lldb/Target/Process.h"15#include "lldb/Target/StackFrame.h"16#include "lldb/Target/Target.h"17#include "lldb/Target/Thread.h"18#include "lldb/Utility/DataExtractor.h"19#include "lldb/Utility/Endian.h"20#include "lldb/Utility/RegisterValue.h"21#include "lldb/Utility/Scalar.h"22 23using namespace lldb;24using namespace lldb_private;25 26RegisterContext::RegisterContext(Thread &thread, uint32_t concrete_frame_idx)27    : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx),28      m_stop_id(thread.GetProcess()->GetStopID()) {}29 30RegisterContext::~RegisterContext() = default;31 32void RegisterContext::InvalidateIfNeeded(bool force) {33  ProcessSP process_sp(m_thread.GetProcess());34  bool invalidate = force;35  uint32_t process_stop_id = UINT32_MAX;36 37  if (process_sp)38    process_stop_id = process_sp->GetStopID();39  else40    invalidate = true;41 42  if (!invalidate)43    invalidate = process_stop_id != GetStopID();44 45  if (invalidate) {46    InvalidateAllRegisters();47    SetStopID(process_stop_id);48  }49}50 51const RegisterInfo *52RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name,53                                       uint32_t start_idx) {54  if (reg_name.empty())55    return nullptr;56 57  // Generic register names take precedence over specific register names.58  // For example, on x86 we want "sp" to refer to the complete RSP/ESP register59  // rather than the 16-bit SP pseudo-register.60  uint32_t generic_reg = Args::StringToGenericRegister(reg_name);61  if (generic_reg != LLDB_INVALID_REGNUM) {62    const RegisterInfo *reg_info =63        GetRegisterInfo(eRegisterKindGeneric, generic_reg);64    if (reg_info)65      return reg_info;66  }67 68  const uint32_t num_registers = GetRegisterCount();69  for (uint32_t reg = start_idx; reg < num_registers; ++reg) {70    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);71 72    if (reg_name.equals_insensitive(reg_info->name) ||73        reg_name.equals_insensitive(reg_info->alt_name))74      return reg_info;75  }76 77  return nullptr;78}79 80const RegisterInfo *RegisterContext::GetRegisterInfo(lldb::RegisterKind kind,81                                                     uint32_t num) {82  const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);83  if (reg_num == LLDB_INVALID_REGNUM)84    return nullptr;85  return GetRegisterInfoAtIndex(reg_num);86}87 88const char *RegisterContext::GetRegisterName(uint32_t reg) {89  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);90  if (reg_info)91    return reg_info->name;92  return nullptr;93}94 95uint64_t RegisterContext::GetPC(uint64_t fail_value) {96  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,97                                                     LLDB_REGNUM_GENERIC_PC);98  uint64_t pc = ReadRegisterAsUnsigned(reg, fail_value);99 100  if (pc != fail_value) {101    TargetSP target_sp = m_thread.CalculateTarget();102    if (target_sp) {103      Target *target = target_sp.get();104      if (target)105        pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode);106    }107  }108 109  return pc;110}111 112uint64_t RegisterContext::GetThreadPointer(uint64_t fail_value) {113  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,114                                                     LLDB_REGNUM_GENERIC_TP);115  return ReadRegisterAsUnsigned(reg, fail_value);116}117 118bool RegisterContext::SetPC(uint64_t pc) {119  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,120                                                     LLDB_REGNUM_GENERIC_PC);121  bool success = WriteRegisterFromUnsigned(reg, pc);122  if (success) {123    StackFrameSP frame_sp(124        m_thread.GetFrameWithConcreteFrameIndex(m_concrete_frame_idx));125    if (frame_sp)126      frame_sp->ChangePC(pc);127    else128      m_thread.ClearStackFrames();129  }130  return success;131}132 133bool RegisterContext::GetPCForSymbolication(Address &address) {134  addr_t pc = GetPC(LLDB_INVALID_ADDRESS);135  if (pc == LLDB_INVALID_ADDRESS)136    return false;137  TargetSP target_sp = m_thread.CalculateTarget();138  if (!target_sp.get())139    return false;140 141  if (!BehavesLikeZerothFrame() && pc != 0)142    pc--;143  address.SetLoadAddress(pc, target_sp.get());144  return true;145}146 147bool RegisterContext::SetPC(Address addr) {148  TargetSP target_sp = m_thread.CalculateTarget();149  Target *target = target_sp.get();150 151  lldb::addr_t callAddr = addr.GetCallableLoadAddress(target);152  if (callAddr == LLDB_INVALID_ADDRESS)153    return false;154 155  return SetPC(callAddr);156}157 158uint64_t RegisterContext::GetSP(uint64_t fail_value) {159  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,160                                                     LLDB_REGNUM_GENERIC_SP);161  return ReadRegisterAsUnsigned(reg, fail_value);162}163 164bool RegisterContext::SetSP(uint64_t sp) {165  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,166                                                     LLDB_REGNUM_GENERIC_SP);167  return WriteRegisterFromUnsigned(reg, sp);168}169 170uint64_t RegisterContext::GetFP(uint64_t fail_value) {171  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,172                                                     LLDB_REGNUM_GENERIC_FP);173  return ReadRegisterAsUnsigned(reg, fail_value);174}175 176bool RegisterContext::SetFP(uint64_t fp) {177  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,178                                                     LLDB_REGNUM_GENERIC_FP);179  return WriteRegisterFromUnsigned(reg, fp);180}181 182uint64_t RegisterContext::GetReturnAddress(uint64_t fail_value) {183  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,184                                                     LLDB_REGNUM_GENERIC_RA);185  return ReadRegisterAsUnsigned(reg, fail_value);186}187 188uint64_t RegisterContext::GetFlags(uint64_t fail_value) {189  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,190                                                     LLDB_REGNUM_GENERIC_FLAGS);191  return ReadRegisterAsUnsigned(reg, fail_value);192}193 194uint64_t RegisterContext::ReadRegisterAsUnsigned(uint32_t reg,195                                                 uint64_t fail_value) {196  if (reg != LLDB_INVALID_REGNUM)197    return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg), fail_value);198  return fail_value;199}200 201uint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,202                                                 uint64_t fail_value) {203  if (reg_info) {204    RegisterValue value;205    if (ReadRegister(reg_info, value))206      return value.GetAsUInt64();207  }208  return fail_value;209}210 211bool RegisterContext::WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval) {212  if (reg == LLDB_INVALID_REGNUM)213    return false;214  return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg), uval);215}216 217bool RegisterContext::WriteRegisterFromUnsigned(const RegisterInfo *reg_info,218                                                uint64_t uval) {219  if (reg_info) {220    RegisterValue value;221    if (value.SetUInt(uval, reg_info->byte_size))222      return WriteRegister(reg_info, value);223  }224  return false;225}226 227bool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) {228  uint32_t num_register_sets = context->GetRegisterSetCount();229  // We don't know that two threads have the same register context, so require230  // the threads to be the same.231  if (context->GetThreadID() != GetThreadID())232    return false;233 234  if (num_register_sets != GetRegisterSetCount())235    return false;236 237  RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();238 239  for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx) {240    const RegisterSet *const reg_set = GetRegisterSet(set_idx);241 242    const uint32_t num_registers = reg_set->num_registers;243    for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) {244      const uint32_t reg = reg_set->registers[reg_idx];245      const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);246      if (!reg_info || reg_info->value_regs)247        continue;248      RegisterValue reg_value;249 250      // If we can reconstruct the register from the frame we are copying from,251      // then do so, otherwise use the value from frame 0.252      if (context->ReadRegister(reg_info, reg_value)) {253        WriteRegister(reg_info, reg_value);254      } else if (frame_zero_context->ReadRegister(reg_info, reg_value)) {255        WriteRegister(reg_info, reg_value);256      }257    }258  }259  return true;260}261 262lldb::tid_t RegisterContext::GetThreadID() const { return m_thread.GetID(); }263 264uint32_t RegisterContext::NumSupportedHardwareBreakpoints() { return 0; }265 266uint32_t RegisterContext::SetHardwareBreakpoint(lldb::addr_t addr,267                                                size_t size) {268  return LLDB_INVALID_INDEX32;269}270 271// Used when parsing DWARF and EH frame information and any other object file272// sections that contain register numbers in them.273uint32_t274RegisterContext::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,275                                                     uint32_t num) {276  const uint32_t num_regs = GetRegisterCount();277 278  assert(kind < kNumRegisterKinds);279  for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {280    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);281 282    if (reg_info->kinds[kind] == num)283      return reg_idx;284  }285 286  return LLDB_INVALID_REGNUM;287}288 289bool RegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) { return false; }290 291uint32_t RegisterContext::NumSupportedHardwareWatchpoints() { return 0; }292 293uint32_t RegisterContext::SetHardwareWatchpoint(lldb::addr_t addr, size_t size,294                                                bool read, bool write) {295  return LLDB_INVALID_INDEX32;296}297 298bool RegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) {299  return false;300}301 302bool RegisterContext::HardwareSingleStep(bool enable) { return false; }303 304Status RegisterContext::ReadRegisterValueFromMemory(305    const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len,306    RegisterValue &reg_value) {307  Status error;308  if (!reg_info)309    return Status::FromErrorString("invalid register info argument.");310 311  // Moving from addr into a register312  //313  // Case 1: src_len == dst_len314  //315  //   |AABBCCDD| Address contents316  //   |AABBCCDD| Register contents317  //318  // Case 2: src_len > dst_len319  //320  //   Status!  (The register should always be big enough to hold the data)321  //322  // Case 3: src_len < dst_len323  //324  //   |AABB| Address contents325  //   |AABB0000| Register contents [on little-endian hardware]326  //   |0000AABB| Register contents [on big-endian hardware]327  const uint32_t dst_len = reg_info->byte_size;328 329  if (src_len > dst_len) {330    return Status::FromErrorStringWithFormat(331        "%u bytes is too big to store in register %s (%u bytes)", src_len,332        reg_info->name, dst_len);333    return error;334  }335 336  ProcessSP process_sp(m_thread.GetProcess());337  if (process_sp) {338    RegisterValue::BytesContainer src(src_len);339 340    // Read the memory341    const uint32_t bytes_read =342        process_sp->ReadMemory(src_addr, src.data(), src_len, error);343 344    // Make sure the memory read succeeded...345    if (bytes_read != src_len) {346      if (error.Success()) {347        // This might happen if we read _some_ bytes but not all348        return Status::FromErrorStringWithFormat("read %u of %u bytes",349                                                 bytes_read, src_len);350      }351      return error;352    }353 354    // We now have a memory buffer that contains the part or all of the355    // register value. Set the register value using this memory data.356    // TODO: we might need to add a parameter to this function in case the byte357    // order of the memory data doesn't match the process. For now we are358    // assuming they are the same.359    reg_value.SetFromMemoryData(*reg_info, src.data(), src_len,360                                process_sp->GetByteOrder(), error);361  } else362    return Status::FromErrorString("invalid process");363 364  return error;365}366 367Status RegisterContext::WriteRegisterValueToMemory(368    const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len,369    const RegisterValue &reg_value) {370  Status error;371  ProcessSP process_sp(m_thread.GetProcess());372 373  if (!process_sp) {374    return Status::FromErrorString("invalid process");375    return error;376  }377 378  if (reg_info == nullptr) {379    return Status::FromErrorString("Invalid register info argument.");380    return error;381  }382 383  // TODO: we might need to add a parameter to this function in case the byte384  // order of the memory data doesn't match the process. For now we are385  // assuming they are the same.386  RegisterValue::BytesContainer dst(dst_len);387  const uint32_t bytes_copied = reg_value.GetAsMemoryData(388      *reg_info, dst.data(), dst_len, process_sp->GetByteOrder(), error);389 390  if (error.Success()) {391    if (bytes_copied == 0) {392      return Status::FromErrorString("byte copy failed.");393    } else {394      const uint32_t bytes_written =395          process_sp->WriteMemory(dst_addr, dst.data(), bytes_copied, error);396      if (bytes_written != bytes_copied) {397        if (error.Success()) {398          // This might happen if we read _some_ bytes but not all399          return Status::FromErrorStringWithFormat("only wrote %u of %u bytes",400                                                   bytes_written, bytes_copied);401        }402      }403    }404  }405 406  return error;407}408 409lldb::ByteOrder RegisterContext::GetByteOrder() {410  // Get the target process whose privileged thread was used for the register411  // read.412  lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;413  lldb_private::Process *process = CalculateProcess().get();414 415  if (process)416    byte_order = process->GetByteOrder();417  return byte_order;418}419 420bool RegisterContext::ReadAllRegisterValues(421    lldb_private::RegisterCheckpoint &reg_checkpoint) {422  return ReadAllRegisterValues(reg_checkpoint.GetData());423}424 425bool RegisterContext::WriteAllRegisterValues(426    const lldb_private::RegisterCheckpoint &reg_checkpoint) {427  return WriteAllRegisterValues(reg_checkpoint.GetData());428}429 430TargetSP RegisterContext::CalculateTarget() {431  return m_thread.CalculateTarget();432}433 434ProcessSP RegisterContext::CalculateProcess() {435  return m_thread.CalculateProcess();436}437 438ThreadSP RegisterContext::CalculateThread() {439  return m_thread.shared_from_this();440}441 442StackFrameSP RegisterContext::CalculateStackFrame() {443  // Register contexts might belong to many frames if we have inlined functions444  // inside a frame since all inlined functions share the same registers, so we445  // can't definitively say which frame we come from...446  return StackFrameSP();447}448 449void RegisterContext::CalculateExecutionContext(ExecutionContext &exe_ctx) {450  m_thread.CalculateExecutionContext(exe_ctx);451}452 453bool RegisterContext::ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,454                                                  uint32_t source_regnum,455                                                  lldb::RegisterKind target_rk,456                                                  uint32_t &target_regnum) {457  const uint32_t num_registers = GetRegisterCount();458  for (uint32_t reg = 0; reg < num_registers; ++reg) {459    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);460 461    if (reg_info->kinds[source_rk] == source_regnum) {462      target_regnum = reg_info->kinds[target_rk];463      return (target_regnum != LLDB_INVALID_REGNUM);464    }465  }466  return false;467}468