1 /*
2 * Check decoding of socketcall syscall.
3 *
4 * Copyright (c) 2016-2018 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2016-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13
14 #if defined __NR_socketcall && !defined __ARM_EABI__
15
16 # include <assert.h>
17 # include <stdio.h>
18 # include <unistd.h>
19
20 # include "xlat.h"
21 # include "xlat/socketcalls.h"
22
23 static const char *
24 xlookup_uint(const struct xlat *xlat, const unsigned int val)
25 {
26 for (size_t i = 0; i < xlat->size; i++)
27 if (xlat->data[i].val == val)
28 return xlat->data[i].str;
29 return NULL;
30 }
31
32 static const int sc_min = 1, sc_max = 20;
33 static void *efault;
34
35 static void
36 test_socketcall(const int i, const void *const addr)
37 {
38 const unsigned long call =
39 (unsigned long) 0xfacefeed00000000ULL | (unsigned int) i;
40
41 long rc = syscall(__NR_socketcall, call, addr);
42
43 if (i < sc_min || i > sc_max) {
44 printf("socketcall(%d, %p) = %ld %s (%m)\n",
45 (int) call, addr, rc, errno2name());
46 } else if (addr == efault) {
47 const char *const str = xlookup_uint(socketcalls, i);
48 assert(str);
49 printf("socketcall(%s, %p) = %ld %s (%m)\n",
50 str, addr, rc, errno2name());
51 }
52 }
53 int
54 main(void)
55 {
56 assert(0 == socketcalls->data[0].val);
57 assert((unsigned) sc_max == socketcalls->data[socketcalls->size - 1].val);
58
59 const unsigned long *const args = tail_alloc(sizeof(*args) * 6);
60 efault = tail_alloc(1) + 1;
61
62 for (int i = sc_min - 3; i <= sc_max + 3; ++i) {
63 test_socketcall(i, efault);
64 test_socketcall(i, args);
65 }
66
67 puts("+++ exited with 0 +++");
68 return 0;
69 }
70
71 #else
72
73 SKIP_MAIN_UNDEFINED("__NR_socketcall && !__ARM_EABI__")
74
75 #endif