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