[Lldb-commits] [lldb] [lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (PR #152284)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 7 09:10:58 PDT 2025
================
@@ -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
More information about the lldb-commits
mailing list