brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · f2f772a Raw
97 lines · cpp
1//===-- NativeRegisterContextDBReg_arm64.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 "NativeRegisterContextDBReg_arm64.h"10 11#include "lldb/Utility/LLDBLog.h"12#include "lldb/Utility/Log.h"13#include "lldb/Utility/RegisterValue.h"14 15using namespace lldb_private;16 17uint32_t18NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) {19  Log *log = GetLog(LLDBLog::Watchpoints);20  LLDB_LOG(log, "wp_index: {0}", wp_index);21 22  switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {23  case 0x01:24    return 1;25  case 0x03:26    return 2;27  case 0x0f:28    return 4;29  case 0xff:30    return 8;31  default:32    return 0;33  }34}35 36std::optional<NativeRegisterContextDBReg::WatchpointDetails>37NativeRegisterContextDBReg_arm64::AdjustWatchpoint(38    const WatchpointDetails &details) {39  size_t size = details.size;40  lldb::addr_t addr = details.addr;41  // Check if size has a valid hardware watchpoint length.42  if (size != 1 && size != 2 && size != 4 && size != 8)43    return std::nullopt;44 45  // Check 8-byte alignment for hardware watchpoint target address. Below is a46  // hack to recalculate address and size in order to make sure we can watch47  // non 8-byte aligned addresses as well.48  if (addr & 0x07) {49    uint8_t watch_mask = (addr & 0x07) + size;50 51    if (watch_mask > 0x08)52      return std::nullopt;53 54    if (watch_mask <= 0x02)55      size = 2;56    else if (watch_mask <= 0x04)57      size = 4;58    else59      size = 8;60 61    addr = addr & (~0x07);62  }63  return WatchpointDetails{size, addr};64}65 66uint32_t NativeRegisterContextDBReg_arm64::MakeBreakControlValue(size_t size) {67  // PAC (bits 2:1): 0b1068  const uint32_t pac_bits = 2 << 1;69 70  // BAS (bits 12:5) hold a bit-mask of addresses to watch71  // e.g. 0b00000001 means 1 byte at address72  //      0b00000011 means 2 bytes (addr..addr+1)73  //      ...74  //      0b11111111 means 8 bytes (addr..addr+7)75  size_t encoded_size = ((1 << size) - 1) << 5;76 77  // Return encoded hardware breakpoint control value.78  return m_hw_dbg_enable_bit | pac_bits | encoded_size;79}80 81uint32_t82NativeRegisterContextDBReg_arm64::MakeWatchControlValue(size_t size,83                                                        uint32_t watch_flags) {84  // PAC (bits 2:1): 0b1085  const uint32_t pac_bits = 2 << 1;86 87  // BAS (bits 12:5) hold a bit-mask of addresses to watch88  // e.g. 0b00000001 means 1 byte at address89  //      0b00000011 means 2 bytes (addr..addr+1)90  //      ...91  //      0b11111111 means 8 bytes (addr..addr+7)92  size_t encoded_size = ((1 << size) - 1) << 5;93 94  // Return encoded hardware watchpoint control value.95  return m_hw_dbg_enable_bit | pac_bits | encoded_size | (watch_flags << 3);96}97