1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
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 "gtest/gtest.h"
18 
19 #include <cstring>
20 
21 #include "berberis/base/bit_util.h"
22 #include "berberis/guest_abi/guest_params.h"
23 #include "berberis/guest_state/guest_addr.h"
24 #include "berberis/guest_state/guest_state.h"
25 
26 namespace berberis {
27 
28 namespace {
29 
TEST(Params,PtrIntArgs)30 TEST(Params, PtrIntArgs) {
31   ThreadState state{};
32 
33   static int x;
34 
35   state.cpu.x[0] = ToGuestAddr(&x);
36   state.cpu.x[1] = static_cast<uint64_t>(1234u);
37   state.cpu.x[2] = static_cast<uint64_t>(-7);
38 
39   auto [param1, param2, param3] = GuestParamsValues<void(int*, unsigned int, int)>(&state);
40   auto [param1f, param2f, param3f] = GuestParamsValues<void (*)(int*, unsigned int, int)>(&state);
41   auto [param1v, param2v, param3v] = GuestParamsValues<void(int*, unsigned int, int, ...)>(&state);
42   auto [param1fv, param2fv, param3fv] =
43       GuestParamsValues<void (*)(int*, unsigned int, int, ...)>(&state);
44 
45   EXPECT_EQ(&x, param1);
46   EXPECT_EQ(1234u, param2);
47   EXPECT_EQ(-7, param3);
48 
49   EXPECT_EQ(&x, param1f);
50   EXPECT_EQ(1234u, param2f);
51   EXPECT_EQ(-7, param3f);
52 
53   EXPECT_EQ(&x, param1v);
54   EXPECT_EQ(1234u, param2v);
55   EXPECT_EQ(-7, param3v);
56 
57   EXPECT_EQ(&x, param1fv);
58   EXPECT_EQ(1234u, param2fv);
59   EXPECT_EQ(-7, param3fv);
60 }
61 
TEST(Params,IntRes)62 TEST(Params, IntRes) {
63   ThreadState state{};
64 
65   auto&& [ret] = GuestReturnReference<int()>(&state);
66   auto&& [retf] = GuestReturnReference<int (*)()>(&state);
67   auto&& [retv] = GuestReturnReference<int(...)>(&state);
68   auto&& [retfv] = GuestReturnReference<int (*)(...)>(&state);
69 
70   ret = 123;
71   EXPECT_EQ(123u, state.cpu.x[0]);
72 
73   retf = 234;
74   EXPECT_EQ(234u, state.cpu.x[0]);
75 
76   retv = 345;
77   EXPECT_EQ(345u, state.cpu.x[0]);
78 
79   retfv = 456;
80   EXPECT_EQ(456u, state.cpu.x[0]);
81 }
82 
TEST(Params,SignedCharRes)83 TEST(Params, SignedCharRes) {
84   ThreadState state{};
85 
86   state.cpu.x[0] = 0;
87 
88   auto&& [ret] = GuestReturnReference<signed char()>(&state);
89   auto&& [retf] = GuestReturnReference<signed char (*)()>(&state);
90   auto&& [retv] = GuestReturnReference<signed char(...)>(&state);
91   auto&& [retfv] = GuestReturnReference<signed char (*)(...)>(&state);
92 
93   ret = -1;
94   EXPECT_EQ(0xFFu, state.cpu.x[0]);
95 
96   retf = -2;
97   EXPECT_EQ(0xFEu, state.cpu.x[0]);
98 
99   retv = -3;
100   EXPECT_EQ(0xFDu, state.cpu.x[0]);
101 
102   retfv = -4;
103   EXPECT_EQ(0xFCu, state.cpu.x[0]);
104 }
105 
TEST(Params,PtrRes)106 TEST(Params, PtrRes) {
107   ThreadState state{};
108 
109   state.cpu.x[0] = static_cast<uint64_t>(42);
110 
111   auto&& [ret] = GuestReturnReference<void*()>(&state);
112 
113   ret = nullptr;
114 
115   EXPECT_EQ(0u, state.cpu.x[0]);
116 }
117 
TEST(Params,SignedCharArg)118 TEST(Params, SignedCharArg) {
119   ThreadState state{};
120 
121   state.cpu.x[0] = 0xF0F0F0F0F0F0F0F0ULL;
122 
123   auto [arg] = GuestParamsValues<void(signed char)>(&state);
124   auto [argf] = GuestParamsValues<void (*)(signed char)>(&state);
125   auto [argv] = GuestParamsValues<void(signed char, ...)>(&state);
126   auto [argfv] = GuestParamsValues<void (*)(signed char, ...)>(&state);
127 
128   EXPECT_EQ(-16, arg);
129 
130   EXPECT_EQ(-16, argf);
131 
132   EXPECT_EQ(-16, argv);
133 
134   EXPECT_EQ(-16, argfv);
135 }
136 
TEST(Params,IntFloatIntDoubleArgs)137 TEST(Params, IntFloatIntDoubleArgs) {
138   ThreadState state{};
139 
140   state.cpu.x[0] = static_cast<uint64_t>(1234u);
141   state.cpu.x[1] = static_cast<uint64_t>(-7);
142   float f = 2.71f;
143   memcpy(state.cpu.v + 0, &f, sizeof(f));
144   double d = 3.14;
145   memcpy(state.cpu.v + 1, &d, sizeof(d));
146 
147   auto [param1, param2, param3, param4] =
148       GuestParamsValues<void(unsigned int, float, int, double)>(&state);
149   auto [param1f, param2f, param3f, param4f] =
150       GuestParamsValues<void (*)(unsigned int, float, int, double)>(&state);
151   auto [param1v, param2v, param3v, param4v] =
152       GuestParamsValues<void(unsigned int, float, int, double, ...)>(&state);
153   auto [param1fv, param2fv, param3fv, param4fv] =
154       GuestParamsValues<void (*)(unsigned int, float, int, double, ...)>(&state);
155 
156   EXPECT_EQ(1234u, param1);
157   EXPECT_FLOAT_EQ(2.71f, param2);
158   EXPECT_EQ(-7, param3);
159   EXPECT_DOUBLE_EQ(3.14, param4);
160 
161   EXPECT_EQ(1234u, param1f);
162   EXPECT_FLOAT_EQ(2.71f, param2f);
163   EXPECT_EQ(-7, param3f);
164   EXPECT_DOUBLE_EQ(3.14, param4f);
165 
166   EXPECT_EQ(1234u, param1v);
167   EXPECT_FLOAT_EQ(2.71f, param2v);
168   EXPECT_EQ(-7, param3v);
169   EXPECT_DOUBLE_EQ(3.14, param4v);
170 
171   EXPECT_EQ(1234u, param1fv);
172   EXPECT_FLOAT_EQ(2.71f, param2fv);
173   EXPECT_EQ(-7, param3fv);
174   EXPECT_DOUBLE_EQ(3.14, param4fv);
175 }
176 
TEST(Params,DoubleRes)177 TEST(Params, DoubleRes) {
178   ThreadState state{};
179   double d;
180 
181   auto&& [ret] = GuestReturnReference<double()>(&state);
182   auto&& [retf] = GuestReturnReference<double (*)()>(&state);
183   auto&& [retv] = GuestReturnReference<double(...)>(&state);
184   auto&& [retfv] = GuestReturnReference<double (*)(...)>(&state);
185 
186   ret = 3.14;
187   memcpy(&d, state.cpu.v + 0, sizeof(d));
188   EXPECT_DOUBLE_EQ(3.14, d);
189 
190   retf = 3.15;
191   memcpy(&d, state.cpu.v + 0, sizeof(d));
192   EXPECT_DOUBLE_EQ(3.15, d);
193 
194   retv = 3.15;
195   memcpy(&d, state.cpu.v + 0, sizeof(d));
196   EXPECT_DOUBLE_EQ(3.15, d);
197 
198   retfv = 3.16;
199   memcpy(&d, state.cpu.v + 0, sizeof(d));
200   EXPECT_DOUBLE_EQ(3.16, d);
201 }
202 
TEST(Params,StackArgs)203 TEST(Params, StackArgs) {
204   static_assert(sizeof(double) == sizeof(int64_t));
205   int64_t stack[8];
206 
207   ThreadState state{};
208   state.cpu.sp = ToGuestAddr(stack);
209 
210   state.cpu.x[0] = 0;
211   state.cpu.x[1] = 1;
212   state.cpu.x[2] = 2;
213   state.cpu.x[3] = 3;
214   state.cpu.x[4] = 4;
215   state.cpu.x[5] = 5;
216   state.cpu.x[6] = 6;
217   state.cpu.x[7] = 7;
218   stack[0] = 8;
219   stack[1] = 9;
220 
221   double d;
222   d = 0.0;
223   memcpy(state.cpu.v + 0, &d, sizeof(d));
224   d = 1.1;
225   memcpy(state.cpu.v + 1, &d, sizeof(d));
226   d = 2.2;
227   memcpy(state.cpu.v + 2, &d, sizeof(d));
228   d = 3.3;
229   memcpy(state.cpu.v + 3, &d, sizeof(d));
230   d = 4.4;
231   memcpy(state.cpu.v + 4, &d, sizeof(d));
232   d = 5.5;
233   memcpy(state.cpu.v + 5, &d, sizeof(d));
234   d = 6.6;
235   memcpy(state.cpu.v + 6, &d, sizeof(d));
236   d = 7.7;
237   memcpy(state.cpu.v + 7, &d, sizeof(d));
238   d = 8.8;
239   memcpy(stack + 2, &d, sizeof(d));
240   d = 9.9;
241   memcpy(stack + 3, &d, sizeof(d));
242 
243   auto [param1,
244         param2,
245         param3,
246         param4,
247         param5,
248         param6,
249         param7,
250         param8,
251         param9,
252         param10,
253         param11,
254         param12,
255         param13,
256         param14,
257         param15,
258         param16,
259         param17,
260         param18,
261         param19,
262         param20] = GuestParamsValues<void(int,
263                                           int,
264                                           int,
265                                           int,
266                                           int,
267                                           int,
268                                           int,
269                                           int,
270                                           int,
271                                           int,
272                                           double,
273                                           double,
274                                           double,
275                                           double,
276                                           double,
277                                           double,
278                                           double,
279                                           double,
280                                           double,
281                                           double)>(&state);
282   auto [param1f,
283         param2f,
284         param3f,
285         param4f,
286         param5f,
287         param6f,
288         param7f,
289         param8f,
290         param9f,
291         param10f,
292         param11f,
293         param12f,
294         param13f,
295         param14f,
296         param15f,
297         param16f,
298         param17f,
299         param18f,
300         param19f,
301         param20f] = GuestParamsValues<void (*)(int,
302                                                int,
303                                                int,
304                                                int,
305                                                int,
306                                                int,
307                                                int,
308                                                int,
309                                                int,
310                                                int,
311                                                double,
312                                                double,
313                                                double,
314                                                double,
315                                                double,
316                                                double,
317                                                double,
318                                                double,
319                                                double,
320                                                double)>(&state);
321   auto [param1v,
322         param2v,
323         param3v,
324         param4v,
325         param5v,
326         param6v,
327         param7v,
328         param8v,
329         param9v,
330         param10v,
331         param11v,
332         param12v,
333         param13v,
334         param14v,
335         param15v,
336         param16v,
337         param17v,
338         param18v,
339         param19v,
340         param20v] = GuestParamsValues<void(int,
341                                            int,
342                                            int,
343                                            int,
344                                            int,
345                                            int,
346                                            int,
347                                            int,
348                                            int,
349                                            int,
350                                            double,
351                                            double,
352                                            double,
353                                            double,
354                                            double,
355                                            double,
356                                            double,
357                                            double,
358                                            double,
359                                            double,
360                                            ...)>(&state);
361   auto [param1fv,
362         param2fv,
363         param3fv,
364         param4fv,
365         param5fv,
366         param6fv,
367         param7fv,
368         param8fv,
369         param9fv,
370         param10fv,
371         param11fv,
372         param12fv,
373         param13fv,
374         param14fv,
375         param15fv,
376         param16fv,
377         param17fv,
378         param18fv,
379         param19fv,
380         param20fv] = GuestParamsValues<void (*)(int,
381                                                 int,
382                                                 int,
383                                                 int,
384                                                 int,
385                                                 int,
386                                                 int,
387                                                 int,
388                                                 int,
389                                                 int,
390                                                 double,
391                                                 double,
392                                                 double,
393                                                 double,
394                                                 double,
395                                                 double,
396                                                 double,
397                                                 double,
398                                                 double,
399                                                 double,
400                                                 ...)>(&state);
401 
402   EXPECT_EQ(0, param1);
403   EXPECT_EQ(1, param2);
404   EXPECT_EQ(2, param3);
405   EXPECT_EQ(3, param4);
406   EXPECT_EQ(4, param5);
407   EXPECT_EQ(5, param6);
408   EXPECT_EQ(6, param7);
409   EXPECT_EQ(7, param8);
410   EXPECT_EQ(8, param9);
411   EXPECT_EQ(9, param10);
412 
413   EXPECT_DOUBLE_EQ(0.0, param11);
414   EXPECT_DOUBLE_EQ(1.1, param12);
415   EXPECT_DOUBLE_EQ(2.2, param13);
416   EXPECT_DOUBLE_EQ(3.3, param14);
417   EXPECT_DOUBLE_EQ(4.4, param15);
418   EXPECT_DOUBLE_EQ(5.5, param16);
419   EXPECT_DOUBLE_EQ(6.6, param17);
420   EXPECT_DOUBLE_EQ(7.7, param18);
421   EXPECT_DOUBLE_EQ(8.8, param19);
422   EXPECT_DOUBLE_EQ(9.9, param20);
423 
424   EXPECT_EQ(0, param1f);
425   EXPECT_EQ(1, param2f);
426   EXPECT_EQ(2, param3f);
427   EXPECT_EQ(3, param4f);
428   EXPECT_EQ(4, param5f);
429   EXPECT_EQ(5, param6f);
430   EXPECT_EQ(6, param7f);
431   EXPECT_EQ(7, param8f);
432   EXPECT_EQ(8, param9f);
433   EXPECT_EQ(9, param10f);
434 
435   EXPECT_DOUBLE_EQ(0.0, param11f);
436   EXPECT_DOUBLE_EQ(1.1, param12f);
437   EXPECT_DOUBLE_EQ(2.2, param13f);
438   EXPECT_DOUBLE_EQ(3.3, param14f);
439   EXPECT_DOUBLE_EQ(4.4, param15f);
440   EXPECT_DOUBLE_EQ(5.5, param16f);
441   EXPECT_DOUBLE_EQ(6.6, param17f);
442   EXPECT_DOUBLE_EQ(7.7, param18f);
443   EXPECT_DOUBLE_EQ(8.8, param19f);
444   EXPECT_DOUBLE_EQ(9.9, param20f);
445 
446   EXPECT_EQ(0, param1v);
447   EXPECT_EQ(1, param2v);
448   EXPECT_EQ(2, param3v);
449   EXPECT_EQ(3, param4v);
450   EXPECT_EQ(4, param5v);
451   EXPECT_EQ(5, param6v);
452   EXPECT_EQ(6, param7v);
453   EXPECT_EQ(7, param8v);
454   EXPECT_EQ(8, param9v);
455   EXPECT_EQ(9, param10v);
456 
457   EXPECT_DOUBLE_EQ(0.0, param11v);
458   EXPECT_DOUBLE_EQ(1.1, param12v);
459   EXPECT_DOUBLE_EQ(2.2, param13v);
460   EXPECT_DOUBLE_EQ(3.3, param14v);
461   EXPECT_DOUBLE_EQ(4.4, param15v);
462   EXPECT_DOUBLE_EQ(5.5, param16v);
463   EXPECT_DOUBLE_EQ(6.6, param17v);
464   EXPECT_DOUBLE_EQ(7.7, param18v);
465   EXPECT_DOUBLE_EQ(8.8, param19v);
466   EXPECT_DOUBLE_EQ(9.9, param20v);
467 
468   EXPECT_EQ(0, param1fv);
469   EXPECT_EQ(1, param2fv);
470   EXPECT_EQ(2, param3fv);
471   EXPECT_EQ(3, param4fv);
472   EXPECT_EQ(4, param5fv);
473   EXPECT_EQ(5, param6fv);
474   EXPECT_EQ(6, param7fv);
475   EXPECT_EQ(7, param8fv);
476   EXPECT_EQ(8, param9fv);
477   EXPECT_EQ(9, param10fv);
478 
479   EXPECT_DOUBLE_EQ(0.0, param11fv);
480   EXPECT_DOUBLE_EQ(1.1, param12fv);
481   EXPECT_DOUBLE_EQ(2.2, param13fv);
482   EXPECT_DOUBLE_EQ(3.3, param14fv);
483   EXPECT_DOUBLE_EQ(4.4, param15fv);
484   EXPECT_DOUBLE_EQ(5.5, param16fv);
485   EXPECT_DOUBLE_EQ(6.6, param17fv);
486   EXPECT_DOUBLE_EQ(7.7, param18fv);
487   EXPECT_DOUBLE_EQ(8.8, param19fv);
488   EXPECT_DOUBLE_EQ(9.9, param20fv);
489 }
490 
TEST(Params,LongArgHugeStructResult)491 TEST(Params, LongArgHugeStructResult) {
492   ThreadState state{};
493 
494   struct Result {
495     uint64_t values[10];
496   } result{};
497 
498   state.cpu.x[0] = 0xdead0000beef;
499   state.cpu.x[8] = bit_cast<uint64_t>(&result);
500 
501   auto [arg] = GuestParamsValues<Result(uint64_t)>(&state);
502 
503   EXPECT_EQ(0xdead0000beefUL, arg);
504 
505   auto&& [ret] = GuestReturnReference<Result(uint64_t)>(&state);
506 
507   ret = Result{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
508 
509   EXPECT_EQ(1U, result.values[0]);
510   EXPECT_EQ(2U, result.values[1]);
511   EXPECT_EQ(3U, result.values[2]);
512   EXPECT_EQ(4U, result.values[3]);
513   EXPECT_EQ(5U, result.values[4]);
514   EXPECT_EQ(6U, result.values[5]);
515   EXPECT_EQ(7U, result.values[6]);
516   EXPECT_EQ(8U, result.values[7]);
517   EXPECT_EQ(9U, result.values[8]);
518   EXPECT_EQ(10U, result.values[9]);
519 }
520 
TEST(GuestVAListParams,PtrIntArgs)521 TEST(GuestVAListParams, PtrIntArgs) {
522   ThreadState state{};
523 
524   static int x;
525 
526   state.cpu.x[0] = ToGuestAddr(&x);
527   state.cpu.x[1] = static_cast<uint64_t>(1234u);
528   state.cpu.x[2] = static_cast<uint64_t>(-7);
529 
530   GuestVAListParams params = GuestParamsValues<void(...)>(&state);
531 
532   EXPECT_EQ(&x, params.GetPointerParam<int>());
533   EXPECT_EQ(1234u, params.GetParam<unsigned int>());
534   EXPECT_EQ(-7, params.GetParam<int>());
535 }
536 
TEST(GuestVAListParams,IntFloatIntDoubleArgs)537 TEST(GuestVAListParams, IntFloatIntDoubleArgs) {
538   ThreadState state{};
539 
540   state.cpu.x[0] = static_cast<uint64_t>(1234u);
541   state.cpu.x[1] = static_cast<uint64_t>(-7);
542   float f = 2.71f;
543   memcpy(state.cpu.v + 0, &f, sizeof(f));
544   double d = 3.14;
545   memcpy(state.cpu.v + 1, &d, sizeof(d));
546 
547   GuestVAListParams params = GuestParamsValues<void(...)>(&state);
548 
549   EXPECT_EQ(1234u, params.GetParam<unsigned int>());
550   EXPECT_FLOAT_EQ(2.71f, params.GetParam<float>());
551   EXPECT_EQ(-7, params.GetParam<int>());
552   EXPECT_DOUBLE_EQ(3.14, params.GetParam<double>());
553 }
554 
TEST(GuestVAListParams,StackArgs)555 TEST(GuestVAListParams, StackArgs) {
556   static_assert(sizeof(double) == sizeof(int64_t));
557   int64_t stack[8];
558 
559   ThreadState state{};
560   state.cpu.sp = ToGuestAddr(stack);
561 
562   state.cpu.x[0] = 0;
563   state.cpu.x[1] = 1;
564   state.cpu.x[2] = 2;
565   state.cpu.x[3] = 3;
566   state.cpu.x[4] = 4;
567   state.cpu.x[5] = 5;
568   state.cpu.x[6] = 6;
569   state.cpu.x[7] = 7;
570   stack[0] = 8;
571   stack[1] = 9;
572 
573   double d;
574   d = 0.0;
575   memcpy(state.cpu.v + 0, &d, sizeof(d));
576   d = 1.1;
577   memcpy(state.cpu.v + 1, &d, sizeof(d));
578   d = 2.2;
579   memcpy(state.cpu.v + 2, &d, sizeof(d));
580   d = 3.3;
581   memcpy(state.cpu.v + 3, &d, sizeof(d));
582   d = 4.4;
583   memcpy(state.cpu.v + 4, &d, sizeof(d));
584   d = 5.5;
585   memcpy(state.cpu.v + 5, &d, sizeof(d));
586   d = 6.6;
587   memcpy(state.cpu.v + 6, &d, sizeof(d));
588   d = 7.7;
589   memcpy(state.cpu.v + 7, &d, sizeof(d));
590   d = 8.8;
591   memcpy(stack + 2, &d, sizeof(d));
592   d = 9.9;
593   memcpy(stack + 3, &d, sizeof(d));
594 
595   GuestVAListParams params = GuestParamsValues<void(...)>(&state);
596 
597   EXPECT_EQ(0, params.GetParam<int>());
598   EXPECT_EQ(1, params.GetParam<int>());
599   EXPECT_EQ(2, params.GetParam<int>());
600   EXPECT_EQ(3, params.GetParam<int>());
601   EXPECT_EQ(4, params.GetParam<int>());
602   EXPECT_EQ(5, params.GetParam<int>());
603   EXPECT_EQ(6, params.GetParam<int>());
604   EXPECT_EQ(7, params.GetParam<int>());
605   EXPECT_EQ(8, params.GetParam<int>());
606   EXPECT_EQ(9, params.GetParam<int>());
607 
608   EXPECT_DOUBLE_EQ(0.0, params.GetParam<double>());
609   EXPECT_DOUBLE_EQ(1.1, params.GetParam<double>());
610   EXPECT_DOUBLE_EQ(2.2, params.GetParam<double>());
611   EXPECT_DOUBLE_EQ(3.3, params.GetParam<double>());
612   EXPECT_DOUBLE_EQ(4.4, params.GetParam<double>());
613   EXPECT_DOUBLE_EQ(5.5, params.GetParam<double>());
614   EXPECT_DOUBLE_EQ(6.6, params.GetParam<double>());
615   EXPECT_DOUBLE_EQ(7.7, params.GetParam<double>());
616   EXPECT_DOUBLE_EQ(8.8, params.GetParam<double>());
617   EXPECT_DOUBLE_EQ(9.9, params.GetParam<double>());
618 }
619 
620 }  // namespace
621 
622 }  // namespace berberis
623