LLDB mainline
NativeRegisterContextDBReg_arm64.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
10
12#include "lldb/Utility/Log.h"
14
15#include "llvm/Support/MathExtras.h"
16
17using namespace lldb_private;
18
19uint32_t
22 LLDB_LOG(log, "wp_index: {0}", wp_index);
23
24 switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
25 case 0x01:
26 return 1;
27 case 0x03:
28 return 2;
29 case 0x0f:
30 return 4;
31 case 0xff:
32 return 8;
33 default:
34 return 0;
35 }
36}
37
38std::optional<NativeRegisterContextDBReg::WatchpointDetails>
40 const WatchpointDetails &details) {
41 // For the way we are using BAS watchpoints, their size must be a power of 2
42 // that is less than 8. Note that this is a subset of what hardware allows.
43 const size_t max_size = 8;
44 size_t size = details.size;
45 if (!llvm::isPowerOf2_64(size) || size > max_size)
46 return std::nullopt;
47
48 // The start address must be aligned to 8 bytes.
49 lldb::addr_t addr = details.addr;
50 const size_t misalignment = addr & (max_size - 1);
51 if (misalignment == 0)
52 return details;
53
54 // The start address is not aligned, but we might be able to expand the
55 // watched range backwards to the previous 8 byte aligned address while
56 // keeping the size <= 8 bytes.
57 //
58 // Aligned Address
59 // | /--------- Start Address
60 // [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
61 // | |<-------- Size ------->|
62 // |<----- Aligned Size -------->|
63 //
64 size_t aligned_size = misalignment + size;
65 if (aligned_size > max_size) {
66 // The range does not fit within a single BAS watchpoint, reject it.
67 return std::nullopt;
68 }
69
70 // Size must still be a power of 2. After correcting this, sometimes we will
71 // watch bytes before and after the intended range. Stops in these extra bytes
72 // will be filtered out.
73 //
74 // For example, A is an aligned address and S is the start address. You want
75 // to watch the 1 byte at address S.
76 // [A][ ][S][ ]
77 // { }
78 // This is misaligned by 2, so our aligned size is 3.
79 // [A][ ][S][ ]
80 // { }
81 // We cannot watch 3 bytes but we can watch 4.
82 // [A][ ][S][ ]
83 // { }
84 // The watched range is expanded before and after S.
85
86 // Round up to a power of 2 size.
87 size = llvm::PowerOf2Ceil(aligned_size);
88 // Align the address down.
89 addr -= misalignment;
90
91 return WatchpointDetails{size, addr};
92}
93
95 // PAC (bits 2:1): 0b10
96 const uint32_t pac_bits = 2 << 1;
97
98 // BAS (bits 12:5) hold a bit-mask of addresses to watch.
99 // Hardware does allow gaps but we only support unbroken ranges at this time
100 //
101 // e.g. 0b00000001 means 1 byte at address
102 // 0b00000011 means 2 bytes (addr..addr+1)
103 // ...
104 // 0b11111111 means 8 bytes (addr..addr+7)
105 size_t encoded_size = ((1 << size) - 1) << 5;
106
107 return m_hw_dbg_enable_bit | pac_bits | encoded_size;
108}
109
110uint32_t
112 uint32_t watch_flags) {
113 // PAC (bits 2:1): 0b10
114 const uint32_t pac_bits = 2 << 1;
115
116 // BAS (bits 12:5) hold a bit-mask of addresses to watch.
117 // Hardware does allow gaps but we only support unbroken ranges at this time.
118 //
119 // e.g. 0b00000001 means 1 byte at address
120 // 0b00000011 means 2 bytes (addr..addr+1)
121 // ...
122 // 0b11111111 means 8 bytes (addr..addr+7)
123 size_t encoded_size = ((1 << size) - 1) << 5;
124
125 return m_hw_dbg_enable_bit | pac_bits | encoded_size | (watch_flags << 3);
126}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
uint32_t MakeWatchControlValue(size_t size, uint32_t watch_flags) override
std::optional< WatchpointDetails > AdjustWatchpoint(const WatchpointDetails &details) override
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:338
uint64_t addr_t
Definition lldb-types.h:80