================
@@ -0,0 +1,116 @@
+//===-- NativeRegisterContextDBReg_arm.cpp 
--------------------------------===//
+//
+// 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 "NativeRegisterContextDBReg_arm.h"
+
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+using namespace lldb_private;
+
+uint32_t NativeRegisterContextDBReg_arm::GetWatchpointSize(uint32_t wp_index) {
+  Log *log = GetLog(LLDBLog::Watchpoints);
+  LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+  switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) {
+  case 0x01:
+    return 1;
+  case 0x03:
+    return 2;
+  case 0x07:
+    return 3;
+  case 0x0f:
+    return 4;
+  default:
+    return 0;
+  }
+}
+
+std::optional<NativeRegisterContextDBReg::BreakpointDetails>
+NativeRegisterContextDBReg_arm::AdjustBreakpoint(
+    const BreakpointDetails &details) {
+  BreakpointDetails bd = details;
+  // Use size to get a hint of arm vs thumb modes.
+  switch (bd.size) {
+  case 2:
+    bd.addr &= ~1;
+    break;
+  case 4:
+    bd.addr &= ~3;
+    break;
+  default:
+    return {};
+  }
+
+  return bd;
+}
+
+std::optional<NativeRegisterContextDBReg::WatchpointDetails>
+NativeRegisterContextDBReg_arm::AdjustWatchpoint(
+    const WatchpointDetails &details) {
+  auto [size, addr] = details;
+
+  if (size == 0 || size > 4)
+    return {};
+
+  // Check 4-byte alignment for hardware watchpoint target address. Below is a
+  // hack to recalculate address and size in order to make sure we can watch
+  // non 4-byte aligned addresses as well.
+  if (addr & 0x03) {
+    uint8_t watch_mask = (addr & 0x03) + size;
+    if (watch_mask > 0x04)
+      return {};
+    else if (watch_mask <= 0x02)
+      size = 2;
+    else
+      size = 4;
+
+    addr = addr & (~0x03);
+  }
+
+  return WatchpointDetails{size, addr};
+}
+
+uint32_t NativeRegisterContextDBReg_arm::MakeBreakControlValue(size_t size) {
+  switch (size) {
+  case 2:
+    return (0x3 << 5) | 7;
+  case 4:
+    return (0xfu << 5) | 7;
+  default:
+    // We assume that AdjustBreakpoint would have caught this earlier.
+    llvm_unreachable("Invalid breakpoint size.");
+  }
+}
+
+uint32_t NativeRegisterContextDBReg_arm::MakeWatchControlValue(
+    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+  uint32_t addr_word_offset = 0, byte_mask = 0;
+
+  // We can only watch up to four bytes that follow a 4 byte aligned address
+  // per watchpoint register pair, so make sure we can properly encode this.
+  addr_word_offset = addr % 4;
----------------
b10902118 wrote:

This is actually unneeded. `addr_word_offset` will always be 0 because there is 
`addr = addr & (~0x03);` in `NativeRegisterContextDBReg_arm::AdjustWatchpoint`. 
Previous `NativeRegisterContextLinux_arm::SetHardwareWatchpoint` made this 
redundancy, which is clearer there.

https://github.com/llvm/llvm-project/pull/152284
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to