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