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 "cflow/jumps_map.h"
17 #include "cflow/instructions_map.h"
18
19 #include "util/tests/verifier_test.h"
20
21 #include <gtest/gtest.h>
22
23 namespace panda::verifier::test {
24
TEST_F(VerifierTest,JumpsMap)25 TEST_F(VerifierTest, JumpsMap)
26 {
27 char code[148];
28 JumpsMap map {&code[5], &code[147]};
29
30 // 11110010
31 EXPECT_FALSE(map.PutJump(&code[5], &code[4]));
32 EXPECT_TRUE(map.PutJump(&code[5], &code[5]));
33 EXPECT_TRUE(map.PutJump(&code[5], &code[128]));
34 EXPECT_FALSE(map.PutJump(&code[3], &code[6]));
35 EXPECT_TRUE(map.PutJump(&code[147], &code[145]));
36 EXPECT_FALSE(map.PutJump(&code[148], &code[145]));
37 EXPECT_FALSE(map.PutJump(&code[143], &code[148]));
38
39 EXPECT_TRUE(map.PutJump(&code[13], &code[5]));
40 EXPECT_TRUE(map.PutJump(&code[12], &code[5]));
41 EXPECT_TRUE(map.PutJump(&code[11], &code[5]));
42
43 uintptr_t sum = 0;
44 map.EnumerateAllTargets<const char *>([&sum, &code](const char *tgt) {
45 uintptr_t val = reinterpret_cast<uintptr_t>(tgt) - reinterpret_cast<uintptr_t>(code);
46 sum += val;
47 return true;
48 });
49
50 EXPECT_EQ(sum, 5 + 128 + 145);
51
52 sum = 0;
53
54 map.EnumerateAllJumpsToTarget<const char *>(&code[5], [&sum, &code](const char *tgt) {
55 uintptr_t val = reinterpret_cast<uintptr_t>(tgt) - reinterpret_cast<uintptr_t>(code);
56 sum += val;
57 return true;
58 });
59
60 EXPECT_EQ(sum, 5 + 11 + 12 + 13);
61 }
62
TEST_F(VerifierTest,JumpsMapConflicts)63 TEST_F(VerifierTest, JumpsMapConflicts)
64 {
65 char code[148];
66 JumpsMap jmap {&code[5], &code[147]};
67 InstructionsMap imap {&code[5], &code[147]};
68
69 EXPECT_TRUE(imap.PutInstruction(&code[13], 5)); // 13 - ok, 14,15,16,17 - prohibited
70 EXPECT_TRUE(jmap.PutJump(&code[25], &code[13]));
71
72 EXPECT_FALSE(jmap.IsConflictingWith(imap));
73
74 EXPECT_TRUE(jmap.PutJump(&code[45], &code[14]));
75 EXPECT_TRUE(jmap.IsConflictingWith(imap));
76
77 const char *tgt_pc = nullptr;
78 const char *jmp_pc = nullptr;
79
80 EXPECT_TRUE(jmap.GetFirstConflictingJump(imap, &jmp_pc, &tgt_pc));
81
82 EXPECT_EQ(tgt_pc, &code[14]);
83 EXPECT_EQ(jmp_pc, &code[45]);
84
85 EXPECT_TRUE(jmap.PutJump(&code[35], &code[14]));
86 EXPECT_TRUE(jmap.IsConflictingWith(imap));
87
88 EXPECT_TRUE(jmap.GetFirstConflictingJump(imap, &jmp_pc, &tgt_pc));
89
90 EXPECT_EQ(tgt_pc, &code[14]);
91 EXPECT_EQ(jmp_pc, &code[45]); // should be 45, since 35 added after
92 }
93
94 } // namespace panda::verifier::test
95