#include "gtest/gtest.h"
#include "lldb/Breakpoint/WatchpointAlgorithms.h"
#include <utility>
#include <vector>
using namespace lldb;
using namespace lldb_private;
class WatchpointAlgorithmsTest : public WatchpointAlgorithms {
public:
using WatchpointAlgorithms::PowerOf2Watchpoints;
using WatchpointAlgorithms::Region;
};
struct testcase {
WatchpointAlgorithmsTest::Region user;
std::vector<WatchpointAlgorithmsTest::Region>
hw;
};
void check_testcase(testcase test,
std::vector<WatchpointAlgorithmsTest::Region> result,
size_t min_byte_size, size_t max_byte_size,
uint32_t address_byte_size) {
EXPECT_EQ(result.size(), test.hw.size());
for (size_t i = 0; i < result.size(); i++) {
EXPECT_EQ(result[i].addr, test.hw[i].addr);
EXPECT_EQ(result[i].size, test.hw[i].size);
}
}
TEST(WatchpointAlgorithmsTests, PowerOf2Watchpoints) {
std::vector<testcase> doubleword_max = {
#if defined(__LP64__)
{
{0x7fffffffe83b, 1},
{{0x7fffffffe83b, 1}}
},
{
{0x7fffffffe838, 2},
{{0x7fffffffe838, 2}}
},
#endif
{
{0x1012, 8},
{{0x1010, 8}, {0x1018, 8}}
},
{
{0x1002, 4},
{{0x1000, 8}}
},
{
{0x1006, 4},
{{0x1004, 4}, {0x1008, 4}}
},
{
{0x1006, 8},
{{0x1000, 8}, {0x1008, 8}}
},
{
{0x1000, 24},
{{0x1000, 8}, {0x1008, 8}, {0x1010, 8}}
},
{
{0x1014, 26},
{{0x1010, 8}, {0x1018, 8}, {0x1020, 8}, {0x1028, 8}}
},
};
for (testcase test : doubleword_max) {
addr_t user_addr = test.user.addr;
size_t user_size = test.user.size;
size_t min_byte_size = 1;
size_t max_byte_size = 8;
size_t address_byte_size = 8;
auto result = WatchpointAlgorithmsTest::PowerOf2Watchpoints(
user_addr, user_size, min_byte_size, max_byte_size, address_byte_size);
check_testcase(test, result, min_byte_size, max_byte_size,
address_byte_size);
}
std::vector<testcase> word_max = {
{
{0x00411050, 4},
{{0x00411050, 4}}
},
{
{0x1002, 4},
{{0x1000, 4}, {0x1004, 4}}
},
};
for (testcase test : word_max) {
addr_t user_addr = test.user.addr;
size_t user_size = test.user.size;
size_t min_byte_size = 1;
size_t max_byte_size = 4;
size_t address_byte_size = 4;
auto result = WatchpointAlgorithmsTest::PowerOf2Watchpoints(
user_addr, user_size, min_byte_size, max_byte_size, address_byte_size);
check_testcase(test, result, min_byte_size, max_byte_size,
address_byte_size);
}
std::vector<testcase> twogig_max = {
{
{0x1010, 16},
{{0x1010, 16}}
},
{
{0x1010, 24},
{{0x1000, 64}}
},
{
{0x1024, 36},
{{0x1000, 128}}
},
{
{0x1000, 192},
{{0x1000, 256}}
},
{
{0x1080, 192},
{{0x1000, 512}}
},
{
{0x12e0, 120},
{{0x1280, 128}, {0x1300, 128}}
},
};
for (testcase test : twogig_max) {
addr_t user_addr = test.user.addr;
size_t user_size = test.user.size;
size_t min_byte_size = 1;
size_t max_byte_size = INT32_MAX;
size_t address_byte_size = 8;
auto result = WatchpointAlgorithmsTest::PowerOf2Watchpoints(
user_addr, user_size, min_byte_size, max_byte_size, address_byte_size);
check_testcase(test, result, min_byte_size, max_byte_size,
address_byte_size);
}
}