1147d7a64SJason Molenda //===-- WatchpointAlgorithmsTests.cpp -------------------------------------===//
2147d7a64SJason Molenda //
3147d7a64SJason Molenda // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4147d7a64SJason Molenda // See https://llvm.org/LICENSE.txt for license information.
5147d7a64SJason Molenda // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6147d7a64SJason Molenda //
7147d7a64SJason Molenda //===----------------------------------------------------------------------===//
8147d7a64SJason Molenda
9147d7a64SJason Molenda #include "gtest/gtest.h"
10147d7a64SJason Molenda
11147d7a64SJason Molenda #include "lldb/Breakpoint/WatchpointAlgorithms.h"
12147d7a64SJason Molenda
13147d7a64SJason Molenda #include <utility>
14147d7a64SJason Molenda #include <vector>
15147d7a64SJason Molenda
16147d7a64SJason Molenda using namespace lldb;
17147d7a64SJason Molenda using namespace lldb_private;
18147d7a64SJason Molenda
19147d7a64SJason Molenda class WatchpointAlgorithmsTest : public WatchpointAlgorithms {
20147d7a64SJason Molenda public:
21147d7a64SJason Molenda using WatchpointAlgorithms::PowerOf2Watchpoints;
22*7dd790dbSJason Molenda using WatchpointAlgorithms::Region;
23*7dd790dbSJason Molenda };
24*7dd790dbSJason Molenda
25*7dd790dbSJason Molenda struct testcase {
26*7dd790dbSJason Molenda WatchpointAlgorithmsTest::Region user; // What the user requested
27*7dd790dbSJason Molenda std::vector<WatchpointAlgorithmsTest::Region>
28*7dd790dbSJason Molenda hw; // The hardware watchpoints we'll use
29147d7a64SJason Molenda };
30147d7a64SJason Molenda
check_testcase(testcase test,std::vector<WatchpointAlgorithmsTest::Region> result,size_t min_byte_size,size_t max_byte_size,uint32_t address_byte_size)31147d7a64SJason Molenda void check_testcase(testcase test,
32*7dd790dbSJason Molenda std::vector<WatchpointAlgorithmsTest::Region> result,
33147d7a64SJason Molenda size_t min_byte_size, size_t max_byte_size,
34147d7a64SJason Molenda uint32_t address_byte_size) {
35147d7a64SJason Molenda
36147d7a64SJason Molenda EXPECT_EQ(result.size(), test.hw.size());
37147d7a64SJason Molenda for (size_t i = 0; i < result.size(); i++) {
38147d7a64SJason Molenda EXPECT_EQ(result[i].addr, test.hw[i].addr);
39147d7a64SJason Molenda EXPECT_EQ(result[i].size, test.hw[i].size);
40147d7a64SJason Molenda }
41147d7a64SJason Molenda }
42147d7a64SJason Molenda
TEST(WatchpointAlgorithmsTests,PowerOf2Watchpoints)43147d7a64SJason Molenda TEST(WatchpointAlgorithmsTests, PowerOf2Watchpoints) {
44147d7a64SJason Molenda
45147d7a64SJason Molenda // clang-format off
46147d7a64SJason Molenda std::vector<testcase> doubleword_max = {
4790e68086SJason Molenda #if defined(__LP64__)
4890e68086SJason Molenda // These two tests don't work if lldb is built on
4990e68086SJason Molenda // a 32-bit system (likely with a 32-bit size_t).
5090e68086SJason Molenda // A 32-bit lldb debugging a 64-bit process isn't
5190e68086SJason Molenda // critical right now.
52147d7a64SJason Molenda {
53147d7a64SJason Molenda {0x7fffffffe83b, 1},
54147d7a64SJason Molenda {{0x7fffffffe83b, 1}}
55147d7a64SJason Molenda },
56147d7a64SJason Molenda {
57147d7a64SJason Molenda {0x7fffffffe838, 2},
58147d7a64SJason Molenda {{0x7fffffffe838, 2}}
59147d7a64SJason Molenda },
6090e68086SJason Molenda #endif
61147d7a64SJason Molenda {
62147d7a64SJason Molenda {0x1012, 8},
63147d7a64SJason Molenda {{0x1010, 8}, {0x1018, 8}}
64147d7a64SJason Molenda },
65147d7a64SJason Molenda {
66147d7a64SJason Molenda {0x1002, 4},
67147d7a64SJason Molenda {{0x1000, 8}}
68147d7a64SJason Molenda },
69147d7a64SJason Molenda {
70147d7a64SJason Molenda {0x1006, 4},
71147d7a64SJason Molenda {{0x1004, 4}, {0x1008, 4}}
72147d7a64SJason Molenda },
73147d7a64SJason Molenda {
74147d7a64SJason Molenda {0x1006, 8},
75147d7a64SJason Molenda {{0x1000, 8}, {0x1008, 8}}
76147d7a64SJason Molenda },
77147d7a64SJason Molenda {
78147d7a64SJason Molenda {0x1000, 24},
79147d7a64SJason Molenda {{0x1000, 8}, {0x1008, 8}, {0x1010, 8}}
80147d7a64SJason Molenda },
81147d7a64SJason Molenda {
82147d7a64SJason Molenda {0x1014, 26},
83147d7a64SJason Molenda {{0x1010, 8}, {0x1018, 8}, {0x1020, 8}, {0x1028, 8}}
84147d7a64SJason Molenda },
85147d7a64SJason Molenda };
86147d7a64SJason Molenda // clang-format on
87147d7a64SJason Molenda for (testcase test : doubleword_max) {
88147d7a64SJason Molenda addr_t user_addr = test.user.addr;
89147d7a64SJason Molenda size_t user_size = test.user.size;
90147d7a64SJason Molenda size_t min_byte_size = 1;
91147d7a64SJason Molenda size_t max_byte_size = 8;
92147d7a64SJason Molenda size_t address_byte_size = 8;
93147d7a64SJason Molenda auto result = WatchpointAlgorithmsTest::PowerOf2Watchpoints(
94147d7a64SJason Molenda user_addr, user_size, min_byte_size, max_byte_size, address_byte_size);
95147d7a64SJason Molenda
96147d7a64SJason Molenda check_testcase(test, result, min_byte_size, max_byte_size,
97147d7a64SJason Molenda address_byte_size);
98147d7a64SJason Molenda }
99147d7a64SJason Molenda
100147d7a64SJason Molenda // clang-format off
101147d7a64SJason Molenda std::vector<testcase> word_max = {
102147d7a64SJason Molenda {
103147d7a64SJason Molenda {0x00411050, 4},
104147d7a64SJason Molenda {{0x00411050, 4}}
105147d7a64SJason Molenda },
106147d7a64SJason Molenda {
107147d7a64SJason Molenda {0x1002, 4},
108147d7a64SJason Molenda {{0x1000, 4}, {0x1004, 4}}
109147d7a64SJason Molenda },
110147d7a64SJason Molenda };
111147d7a64SJason Molenda // clang-format on
112147d7a64SJason Molenda for (testcase test : word_max) {
113147d7a64SJason Molenda addr_t user_addr = test.user.addr;
114147d7a64SJason Molenda size_t user_size = test.user.size;
115147d7a64SJason Molenda size_t min_byte_size = 1;
116147d7a64SJason Molenda size_t max_byte_size = 4;
117147d7a64SJason Molenda size_t address_byte_size = 4;
118147d7a64SJason Molenda auto result = WatchpointAlgorithmsTest::PowerOf2Watchpoints(
119147d7a64SJason Molenda user_addr, user_size, min_byte_size, max_byte_size, address_byte_size);
120147d7a64SJason Molenda
121147d7a64SJason Molenda check_testcase(test, result, min_byte_size, max_byte_size,
122147d7a64SJason Molenda address_byte_size);
123147d7a64SJason Molenda }
124147d7a64SJason Molenda
125147d7a64SJason Molenda // clang-format off
126147d7a64SJason Molenda std::vector<testcase> twogig_max = {
127147d7a64SJason Molenda {
128147d7a64SJason Molenda {0x1010, 16},
129147d7a64SJason Molenda {{0x1010, 16}}
130147d7a64SJason Molenda },
131147d7a64SJason Molenda {
132147d7a64SJason Molenda {0x1010, 24},
133147d7a64SJason Molenda {{0x1000, 64}}
134147d7a64SJason Molenda },
135147d7a64SJason Molenda
136147d7a64SJason Molenda // We increase 36 to the aligned 64 byte size, but
137147d7a64SJason Molenda // 0x1000-0x1040 doesn't cover the requested region. Then
138147d7a64SJason Molenda // we expand to 128 bytes starting at 0x1000 that does
139147d7a64SJason Molenda // cover it. Is this a good tradeoff for a 36 byte region?
140147d7a64SJason Molenda {
141147d7a64SJason Molenda {0x1024, 36},
142147d7a64SJason Molenda {{0x1000, 128}}
143147d7a64SJason Molenda },
144147d7a64SJason Molenda {
145147d7a64SJason Molenda {0x1000, 192},
146147d7a64SJason Molenda {{0x1000, 256}}
147147d7a64SJason Molenda },
148147d7a64SJason Molenda {
149147d7a64SJason Molenda {0x1080, 192},
150147d7a64SJason Molenda {{0x1000, 512}}
151147d7a64SJason Molenda },
152147d7a64SJason Molenda
153147d7a64SJason Molenda // In this case, our aligned size is 128, and increasing it to 256
154147d7a64SJason Molenda // still can't watch the requested region. The algorithm
155147d7a64SJason Molenda // falls back to using two 128 byte watchpoints.
156147d7a64SJason Molenda // The alternative would be to use a 1024B watchpoint
157147d7a64SJason Molenda // starting at 0x1000, to watch this 120 byte user request.
158147d7a64SJason Molenda //
159147d7a64SJason Molenda // This still isn't ideal. The user is asking to watch 0x12e0-1358
160147d7a64SJason Molenda // and could be optimally handled by a
161147d7a64SJason Molenda // 16-byte watchpoint at 0x12e0 and a 128-byte watchpoint at 0x1300
162147d7a64SJason Molenda {
163147d7a64SJason Molenda {0x12e0, 120},
164147d7a64SJason Molenda {{0x1280, 128}, {0x1300, 128}}
165147d7a64SJason Molenda },
166147d7a64SJason Molenda };
167147d7a64SJason Molenda // clang-format on
168147d7a64SJason Molenda for (testcase test : twogig_max) {
169147d7a64SJason Molenda addr_t user_addr = test.user.addr;
170147d7a64SJason Molenda size_t user_size = test.user.size;
171147d7a64SJason Molenda size_t min_byte_size = 1;
172147d7a64SJason Molenda size_t max_byte_size = INT32_MAX;
173147d7a64SJason Molenda size_t address_byte_size = 8;
174147d7a64SJason Molenda auto result = WatchpointAlgorithmsTest::PowerOf2Watchpoints(
175147d7a64SJason Molenda user_addr, user_size, min_byte_size, max_byte_size, address_byte_size);
176147d7a64SJason Molenda
177147d7a64SJason Molenda check_testcase(test, result, min_byte_size, max_byte_size,
178147d7a64SJason Molenda address_byte_size);
179147d7a64SJason Molenda }
180fdd98e50SJason Molenda
181147d7a64SJason Molenda }
182