brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · b557787 Raw
231 lines · cpp
1//===-- RegisterContextThreadMemory.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/OperatingSystem.h"10#include "lldb/Target/Process.h"11#include "lldb/Target/Thread.h"12#include "lldb/Utility/Status.h"13#include "lldb/lldb-private.h"14 15#include "RegisterContextThreadMemory.h"16 17using namespace lldb;18using namespace lldb_private;19 20RegisterContextThreadMemory::RegisterContextThreadMemory(21    Thread &thread, lldb::addr_t register_data_addr)22    : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),23      m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}24 25RegisterContextThreadMemory::~RegisterContextThreadMemory() = default;26 27void RegisterContextThreadMemory::UpdateRegisterContext() {28  std::lock_guard<std::mutex> lock(m_update_register_ctx_lock);29 30  ThreadSP thread_sp(m_thread_wp.lock());31  if (thread_sp) {32    ProcessSP process_sp(thread_sp->GetProcess());33 34    if (process_sp) {35      const uint32_t stop_id = process_sp->GetModID().GetStopID();36      if (m_stop_id != stop_id) {37        m_stop_id = stop_id;38        m_reg_ctx_sp.reset();39      }40      if (!m_reg_ctx_sp) {41        ThreadSP backing_thread_sp(thread_sp->GetBackingThread());42        if (backing_thread_sp) {43          m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();44        } else {45          OperatingSystem *os = process_sp->GetOperatingSystem();46          if (os->IsOperatingSystemPluginThread(thread_sp))47            m_reg_ctx_sp = os->CreateRegisterContextForThread(48                thread_sp.get(), m_register_data_addr);49        }50      }51    } else {52      m_reg_ctx_sp.reset();53    }54  } else {55    m_reg_ctx_sp.reset();56  }57}58 59// Subclasses must override these functions60void RegisterContextThreadMemory::InvalidateAllRegisters() {61  UpdateRegisterContext();62  if (m_reg_ctx_sp)63    m_reg_ctx_sp->InvalidateAllRegisters();64}65 66size_t RegisterContextThreadMemory::GetRegisterCount() {67  UpdateRegisterContext();68  if (m_reg_ctx_sp)69    return m_reg_ctx_sp->GetRegisterCount();70  return 0;71}72 73const RegisterInfo *74RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) {75  UpdateRegisterContext();76  if (m_reg_ctx_sp)77    return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);78  return nullptr;79}80 81size_t RegisterContextThreadMemory::GetRegisterSetCount() {82  UpdateRegisterContext();83  if (m_reg_ctx_sp)84    return m_reg_ctx_sp->GetRegisterSetCount();85  return 0;86}87 88const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) {89  UpdateRegisterContext();90  if (m_reg_ctx_sp)91    return m_reg_ctx_sp->GetRegisterSet(reg_set);92  return nullptr;93}94 95bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info,96                                               RegisterValue &reg_value) {97  UpdateRegisterContext();98  if (m_reg_ctx_sp)99    return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);100  return false;101}102 103bool RegisterContextThreadMemory::WriteRegister(104    const RegisterInfo *reg_info, const RegisterValue &reg_value) {105  UpdateRegisterContext();106  if (m_reg_ctx_sp)107    return m_reg_ctx_sp->WriteRegister(reg_info, reg_value);108  return false;109}110 111bool RegisterContextThreadMemory::ReadAllRegisterValues(112    lldb::WritableDataBufferSP &data_sp) {113  UpdateRegisterContext();114  if (m_reg_ctx_sp)115    return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);116  return false;117}118 119bool RegisterContextThreadMemory::ReadAllRegisterValues(120    lldb_private::RegisterCheckpoint &reg_checkpoint) {121  UpdateRegisterContext();122  if (m_reg_ctx_sp)123    return m_reg_ctx_sp->ReadAllRegisterValues(reg_checkpoint);124  return false;125}126 127bool RegisterContextThreadMemory::WriteAllRegisterValues(128    const lldb::DataBufferSP &data_sp) {129  UpdateRegisterContext();130  if (m_reg_ctx_sp)131    return m_reg_ctx_sp->WriteAllRegisterValues(data_sp);132  return false;133}134 135bool RegisterContextThreadMemory::WriteAllRegisterValues(136    const lldb_private::RegisterCheckpoint &reg_checkpoint) {137  UpdateRegisterContext();138  if (m_reg_ctx_sp)139    return m_reg_ctx_sp->WriteAllRegisterValues(reg_checkpoint);140  return false;141}142 143bool RegisterContextThreadMemory::CopyFromRegisterContext(144    lldb::RegisterContextSP reg_ctx_sp) {145  UpdateRegisterContext();146  if (m_reg_ctx_sp)147    return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);148  return false;149}150 151uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber(152    lldb::RegisterKind kind, uint32_t num) {153  UpdateRegisterContext();154  if (m_reg_ctx_sp)155    return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);156  return LLDB_INVALID_REGNUM;157}158 159uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() {160  UpdateRegisterContext();161  if (m_reg_ctx_sp)162    return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();163  return 0;164}165 166uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr,167                                                            size_t size) {168  UpdateRegisterContext();169  if (m_reg_ctx_sp)170    return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);171  return 0;172}173 174bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) {175  UpdateRegisterContext();176  if (m_reg_ctx_sp)177    return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx);178  return false;179}180 181uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() {182  UpdateRegisterContext();183  if (m_reg_ctx_sp)184    return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();185  return 0;186}187 188uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr,189                                                            size_t size,190                                                            bool read,191                                                            bool write) {192  UpdateRegisterContext();193  if (m_reg_ctx_sp)194    return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);195  return 0;196}197 198bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) {199  UpdateRegisterContext();200  if (m_reg_ctx_sp)201    return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);202  return false;203}204 205bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) {206  UpdateRegisterContext();207  if (m_reg_ctx_sp)208    return m_reg_ctx_sp->HardwareSingleStep(enable);209  return false;210}211 212Status RegisterContextThreadMemory::ReadRegisterValueFromMemory(213    const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr,214    uint32_t src_len, RegisterValue &reg_value) {215  UpdateRegisterContext();216  if (m_reg_ctx_sp)217    return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr,218                                                     src_len, reg_value);219  return Status::FromErrorString("invalid register context");220}221 222Status RegisterContextThreadMemory::WriteRegisterValueToMemory(223    const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr,224    uint32_t dst_len, const RegisterValue &reg_value) {225  UpdateRegisterContext();226  if (m_reg_ctx_sp)227    return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len,228                                                    reg_value);229  return Status::FromErrorString("invalid register context");230}231