1//===-- UnwindPlanTest.cpp ------------------------------------------------===//
2//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Symbol/UnwindPlan.h"
11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
13
14using namespace lldb_private;
15using namespace lldb;
16
17static UnwindPlan::Row make_simple_row(addr_t offset, uint64_t cfa_value) {
18 UnwindPlan::Row row;
19 row.SetOffset(offset);
20 row.GetCFAValue().SetIsConstant(cfa_value);
21 return row;
22}
23
24TEST(UnwindPlan, InsertRow) {
25 UnwindPlan::Row row1 = make_simple_row(offset: 0, cfa_value: 42);
26 UnwindPlan::Row row2 = make_simple_row(offset: 0, cfa_value: 47);
27 UnwindPlan::Row row3 = make_simple_row(offset: -1, cfa_value: 4242);
28
29 UnwindPlan plan(eRegisterKindGeneric);
30 plan.InsertRow(row: row1);
31 EXPECT_THAT(plan.GetRowForFunctionOffset(0), testing::Pointee(row1));
32
33 plan.InsertRow(row: row2, /*replace_existing=*/false);
34 EXPECT_THAT(plan.GetRowForFunctionOffset(0), testing::Pointee(row1));
35
36 plan.InsertRow(row: row2, /*replace_existing=*/true);
37 EXPECT_THAT(plan.GetRowForFunctionOffset(0), testing::Pointee(row2));
38
39 EXPECT_THAT(plan.GetRowForFunctionOffset(-1), nullptr);
40 plan.InsertRow(row: row3);
41 EXPECT_THAT(plan.GetRowForFunctionOffset(-1), testing::Pointee(row3));
42}
43
44TEST(UnwindPlan, GetRowForFunctionOffset) {
45 UnwindPlan::Row row1 = make_simple_row(offset: 10, cfa_value: 42);
46 UnwindPlan::Row row2 = make_simple_row(offset: 20, cfa_value: 47);
47
48 UnwindPlan plan(eRegisterKindGeneric);
49 plan.InsertRow(row: row1);
50 plan.InsertRow(row: row2);
51
52 EXPECT_THAT(plan.GetRowForFunctionOffset(0), nullptr);
53 EXPECT_THAT(plan.GetRowForFunctionOffset(9), nullptr);
54 EXPECT_THAT(plan.GetRowForFunctionOffset(10), testing::Pointee(row1));
55 EXPECT_THAT(plan.GetRowForFunctionOffset(19), testing::Pointee(row1));
56 EXPECT_THAT(plan.GetRowForFunctionOffset(20), testing::Pointee(row2));
57 EXPECT_THAT(plan.GetRowForFunctionOffset(99), testing::Pointee(row2));
58}
59
60TEST(UnwindPlan, PlanValidAtAddress) {
61 UnwindPlan::Row row1 = make_simple_row(offset: 0, cfa_value: 42);
62 UnwindPlan::Row row2 = make_simple_row(offset: 10, cfa_value: 47);
63
64 UnwindPlan plan(eRegisterKindGeneric);
65 // When valid address range is not set, plans are valid as long as they have a
66 // row that sets the CFA.
67 EXPECT_FALSE(plan.PlanValidAtAddress(Address(0)));
68 EXPECT_FALSE(plan.PlanValidAtAddress(Address(10)));
69
70 plan.InsertRow(row: row2);
71 EXPECT_TRUE(plan.PlanValidAtAddress(Address(0)));
72 EXPECT_TRUE(plan.PlanValidAtAddress(Address(10)));
73
74 plan.InsertRow(row: row1);
75 EXPECT_TRUE(plan.PlanValidAtAddress(Address(0)));
76 EXPECT_TRUE(plan.PlanValidAtAddress(Address(10)));
77
78 // With an address range, they're only valid within that range.
79 plan.SetPlanValidAddressRanges({AddressRange(0, 5), AddressRange(15, 5)});
80 EXPECT_TRUE(plan.PlanValidAtAddress(Address(0)));
81 EXPECT_FALSE(plan.PlanValidAtAddress(Address(5)));
82 EXPECT_FALSE(plan.PlanValidAtAddress(Address(10)));
83 EXPECT_TRUE(plan.PlanValidAtAddress(Address(15)));
84 EXPECT_FALSE(plan.PlanValidAtAddress(Address(20)));
85 EXPECT_FALSE(plan.PlanValidAtAddress(Address(25)));
86}
87

source code of lldb/unittests/Symbol/UnwindPlanTest.cpp