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 "public_internal.h"
20 #include "jobs/service.h"
21 #include "type/type_system.h"
22 #include "value/abstract_typed_value.h"
23
24 #include "util/lazy.h"
25 #include "util/tests/verifier_test.h"
26
27 #include <gtest/gtest.h>
28
29 #include <functional>
30
31 // NOLINTBEGIN(readability-magic-numbers,cppcoreguidelines-pro-bounds-pointer-arithmetic)
32
33 namespace panda::verifier::test {
34
TEST_F(VerifierTest,AbsIntExecContext)35 TEST_F(VerifierTest, AbsIntExecContext)
36 {
37 using Builtin = Type::Builtin;
38 auto *config = NewConfig();
39 RuntimeOptions runtimeOpts;
40 Runtime::Create(runtimeOpts);
41 auto *service = CreateService(config, Runtime::GetCurrent()->GetInternalAllocator(),
42 Runtime::GetCurrent()->GetClassLinker(), "");
43 TypeSystem typeSystem(service->verifierService);
44 Variables variables;
45
46 auto i16 = Type {Builtin::I16};
47 auto i32 = Type {Builtin::I32};
48
49 auto u16 = Type {Builtin::U16};
50
51 auto nv = [&variables] { return variables.NewVar(); };
52
53 AbstractTypedValue av1 {i16, nv()};
54 AbstractTypedValue av2 {i32, nv()};
55 AbstractTypedValue av3 {u16, nv()};
56
57 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
58 uint8_t instructions[128U];
59
60 ExecContext execCtx {&instructions[0], &instructions[127U], &typeSystem};
61
62 std::array<const uint8_t *, 6> cp = {&instructions[8U], &instructions[17U], &instructions[23U],
63 &instructions[49U], &instructions[73U], &instructions[103U]};
64
65 execCtx.SetCheckPoints(ConstLazyFetch(cp));
66
67 // 1 1 1 1 1 1
68 // C I C I C I
69 // E E
70
71 RegContext ctx1;
72 RegContext ctx2;
73 RegContext ctx3;
74
75 ctx1[-1] = av1;
76 ctx1[0] = av2;
77
78 ctx2[0] = av1; // compat with 1
79
80 ctx3[-1] = av3; // incompat with 1
81
82 execCtx.CurrentRegContext() = ctx1;
83
84 execCtx.StoreCurrentRegContextForAddr(cp[0U]);
85 execCtx.StoreCurrentRegContextForAddr(cp[1U]);
86 execCtx.StoreCurrentRegContextForAddr(cp[2U]);
87 execCtx.StoreCurrentRegContextForAddr(cp[3U]);
88 execCtx.StoreCurrentRegContextForAddr(cp[4U]);
89 execCtx.StoreCurrentRegContextForAddr(cp[5U]);
90
91 execCtx.AddEntryPoint(cp[1U], EntryPointType::METHOD_BODY);
92 execCtx.AddEntryPoint(cp[4U], EntryPointType::METHOD_BODY);
93
94 const uint8_t *ep = &instructions[0];
95 EntryPointType ept;
96
97 execCtx.CurrentRegContext() = ctx2;
98 while (ep != cp[0U]) {
99 execCtx.StoreCurrentRegContextForAddr(ep++);
100 }
101 execCtx.StoreCurrentRegContextForAddr(ep++);
102
103 execCtx.CurrentRegContext() = ctx3;
104 while (ep != cp[1U]) {
105 execCtx.StoreCurrentRegContextForAddr(ep++);
106 }
107 execCtx.StoreCurrentRegContextForAddr(ep);
108
109 execCtx.CurrentRegContext() = ctx2;
110 while (ep != cp[2U]) {
111 execCtx.StoreCurrentRegContextForAddr(ep++);
112 }
113 execCtx.StoreCurrentRegContextForAddr(ep++);
114
115 execCtx.CurrentRegContext() = ctx3;
116 while (ep != cp[3U]) {
117 execCtx.StoreCurrentRegContextForAddr(ep++);
118 }
119 execCtx.StoreCurrentRegContextForAddr(ep++);
120
121 execCtx.CurrentRegContext() = ctx2;
122 while (ep != cp[4U]) {
123 execCtx.StoreCurrentRegContextForAddr(ep++);
124 }
125 execCtx.StoreCurrentRegContextForAddr(ep++);
126
127 execCtx.CurrentRegContext() = ctx3;
128 while (ep != cp[5U]) {
129 execCtx.StoreCurrentRegContextForAddr(ep++);
130 }
131 execCtx.StoreCurrentRegContextForAddr(ep++);
132
133 execCtx.GetEntryPointForChecking(&ep, &ept);
134
135 execCtx.GetEntryPointForChecking(&ep, &ept);
136
137 auto status = execCtx.GetEntryPointForChecking(&ep, &ept);
138
139 EXPECT_EQ(status, ExecContext::Status::ALL_DONE);
140
141 DestroyService(service, false);
142 DestroyConfig(config);
143 }
144
145 } // namespace panda::verifier::test
146
147 // NOLINTEND(readability-magic-numbers,cppcoreguidelines-pro-bounds-pointer-arithmetic)
148