1 /*
2 * Copyright (c) 2021 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 <iostream>
17 #include <string>
18
19 #include <gtest/gtest.h>
20 #include "disassembler.h"
21
22 using namespace panda::disasm;
23
24 std::string g_bin_path_abs {};
25
TEST(label_test,test1)26 TEST(label_test, test1)
27 {
28 Disassembler d {};
29
30 std::stringstream ss {};
31 d.Disassemble(g_bin_path_abs + "labels1.bc");
32 d.Serialize(ss, false);
33
34 size_t beg_g = ss.str().find("g_u1_() <static> {\n");
35 size_t end_g = ss.str().find('}', beg_g);
36 size_t beg_gg = ss.str().find("gg_u1_() <static> {\n");
37 size_t end_gg = ss.str().find('}', beg_gg);
38
39 ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
40 ASSERT_TRUE(beg_gg != std::string::npos && end_gg != std::string::npos) << "function gg not found";
41
42 std::string body_g =
43 ss.str().substr(beg_g + strlen("g_u1_() <static> {\n"), end_g - (beg_g + strlen("g_u1_() <static> {\n")));
44 std::string body_gg =
45 ss.str().substr(beg_gg + strlen("gg_u1_() <static> {\n"), end_gg - (beg_gg + strlen("gg_u1_() <static> {\n")));
46
47 EXPECT_EQ(body_g, "\tjump_label_0: jmp jump_label_0\n\treturn\n");
48 EXPECT_EQ(body_gg, "\tjmp jump_label_0\n\tjump_label_0: return\n");
49 }
50
TEST(label_test,test2)51 TEST(label_test, test2)
52 {
53 Disassembler d {};
54
55 std::stringstream ss {};
56 d.Disassemble(g_bin_path_abs + "labels2.bc");
57 d.Serialize(ss);
58
59 size_t beg_g = ss.str().find("g_u1_() <static> {");
60 size_t end_g = ss.str().find('}', beg_g);
61
62 ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
63
64 std::string body_g = ss.str().substr(beg_g + strlen("g_u1_() {"), end_g - (beg_g + strlen("g_u1_() {")));
65
66 EXPECT_TRUE(body_g.find("jump_label_0: movi v0, 0x0") != std::string::npos) << "jump_label_0 not found";
67 EXPECT_TRUE(body_g.find("jump_label_2: movi v0, 0x1") != std::string::npos) << "jump_label_1 not found";
68 EXPECT_TRUE(body_g.find("jump_label_4: movi v0, 0x2") != std::string::npos) << "jump_label_2 not found";
69 EXPECT_TRUE(body_g.find("jump_label_6: movi v0, 0x3") != std::string::npos) << "jump_label_3 not found";
70 EXPECT_TRUE(body_g.find("jump_label_7: movi v0, 0x4") != std::string::npos) << "jump_label_4 not found";
71 EXPECT_TRUE(body_g.find("jump_label_5: movi v0, 0x5") != std::string::npos) << "jump_label_5 not found";
72 EXPECT_TRUE(body_g.find("jump_label_3: movi v0, 0x6") != std::string::npos) << "jump_label_6 not found";
73 EXPECT_TRUE(body_g.find("jump_label_1: movi v0, 0x7") != std::string::npos) << "jump_label_7 not found";
74
75 EXPECT_TRUE(body_g.find("\tjmp jump_label_0\n"
76 "\tjmp jump_label_1\n"
77 "\tjmp jump_label_2\n"
78 "\tjmp jump_label_3\n"
79 "\tjmp jump_label_4\n"
80 "\tjmp jump_label_5\n"
81 "\tjmp jump_label_6\n"
82 "\tjmp jump_label_7\n") != std::string::npos)
83 << "label sequence is broken";
84 }
85
TEST(label_test,test_exceptions)86 TEST(label_test, test_exceptions)
87 {
88 Disassembler d {};
89
90 std::stringstream ss {};
91 d.Disassemble(g_bin_path_abs + "exceptions.bc");
92 d.Serialize(ss);
93
94 std::string res = ss.str();
95
96 EXPECT_TRUE(res.find("try_begin_label_0: ldai 0x1") != std::string::npos);
97 EXPECT_TRUE(res.find("try_end_label_0: ldai 0x3") != std::string::npos);
98 EXPECT_TRUE(res.find("handler_begin_label_0_0: call.virt.short A_exception.getMessage_A_exception_A_, v0") !=
99 std::string::npos);
100 EXPECT_TRUE(res.find("handler_end_label_0_0: ldai 0x6") != std::string::npos);
101 EXPECT_TRUE(res.find("handler_begin_label_0_1: ldai 0x7") != std::string::npos);
102 EXPECT_TRUE(
103 res.find(
104 ".catch A_exception, try_begin_label_0, try_end_label_0, handler_begin_label_0_0, handler_end_label_0_0") !=
105 std::string::npos);
106 EXPECT_TRUE(res.find(".catchall try_begin_label_0, try_end_label_0, handler_begin_label_0_1") != std::string::npos);
107 }
108
main(int argc,char ** argv)109 int main(int argc, char **argv)
110 {
111 std::string dir_basename {};
112 std::string glob_argv0 = argv[0];
113
114 size_t last_slash_idx = glob_argv0.rfind('/');
115
116 if (std::string::npos != last_slash_idx) {
117 dir_basename = glob_argv0.substr(0, last_slash_idx + 1);
118 }
119
120 g_bin_path_abs = dir_basename + "../disassembler/bin/";
121
122 ::testing::InitGoogleTest(&argc, argv);
123 return RUN_ALL_TESTS();
124 }
125