LLDB mainline
NativeRegisterContextDBReg_arm.cpp
Go to the documentation of this file.
1//===-- NativeRegisterContextDBReg_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-exception
6//
7//===----------------------------------------------------------------------===//
8
10
12#include "lldb/Utility/Log.h"
14
15using namespace lldb_private;
16
19 LLDB_LOG(log, "wp_index: {0}", wp_index);
20
21 switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) {
22 case 0x01:
23 return 1;
24 case 0x03:
25 return 2;
26 case 0x07:
27 return 3;
28 case 0x0f:
29 return 4;
30 default:
31 return 0;
32 }
33}
34
35std::optional<NativeRegisterContextDBReg::WatchpointDetails>
37 const WatchpointDetails &details) {
38 auto [size, addr] = details;
39
40 if (size == 0 || size > 4)
41 return {};
42
43 // Check 4-byte alignment for hardware watchpoint target address. Below is a
44 // hack to recalculate address and size in order to make sure we can watch
45 // non 4-byte aligned addresses as well.
46 if (addr & 0x03) {
47 uint8_t watch_mask = (addr & 0x03) + size;
48 if (watch_mask > 0x04)
49 return {};
50 else if (watch_mask <= 0x02)
51 size = 2;
52 else
53 size = 4;
54
55 addr = addr & (~0x03);
56 }
57
58 return WatchpointDetails{size, addr};
59}
60
63 const BreakpointDetails &details) {
64 BreakpointDetails bd = details;
65 // Use size to get a hint of arm vs thumb modes.
66 // LLDB usually aligns this client side, but other clients may not.
67 switch (bd.size) {
68 case 2:
69 bd.addr &= ~1;
70 break;
71 case 4:
72 bd.addr &= ~3;
73 break;
74 default:
75 // We assume that ValidateBreakpoint would have caught this earlier.
76 llvm_unreachable("Invalid breakpoint size!");
77 }
78
79 return bd;
80}
81
83 switch (size) {
84 case 2:
85 return (0x3 << 5) | 7;
86 case 4:
87 return (0xfu << 5) | 7;
88 default:
89 // ValidateBreakpoint would have rejected this earlier.
90 llvm_unreachable("Invalid breakpoint size.");
91 }
92}
93
94uint32_t
96 uint32_t watch_flags) {
97 // We can only watch up to four bytes that follow a 4 byte aligned address
98 // per watchpoint register pair, so make sure we can properly encode this.
99 // We assume that the address was 4 byte aligned by AdjustWatchpoint.
100 uint32_t byte_mask = (1u << size) - 1u;
101
102 // Check if we need multiple watchpoint register
103 if (byte_mask > 0xfu)
105
106 // Setup control value
107 // Make the byte_mask into a valid Byte Address Select mask
108 uint32_t control_value = byte_mask << 5;
109
110 // Turn on appropriate watchpoint flags read or write
111 control_value |= (watch_flags << 3);
112
113 // Enable this watchpoint and make it stop in privileged or user mode;
114 control_value |= 7;
115
116 return control_value;
117}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
BreakpointDetails AdjustBreakpoint(const BreakpointDetails &details) override
uint32_t MakeWatchControlValue(size_t size, uint32_t watch_flags) override
std::optional< WatchpointDetails > AdjustWatchpoint(const WatchpointDetails &details) override
#define LLDB_INVALID_INDEX32
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332