• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 2021 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <iostream>
18 #include <string>
19 
20 #include <gtest/gtest.h>
21 #include "disassembler.h"
22 
23 using namespace panda::disasm;
24 
25 std::string g_bin_path_abs {};
26 
TEST(instructions_test,test_language_panda_assembly)27 TEST(instructions_test, test_language_panda_assembly)
28 {
29     Disassembler d {};
30 
31     std::stringstream ss {};
32     d.Disassemble(g_bin_path_abs + "empty_record.bc");
33     d.Serialize(ss);
34 
35     EXPECT_TRUE(ss.str().find(".language PandaAssembly") != std::string::npos);
36 }
37 
TEST(instructions_test,test_ins)38 TEST(instructions_test, test_ins)
39 {
40     Disassembler d {};
41 
42     std::stringstream ss {};
43     d.Disassemble(g_bin_path_abs + "instructions.bc");
44     d.Serialize(ss);
45 
46     size_t beg_g = ss.str().find("g_u1_() <static> {");
47     size_t end_g = ss.str().find('}', beg_g);
48 
49     ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
50 
51     std::string body_g = ss.str().substr(beg_g + strlen("g() {"), end_g - (beg_g + strlen("g() {")));
52 
53     EXPECT_TRUE(body_g.find("\tmov v0, v1") != std::string::npos);
54     EXPECT_TRUE(body_g.find("\tmov.64 v2, v3") != std::string::npos);
55     EXPECT_TRUE(body_g.find("\tmov.obj v4, v5") != std::string::npos);
56 
57     EXPECT_TRUE(body_g.find("\tmovi v0, 0xffffffffffffffff") != std::string::npos);
58     EXPECT_TRUE(body_g.find("\tmovi.64 v0, 0x2") != std::string::npos);
59     EXPECT_TRUE(body_g.find("\tfmovi.64 v0, 0x4008147ae147ae14") != std::string::npos);
60 
61     EXPECT_TRUE(body_g.find("\tlda v1") != std::string::npos);
62     EXPECT_TRUE(body_g.find("\tlda.64 v0") != std::string::npos);
63     EXPECT_TRUE(body_g.find("\tlda.obj v1") != std::string::npos);
64 
65     EXPECT_TRUE(body_g.find("\tldai 0x1") != std::string::npos);
66     EXPECT_TRUE(body_g.find("\tldai.64 0x2") != std::string::npos);
67     EXPECT_TRUE(body_g.find("\tfldai.64 0x4008147ae147ae14") != std::string::npos);
68     EXPECT_TRUE(body_g.find("\tlda.str \"kek\"") != std::string::npos);
69     EXPECT_TRUE(body_g.find("\tlda.type A") != std::string::npos);
70     EXPECT_TRUE(body_g.find("\tlda.null") != std::string::npos);
71 
72     EXPECT_TRUE(body_g.find("\tsta v0") != std::string::npos);
73     EXPECT_TRUE(body_g.find("\tsta.64 v1") != std::string::npos);
74     EXPECT_TRUE(body_g.find("\tsta.obj v2") != std::string::npos);
75 
76     EXPECT_TRUE(body_g.find("\tjump_label_0: jmp jump_label_0") != std::string::npos);
77     EXPECT_TRUE(body_g.find("\tjeq v1, jump_label_1") != std::string::npos);
78     EXPECT_TRUE(body_g.find("\tldai 0x1") != std::string::npos);
79     EXPECT_TRUE(body_g.find("\tjmp jump_label_2") != std::string::npos);
80     EXPECT_TRUE(body_g.find("\tjump_label_1: ldai 0x0") != std::string::npos);
81     EXPECT_TRUE(body_g.find("\tjump_label_2: cmp.64 v1") != std::string::npos);
82     EXPECT_TRUE(body_g.find("\tucmp v2") != std::string::npos);
83     EXPECT_TRUE(body_g.find("\tucmp.64 v3") != std::string::npos);
84 
85     EXPECT_TRUE(body_g.find("\tfcmpl.64 v1") != std::string::npos);
86     EXPECT_TRUE(body_g.find("\tfcmpg.64 v1") != std::string::npos);
87 
88     EXPECT_TRUE(body_g.find("\tjeqz jump_label_0") != std::string::npos);
89     EXPECT_TRUE(body_g.find("\tjnez jump_label_0") != std::string::npos);
90     EXPECT_TRUE(body_g.find("\tjltz jump_label_0") != std::string::npos);
91     EXPECT_TRUE(body_g.find("\tjgtz jump_label_0") != std::string::npos);
92     EXPECT_TRUE(body_g.find("\tjlez jump_label_0") != std::string::npos);
93     EXPECT_TRUE(body_g.find("\tjgez jump_label_0") != std::string::npos);
94 
95     EXPECT_TRUE(body_g.find("\tjeq v2, jump_label_0") != std::string::npos);
96     EXPECT_TRUE(body_g.find("\tjne v2, jump_label_0") != std::string::npos);
97     EXPECT_TRUE(body_g.find("\tjlt v2, jump_label_0") != std::string::npos);
98     EXPECT_TRUE(body_g.find("\tjgt v2, jump_label_0") != std::string::npos);
99     EXPECT_TRUE(body_g.find("\tjle v2, jump_label_0") != std::string::npos);
100     EXPECT_TRUE(body_g.find("\tjge v2, jump_label_0") != std::string::npos);
101 
102     EXPECT_TRUE(body_g.find("\tfadd2.64 v1") != std::string::npos);
103     EXPECT_TRUE(body_g.find("\tfsub2.64 v1") != std::string::npos);
104     EXPECT_TRUE(body_g.find("\tfmul2.64 v1") != std::string::npos);
105     EXPECT_TRUE(body_g.find("\tfdiv2.64 v1") != std::string::npos);
106     EXPECT_TRUE(body_g.find("\tfmod2.64 v1") != std::string::npos);
107 
108     EXPECT_TRUE(body_g.find("\tadd2 v2") != std::string::npos);
109     EXPECT_TRUE(body_g.find("\tadd2.64 v2") != std::string::npos);
110     EXPECT_TRUE(body_g.find("\tsub2 v2") != std::string::npos);
111     EXPECT_TRUE(body_g.find("\tsub2.64 v2") != std::string::npos);
112     EXPECT_TRUE(body_g.find("\tmul2 v2") != std::string::npos);
113     EXPECT_TRUE(body_g.find("\tmul2.64 v2") != std::string::npos);
114     EXPECT_TRUE(body_g.find("\tand2 v2") != std::string::npos);
115     EXPECT_TRUE(body_g.find("\tand2.64 v2") != std::string::npos);
116     EXPECT_TRUE(body_g.find("\tor2 v2") != std::string::npos);
117     EXPECT_TRUE(body_g.find("\tor2.64 v2") != std::string::npos);
118     EXPECT_TRUE(body_g.find("\txor2 v2") != std::string::npos);
119     EXPECT_TRUE(body_g.find("\txor2.64 v2") != std::string::npos);
120     EXPECT_TRUE(body_g.find("\tshl2 v2") != std::string::npos);
121     EXPECT_TRUE(body_g.find("\tshl2.64 v2") != std::string::npos);
122     EXPECT_TRUE(body_g.find("\tshr2 v2") != std::string::npos);
123     EXPECT_TRUE(body_g.find("\tshr2.64 v2") != std::string::npos);
124     EXPECT_TRUE(body_g.find("\tashr2 v2") != std::string::npos);
125     EXPECT_TRUE(body_g.find("\tashr2.64 v2") != std::string::npos);
126     EXPECT_TRUE(body_g.find("\tdiv2 v2") != std::string::npos);
127     EXPECT_TRUE(body_g.find("\tdiv2.64 v2") != std::string::npos);
128     EXPECT_TRUE(body_g.find("\tmod2 v2") != std::string::npos);
129     EXPECT_TRUE(body_g.find("\tmod2.64 v2") != std::string::npos);
130     EXPECT_TRUE(body_g.find("\tdivu2 v2") != std::string::npos);
131     EXPECT_TRUE(body_g.find("\tdivu2.64 v2") != std::string::npos);
132     EXPECT_TRUE(body_g.find("\tmodu2 v2") != std::string::npos);
133     EXPECT_TRUE(body_g.find("\tmodu2.64 v2") != std::string::npos);
134 
135     EXPECT_TRUE(body_g.find("\tadd v1, v2") != std::string::npos);
136     EXPECT_TRUE(body_g.find("\tsub v1, v2") != std::string::npos);
137     EXPECT_TRUE(body_g.find("\tmul v1, v2") != std::string::npos);
138     EXPECT_TRUE(body_g.find("\tand v1, v2") != std::string::npos);
139     EXPECT_TRUE(body_g.find("\tor v1, v2") != std::string::npos);
140     EXPECT_TRUE(body_g.find("\txor v1, v2") != std::string::npos);
141     EXPECT_TRUE(body_g.find("\tshl v1, v2") != std::string::npos);
142     EXPECT_TRUE(body_g.find("\tshr v1, v2") != std::string::npos);
143     EXPECT_TRUE(body_g.find("\tashr v1, v2") != std::string::npos);
144     EXPECT_TRUE(body_g.find("\tdiv v1, v2") != std::string::npos);
145     EXPECT_TRUE(body_g.find("\tmod v1, v2") != std::string::npos);
146 
147     EXPECT_TRUE(body_g.find("\taddi 0x1") != std::string::npos);
148     EXPECT_TRUE(body_g.find("\tsubi 0x1") != std::string::npos);
149     EXPECT_TRUE(body_g.find("\tmuli 0x1") != std::string::npos);
150     EXPECT_TRUE(body_g.find("\tandi 0x1") != std::string::npos);
151     EXPECT_TRUE(body_g.find("\tori 0x1") != std::string::npos);
152     EXPECT_TRUE(body_g.find("\txori 0x1") != std::string::npos);
153     EXPECT_TRUE(body_g.find("\tshli 0x1") != std::string::npos);
154     EXPECT_TRUE(body_g.find("\tshri 0x1") != std::string::npos);
155     EXPECT_TRUE(body_g.find("\tashri 0x1") != std::string::npos);
156     EXPECT_TRUE(body_g.find("\tdivi 0x1") != std::string::npos);
157     EXPECT_TRUE(body_g.find("\tmodi 0x1") != std::string::npos);
158 
159     EXPECT_TRUE(body_g.find("\tneg") != std::string::npos);
160     EXPECT_TRUE(body_g.find("\tneg.64") != std::string::npos);
161     EXPECT_TRUE(body_g.find("\tnot") != std::string::npos);
162     EXPECT_TRUE(body_g.find("\tnot.64") != std::string::npos);
163 
164     EXPECT_TRUE(body_g.find("\ti32tof64") != std::string::npos);
165     EXPECT_TRUE(body_g.find("\tu32tof64") != std::string::npos);
166     EXPECT_TRUE(body_g.find("\ti64tof64") != std::string::npos);
167     EXPECT_TRUE(body_g.find("\tu64tof64") != std::string::npos);
168     EXPECT_TRUE(body_g.find("\tf64toi32") != std::string::npos);
169     EXPECT_TRUE(body_g.find("\tf64toi64") != std::string::npos);
170     EXPECT_TRUE(body_g.find("\tf64tou32") != std::string::npos);
171     EXPECT_TRUE(body_g.find("\tf64tou64") != std::string::npos);
172     EXPECT_TRUE(body_g.find("\ti32toi64") != std::string::npos);
173     EXPECT_TRUE(body_g.find("\ti64toi32") != std::string::npos);
174     EXPECT_TRUE(body_g.find("\tu32toi64") != std::string::npos);
175 
176     EXPECT_TRUE(body_g.find("\tldarr.8 v1") != std::string::npos);
177     EXPECT_TRUE(body_g.find("\tldarru.8 v2") != std::string::npos);
178     EXPECT_TRUE(body_g.find("\tldarr.16 v1") != std::string::npos);
179     EXPECT_TRUE(body_g.find("\tldarru.16 v1") != std::string::npos);
180     EXPECT_TRUE(body_g.find("\tldarr v1") != std::string::npos);
181     EXPECT_TRUE(body_g.find("\tldarr.64 v1") != std::string::npos);
182     EXPECT_TRUE(body_g.find("\tfldarr.32 v1") != std::string::npos);
183     EXPECT_TRUE(body_g.find("\tfldarr.64 v1") != std::string::npos);
184     EXPECT_TRUE(body_g.find("\tldarr.obj v1") != std::string::npos);
185 
186     EXPECT_TRUE(body_g.find("\tstarr.8 v1, v2") != std::string::npos);
187     EXPECT_TRUE(body_g.find("\tstarr.16 v1, v2") != std::string::npos);
188     EXPECT_TRUE(body_g.find("\tstarr v1, v2") != std::string::npos);
189     EXPECT_TRUE(body_g.find("\tstarr.64 v1, v2") != std::string::npos);
190     EXPECT_TRUE(body_g.find("\tfstarr.32 v1, v2") != std::string::npos);
191     EXPECT_TRUE(body_g.find("\tfstarr.64 v1, v2") != std::string::npos);
192     EXPECT_TRUE(body_g.find("\tstarr.obj v1, v2") != std::string::npos);
193 
194     EXPECT_TRUE(body_g.find("\tnewobj v6, A") != std::string::npos);
195 
196     EXPECT_TRUE(body_g.find("\tinitobj A.init_") != std::string::npos);
197 
198     EXPECT_TRUE(body_g.find("\tldobj v0, A.kek") != std::string::npos);
199     EXPECT_TRUE(body_g.find("\tldobj.64 v0, A.kek") != std::string::npos);
200     EXPECT_TRUE(body_g.find("\tldobj.obj v0, A.kek") != std::string::npos);
201 
202     EXPECT_TRUE(body_g.find("\tstobj v1, A.kek") != std::string::npos);
203     EXPECT_TRUE(body_g.find("\tstobj.64 v1, A.kek") != std::string::npos);
204     EXPECT_TRUE(body_g.find("\tstobj.obj v1, A.kek") != std::string::npos);
205 
206     EXPECT_TRUE(body_g.find("\tldstatic A.kek") != std::string::npos);
207     EXPECT_TRUE(body_g.find("\tldstatic.64 A.kek") != std::string::npos);
208     EXPECT_TRUE(body_g.find("\tldstatic.obj A.kek") != std::string::npos);
209 
210     EXPECT_TRUE(body_g.find("\tststatic A.kek") != std::string::npos);
211     EXPECT_TRUE(body_g.find("\tststatic.64 A.kek") != std::string::npos);
212     EXPECT_TRUE(body_g.find("\tststatic.obj A.kek") != std::string::npos);
213 
214     EXPECT_TRUE(body_g.find("\tcheckcast A") != std::string::npos);
215     EXPECT_TRUE(body_g.find("\tisinstance A") != std::string::npos);
216 }
217 
TEST(instructions_test,test_calls)218 TEST(instructions_test, test_calls)
219 {
220     Disassembler d {};
221 
222     std::stringstream ss {};
223     d.Disassemble(g_bin_path_abs + "calls.bc");
224     d.Serialize(ss);
225 
226     size_t beg_g = ss.str().find("g_u1_u1_(u1 a0) <static> {");
227     size_t end_g = ss.str().find('}', beg_g);
228 
229     ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
230 
231     std::string body_g = ss.str().substr(beg_g + strlen("g_u1_u1_(u1 a0) <static> {"),
232                                          end_g - (beg_g + strlen("g_u1_u1_(u1 a0) <static> {")));
233 
234     EXPECT_TRUE(body_g.find("\tcall.virt.short B.Bhandler_unspec_B_u8_, v4") != std::string::npos);
235     EXPECT_TRUE(body_g.find("\tcall.virt.short B.Bhandler_short_B_u1_u8_, v4, v1") != std::string::npos);
236     EXPECT_TRUE(body_g.find("\tcall.virt B.Bhandler_short2_B_u1_i64_u8_, v4, v1, v2") != std::string::npos);
237     EXPECT_TRUE(body_g.find("\tcall.virt B.Bhandler_long_B_i8_i16_i32_u16_, v4, v0, v1, v2") != std::string::npos);
238     EXPECT_TRUE(body_g.find("\tcall.virt.range B.Bhandler_range_B_i8_i16_i32_i8_i16_i32_u16_, v4") !=
239                 std::string::npos);
240 
241     EXPECT_TRUE(body_g.find("\tcall.short handler_unspec_u8_") != std::string::npos);
242     EXPECT_TRUE(body_g.find("\tcall.short handler_short_u1_u8_, v1") != std::string::npos);
243     EXPECT_TRUE(body_g.find("\tcall.short handler_short2_u1_i64_u8_, v1, v2") != std::string::npos);
244     EXPECT_TRUE(body_g.find("\tcall handler_long_i8_i16_i32_u16_, v0, v1, v2") != std::string::npos);
245     EXPECT_TRUE(body_g.find("\tcall handler_long2_i8_i16_i32_f64_u16_, v0, v1, v2, v3") != std::string::npos);
246     EXPECT_TRUE(body_g.find("\tcall.range handler_range_i8_i16_i32_i8_i16_i32_u16_, v0") != std::string::npos);
247 
248     EXPECT_TRUE(body_g.find("\tinitobj B.Bhandler_unspec_B_u8_") != std::string::npos);
249     EXPECT_TRUE(body_g.find("\tinitobj.short B.Bhandler_short_B_u1_u8_, v1") != std::string::npos);
250     EXPECT_TRUE(body_g.find("\tinitobj.short B.Bhandler_short2_B_u1_i64_u8_, v1, v2") != std::string::npos);
251     EXPECT_TRUE(body_g.find("\tinitobj B.Bhandler_long_B_i8_i16_i32_u16_, v0, v1, v2") != std::string::npos);
252     EXPECT_TRUE(body_g.find("\tinitobj B.Bhandler_long2_B_i8_i16_i32_i64_u16_, v0, v1, v2, v3") != std::string::npos);
253     EXPECT_TRUE(body_g.find("\tinitobj.range B.Bhandler_range_B_i8_i16_i32_i8_i16_i32_u16_, v0") != std::string::npos);
254 
255     EXPECT_TRUE(body_g.find("\tcall.acc.short handler_short_u1_u8_, v0, 0x0") != std::string::npos);
256     EXPECT_TRUE(body_g.find("\tcall.acc.short handler_short2_u1_i64_u8_, a0, 0x1") != std::string::npos);
257 
258     EXPECT_TRUE(ss.str().find(".function u16 long_function_i8_i16_i32_i8_i16_i32_i64_f32_u16_(i8 a0, i16 a1, i32 a2, "
259                               "i8 a3, i16 a4, i32 a5, i64 a6, f32 a7)") != std::string::npos);
260 
261     EXPECT_TRUE(body_g.find("\tcalli.dyn.short 0x1, v0") != std::string::npos);
262 }
263 
TEST(instructions_test,test_returns)264 TEST(instructions_test, test_returns)
265 {
266     Disassembler d {};
267 
268     std::stringstream ss {};
269     d.Disassemble(g_bin_path_abs + "returns.bc");
270     d.Serialize(ss);
271 
272     size_t beg_g = ss.str().find("g_u1_() <static> {");
273     size_t end_g = ss.str().find('}', beg_g);
274 
275     ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
276 
277     std::string body_g = ss.str().substr(beg_g + strlen("g() {"), end_g - (beg_g + strlen("g() {")));
278 
279     EXPECT_TRUE(body_g.find("\treturn") != std::string::npos);
280     EXPECT_TRUE(body_g.find("\treturn.64") != std::string::npos);
281     EXPECT_TRUE(body_g.find("\treturn.obj") != std::string::npos);
282     EXPECT_TRUE(body_g.find("\treturn.void") != std::string::npos);
283 }
284 
TEST(instructions_test,test_newarr)285 TEST(instructions_test, test_newarr)
286 {
287     Disassembler d {};
288 
289     std::stringstream ss {};
290     d.Disassemble(g_bin_path_abs + "newarrs.bc");
291     d.Serialize(ss);
292 
293     size_t beg_g = ss.str().find("g_u1_u1_(u1 a0) <static> {");
294     size_t end_g = ss.str().find('}', beg_g);
295 
296     ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
297 
298     std::string body_g = ss.str().substr(beg_g + strlen("g() {"), end_g - (beg_g + strlen("g() {")));
299 
300     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u1[]") != std::string::npos);
301     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i8[]") != std::string::npos);
302     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u8[]") != std::string::npos);
303     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i16[]") != std::string::npos);
304     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u16[]") != std::string::npos);
305     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i32[]") != std::string::npos);
306     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u32[]") != std::string::npos);
307     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, f32[]") != std::string::npos);
308     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, f64[]") != std::string::npos);
309     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i64[]") != std::string::npos);
310     EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u64[]") != std::string::npos);
311 }
312 
main(int argc,char ** argv)313 int main(int argc, char **argv)
314 {
315     std::string dir_basename {};
316     std::string glob_argv0 = argv[0];
317 
318     size_t last_slash_idx = glob_argv0.rfind('/');
319 
320     if (std::string::npos != last_slash_idx) {
321         dir_basename = glob_argv0.substr(0, last_slash_idx + 1);
322     }
323 
324     g_bin_path_abs = dir_basename + "../disassembler/bin/";
325 
326     ::testing::InitGoogleTest(&argc, argv);
327     return RUN_ALL_TESTS();
328 }
329