1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "absint/reg_context.h"
17 #include "absint/exec_context.h"
18
19 #include "value/abstract_typed_value.h"
20 #include "type/type_system.h"
21 #include "type/type_sort.h"
22 #include "type/type_image.h"
23
24 #include "util/lazy.h"
25
26 #include "util/tests/verifier_test.h"
27
28 #include <gtest/gtest.h>
29
30 #include <functional>
31
32 namespace panda::verifier::test {
33
TEST_F(VerifierTest,AbsIntExecContext)34 TEST_F(VerifierTest, AbsIntExecContext)
35 {
36 SortNames sort {"Bot", "Top"};
37 TypeSystem type_system {sort["Bot"], sort["Top"]};
38 Variables variables;
39
40 auto i8 = type_system.Parametric(sort["i8"])();
41 auto i16 = type_system.Parametric(sort["i16"])();
42 auto i32 = type_system.Parametric(sort["i32"])();
43 auto i64 = type_system.Parametric(sort["i64"])();
44
45 i8 << i16 << i32 << i64;
46
47 auto u8 = type_system.Parametric(sort["u8"])();
48 auto u16 = type_system.Parametric(sort["u16"])();
49 auto u32 = type_system.Parametric(sort["u32"])();
50 auto u64 = type_system.Parametric(sort["u64"])();
51
52 u8 << u16 << u32 << u64;
53
54 auto nv = [&variables] { return variables.NewVar(); };
55
56 AbstractTypedValue av1 {i16, nv()};
57 AbstractTypedValue av2 {i32, nv()};
58 AbstractTypedValue av3 {u16, nv()};
59
60 uint8_t instructions[128];
61
62 ExecContext exec_ctx {&instructions[0], &instructions[127]};
63
64 std::array<const uint8_t *, 6> cp = {&instructions[8], &instructions[17], &instructions[23],
65 &instructions[49], &instructions[73], &instructions[103]};
66
67 exec_ctx.SetCheckPoints(ConstLazyFetch(cp));
68
69 // 1 1 1 1 1 1
70 // C I C I C I
71 // E E
72
73 RegContext ctx1;
74 RegContext ctx2;
75 RegContext ctx3;
76
77 ctx1[-1] = av1;
78 ctx1[0] = av2;
79
80 ctx2[0] = av1; // compat with 1
81
82 ctx3[-1] = av3; // incompat with 1
83
84 exec_ctx.CurrentRegContext() = ctx1;
85
86 exec_ctx.StoreCurrentRegContextForAddr(cp[0]);
87 exec_ctx.StoreCurrentRegContextForAddr(cp[1]);
88 exec_ctx.StoreCurrentRegContextForAddr(cp[2]);
89 exec_ctx.StoreCurrentRegContextForAddr(cp[3]);
90 exec_ctx.StoreCurrentRegContextForAddr(cp[4]);
91 exec_ctx.StoreCurrentRegContextForAddr(cp[5]);
92
93 exec_ctx.AddEntryPoint(cp[1], EntryPointType::METHOD_BODY);
94 exec_ctx.AddEntryPoint(cp[4], EntryPointType::METHOD_BODY);
95
96 const uint8_t *ep = &instructions[0];
97 EntryPointType ept;
98
99 exec_ctx.CurrentRegContext() = ctx2;
100 while (ep != cp[0]) {
101 exec_ctx.StoreCurrentRegContextForAddr(ep++);
102 }
103 exec_ctx.StoreCurrentRegContextForAddr(ep++);
104
105 exec_ctx.CurrentRegContext() = ctx3;
106 while (ep != cp[1]) {
107 exec_ctx.StoreCurrentRegContextForAddr(ep++);
108 }
109 exec_ctx.StoreCurrentRegContextForAddr(ep);
110
111 exec_ctx.CurrentRegContext() = ctx2;
112 while (ep != cp[2]) {
113 exec_ctx.StoreCurrentRegContextForAddr(ep++);
114 }
115 exec_ctx.StoreCurrentRegContextForAddr(ep++);
116
117 exec_ctx.CurrentRegContext() = ctx3;
118 while (ep != cp[3]) {
119 exec_ctx.StoreCurrentRegContextForAddr(ep++);
120 }
121 exec_ctx.StoreCurrentRegContextForAddr(ep++);
122
123 exec_ctx.CurrentRegContext() = ctx2;
124 while (ep != cp[4]) {
125 exec_ctx.StoreCurrentRegContextForAddr(ep++);
126 }
127 exec_ctx.StoreCurrentRegContextForAddr(ep++);
128
129 exec_ctx.CurrentRegContext() = ctx3;
130 while (ep != cp[5]) {
131 exec_ctx.StoreCurrentRegContextForAddr(ep++);
132 }
133 exec_ctx.StoreCurrentRegContextForAddr(ep++);
134
135 auto status = exec_ctx.GetEntryPointForChecking(&ep, &ept);
136
137 status = exec_ctx.GetEntryPointForChecking(&ep, &ept);
138
139 status = exec_ctx.GetEntryPointForChecking(&ep, &ept);
140
141 EXPECT_EQ(status, ExecContext::Status::ALL_DONE);
142 }
143
144 } // namespace panda::verifier::test
145