• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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