diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp')
-rw-r--r-- | gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp new file mode 100644 index 00000000000..946d4fa9f8e --- /dev/null +++ b/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -0,0 +1,139 @@ +//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextMemory.h" + +#include "DynamicRegisterInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +using namespace lldb; +using namespace lldb_private; + +// RegisterContextMemory constructor +RegisterContextMemory::RegisterContextMemory(Thread &thread, + uint32_t concrete_frame_idx, + DynamicRegisterInfo ®_infos, + addr_t reg_data_addr) + : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos), + m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) { + // Resize our vector of bools to contain one bool for every register. We will + // use these boolean values to know when a register value is valid in + // m_reg_data. + const size_t num_regs = reg_infos.GetNumRegisters(); + assert(num_regs > 0); + m_reg_valid.resize(num_regs); + + // Make a heap based buffer that is big enough to store all registers + DataBufferSP reg_data_sp( + new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0)); + m_reg_data.SetData(reg_data_sp); +} + +// Destructor +RegisterContextMemory::~RegisterContextMemory() {} + +void RegisterContextMemory::InvalidateAllRegisters() { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) + SetAllRegisterValid(false); +} + +void RegisterContextMemory::SetAllRegisterValid(bool b) { + std::vector<bool>::iterator pos, end = m_reg_valid.end(); + for (pos = m_reg_valid.begin(); pos != end; ++pos) + *pos = b; +} + +size_t RegisterContextMemory::GetRegisterCount() { + return m_reg_infos.GetNumRegisters(); +} + +const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) { + return m_reg_infos.GetRegisterInfoAtIndex(reg); +} + +size_t RegisterContextMemory::GetRegisterSetCount() { + return m_reg_infos.GetNumRegisterSets(); +} + +const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) { + return m_reg_infos.GetRegisterSet(reg_set); +} + +uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num); +} + +bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; + if (!m_reg_valid[reg_num]) { + if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer())) + return false; + } + const bool partial_data_ok = false; + return reg_value + .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, + partial_data_ok) + .Success(); +} + +bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { + const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; + addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset; + Status error(WriteRegisterValueToMemory(reg_info, reg_addr, + reg_info->byte_size, reg_value)); + m_reg_valid[reg_num] = false; + return error.Success(); + } + return false; +} + +bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + Status error; + if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), + data_sp->GetByteSize(), + error) == data_sp->GetByteSize()) { + SetAllRegisterValid(true); + return true; + } + } + } + return false; +} + +bool RegisterContextMemory::WriteAllRegisterValues( + const DataBufferSP &data_sp) { + if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + Status error; + SetAllRegisterValid(false); + if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), + data_sp->GetByteSize(), + error) == data_sp->GetByteSize()) + return true; + } + } + return false; +} + +void RegisterContextMemory::SetAllRegisterData( + const lldb::DataBufferSP &data_sp) { + m_reg_data.SetData(data_sp); + SetAllRegisterValid(true); +} |