brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · cfee6e8 Raw
204 lines · cpp
1//===-- NativeRegisterContextFreeBSD_arm.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#if defined(__arm__)10 11#include "NativeRegisterContextFreeBSD_arm.h"12 13#include "lldb/Utility/DataBufferHeap.h"14#include "lldb/Utility/RegisterValue.h"15#include "lldb/Utility/Status.h"16 17#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"18#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"19 20// clang-format off21#include <sys/param.h>22#include <sys/ptrace.h>23#include <sys/types.h>24// clang-format on25 26using namespace lldb;27using namespace lldb_private;28using namespace lldb_private::process_freebsd;29 30NativeRegisterContextFreeBSD *31NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(32    const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {33  return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread);34}35 36NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(37    const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)38    : NativeRegisterContextRegisterInfo(39          native_thread, new RegisterInfoPOSIX_arm(target_arch)) {}40 41RegisterInfoPOSIX_arm &42NativeRegisterContextFreeBSD_arm::GetRegisterInfo() const {43  return static_cast<RegisterInfoPOSIX_arm &>(*m_register_info_interface_up);44}45 46uint32_t NativeRegisterContextFreeBSD_arm::GetRegisterSetCount() const {47  return GetRegisterInfo().GetRegisterSetCount();48}49 50const RegisterSet *51NativeRegisterContextFreeBSD_arm::GetRegisterSet(uint32_t set_index) const {52  return GetRegisterInfo().GetRegisterSet(set_index);53}54 55uint32_t NativeRegisterContextFreeBSD_arm::GetUserRegisterCount() const {56  uint32_t count = 0;57  for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)58    count += GetRegisterSet(set_index)->num_registers;59  return count;60}61 62Status NativeRegisterContextFreeBSD_arm::ReadRegisterSet(uint32_t set) {63  switch (set) {64  case RegisterInfoPOSIX_arm::GPRegSet:65    return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),66                                               m_reg_data.data());67  case RegisterInfoPOSIX_arm::FPRegSet:68    return NativeProcessFreeBSD::PtraceWrapper(69        PT_GETVFPREGS, m_thread.GetID(),70        m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));71  }72  llvm_unreachable("NativeRegisterContextFreeBSD_arm::ReadRegisterSet");73}74 75Status NativeRegisterContextFreeBSD_arm::WriteRegisterSet(uint32_t set) {76  switch (set) {77  case RegisterInfoPOSIX_arm::GPRegSet:78    return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),79                                               m_reg_data.data());80  case RegisterInfoPOSIX_arm::FPRegSet:81    return NativeProcessFreeBSD::PtraceWrapper(82        PT_SETVFPREGS, m_thread.GetID(),83        m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));84  }85  llvm_unreachable("NativeRegisterContextFreeBSD_arm::WriteRegisterSet");86}87 88Status89NativeRegisterContextFreeBSD_arm::ReadRegister(const RegisterInfo *reg_info,90                                               RegisterValue &reg_value) {91  Status error;92 93  if (!reg_info) {94    error = Status::FromErrorString("reg_info NULL");95    return error;96  }97 98  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];99 100  if (reg == LLDB_INVALID_REGNUM)101    return Status::FromErrorStringWithFormat(102        "no lldb regnum for %s",103        reg_info && reg_info->name ? reg_info->name : "<unknown register>");104 105  uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);106  error = ReadRegisterSet(set);107  if (error.Fail())108    return error;109 110  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());111  reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,112                     reg_info->byte_size, endian::InlHostByteOrder());113  return error;114}115 116Status NativeRegisterContextFreeBSD_arm::WriteRegister(117    const RegisterInfo *reg_info, const RegisterValue &reg_value) {118  Status error;119 120  if (!reg_info)121    return Status::FromErrorString("reg_info NULL");122 123  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];124 125  if (reg == LLDB_INVALID_REGNUM)126    return Status::FromErrorStringWithFormat(127        "no lldb regnum for %s",128        reg_info && reg_info->name ? reg_info->name : "<unknown register>");129 130  uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);131  error = ReadRegisterSet(set);132  if (error.Fail())133    return error;134 135  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());136  ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),137           reg_info->byte_size);138 139  return WriteRegisterSet(set);140}141 142Status NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues(143    lldb::WritableDataBufferSP &data_sp) {144  Status error;145 146  error = ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);147  if (error.Fail())148    return error;149 150  error = ReadRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);151  if (error.Fail())152    return error;153 154  data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));155  uint8_t *dst = data_sp->GetBytes();156  ::memcpy(dst, m_reg_data.data(), m_reg_data.size());157 158  return error;159}160 161Status NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues(162    const lldb::DataBufferSP &data_sp) {163  Status error;164 165  if (!data_sp) {166    error = Status::FromErrorStringWithFormat(167        "NativeRegisterContextFreeBSD_arm::%s invalid data_sp provided",168        __FUNCTION__);169    return error;170  }171 172  if (data_sp->GetByteSize() != m_reg_data.size()) {173    error = Status::FromErrorStringWithFormat(174        "NativeRegisterContextFreeBSD_arm::%s data_sp contained mismatched "175        "data size, expected %" PRIu64 ", actual %" PRIu64,176        __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());177    return error;178  }179 180  const uint8_t *src = data_sp->GetBytes();181  if (src == nullptr) {182    error = Status::FromErrorStringWithFormat(183        "NativeRegisterContextFreeBSD_arm::%s "184        "DataBuffer::GetBytes() returned a null "185        "pointer",186        __FUNCTION__);187    return error;188  }189  ::memcpy(m_reg_data.data(), src, m_reg_data.size());190 191  error = WriteRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);192  if (error.Fail())193    return error;194 195  return WriteRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);196}197 198llvm::Error NativeRegisterContextFreeBSD_arm::CopyHardwareWatchpointsFrom(199    NativeRegisterContextFreeBSD &source) {200  return llvm::Error::success();201}202 203#endif // defined (__arm__)204