brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 84a19d5 Raw
140 lines · cpp
1//===-- RegisterContextMemory.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 "RegisterContextMemory.h"10 11#include "lldb/Target/Process.h"12#include "lldb/Target/Thread.h"13#include "lldb/Utility/DataBufferHeap.h"14#include "lldb/Utility/RegisterValue.h"15#include "lldb/Utility/Status.h"16 17using namespace lldb;18using namespace lldb_private;19 20// RegisterContextMemory constructor21RegisterContextMemory::RegisterContextMemory(Thread &thread,22                                             uint32_t concrete_frame_idx,23                                             DynamicRegisterInfo &reg_infos,24                                             addr_t reg_data_addr)25    : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos),26      m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) {27  // Resize our vector of bools to contain one bool for every register. We will28  // use these boolean values to know when a register value is valid in29  // m_reg_data.30  const size_t num_regs = reg_infos.GetNumRegisters();31  assert(num_regs > 0);32  m_reg_valid.resize(num_regs);33 34  // Make a heap based buffer that is big enough to store all registers35  m_data =36      std::make_shared<DataBufferHeap>(reg_infos.GetRegisterDataByteSize(), 0);37  m_reg_data.SetData(m_data);38}39 40// Destructor41RegisterContextMemory::~RegisterContextMemory() = default;42 43void RegisterContextMemory::InvalidateAllRegisters() {44  if (m_reg_data_addr != LLDB_INVALID_ADDRESS)45    SetAllRegisterValid(false);46}47 48void RegisterContextMemory::SetAllRegisterValid(bool b) {49  std::vector<bool>::iterator pos, end = m_reg_valid.end();50  for (pos = m_reg_valid.begin(); pos != end; ++pos)51    *pos = b;52}53 54size_t RegisterContextMemory::GetRegisterCount() {55  return m_reg_infos.GetNumRegisters();56}57 58const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) {59  return m_reg_infos.GetRegisterInfoAtIndex(reg);60}61 62size_t RegisterContextMemory::GetRegisterSetCount() {63  return m_reg_infos.GetNumRegisterSets();64}65 66const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) {67  return m_reg_infos.GetRegisterSet(reg_set);68}69 70uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber(71    lldb::RegisterKind kind, uint32_t num) {72  return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num);73}74 75bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info,76                                         RegisterValue &reg_value) {77  const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];78  if (!m_reg_valid[reg_num]) {79    if (!ReadAllRegisterValues(m_data))80      return false;81  }82  const bool partial_data_ok = false;83  return reg_value84      .SetValueFromData(*reg_info, m_reg_data, reg_info->byte_offset,85                        partial_data_ok)86      .Success();87}88 89bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info,90                                          const RegisterValue &reg_value) {91  if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {92    const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];93    addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;94    Status error(WriteRegisterValueToMemory(reg_info, reg_addr,95                                            reg_info->byte_size, reg_value));96    m_reg_valid[reg_num] = false;97    return error.Success();98  }99  return false;100}101 102bool RegisterContextMemory::ReadAllRegisterValues(103    WritableDataBufferSP &data_sp) {104  if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {105    ProcessSP process_sp(CalculateProcess());106    if (process_sp) {107      Status error;108      if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(),109                                 data_sp->GetByteSize(),110                                 error) == data_sp->GetByteSize()) {111        SetAllRegisterValid(true);112        return true;113      }114    }115  }116  return false;117}118 119bool RegisterContextMemory::WriteAllRegisterValues(120    const DataBufferSP &data_sp) {121  if (m_reg_data_addr != LLDB_INVALID_ADDRESS) {122    ProcessSP process_sp(CalculateProcess());123    if (process_sp) {124      Status error;125      SetAllRegisterValid(false);126      if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(),127                                  data_sp->GetByteSize(),128                                  error) == data_sp->GetByteSize())129        return true;130    }131  }132  return false;133}134 135void RegisterContextMemory::SetAllRegisterData(136    const lldb::DataBufferSP &data_sp) {137  m_reg_data.SetData(data_sp);138  SetAllRegisterValid(true);139}140