1 /*
2 * Check decoding of "old mmap" edition of mmap syscall.
3 *
4 * Copyright (c) 2016 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 /*
15 * On s390x and m68k, this is the mmap syscall used by glibc, so,
16 * from one side, it's already covered by another test, and, from another side,
17 * it would require additional efforts to filter out mmap calls made by glibc.
18 */
19
20 #if defined __NR_mmap \
21 && (defined __arm__ || defined __i386__ || defined __m68k__ \
22 || defined __s390__ || defined __s390x__) \
23 && (defined PATH_TRACING || !(defined __s390x__ || defined __m68k__))
24
25 # include <errno.h>
26 # include <stdio.h>
27 # include <string.h>
28 # include <sys/mman.h>
29 # include <unistd.h>
30 # include "xmalloc.h"
31
32 # ifndef TEST_FD
33 # define TEST_FD -2LU
34 # endif
35
36 int
37 main(void)
38 {
39 long rc = syscall(__NR_mmap, 0);
40 const bool implemented = rc != -1 || errno != ENOSYS;
41 # ifndef PATH_TRACING
42 printf("mmap(NULL) = %s\n", sprintrc(rc));
43 # endif
44
45 const unsigned long args1_c[6] = {
46 (unsigned long) 0xbadc0deddeadbeefULL, /* addr */
47 (unsigned long) 0xdeefacedfacefeedULL, /* len */
48 PROT_READ|PROT_EXEC, /* prot */
49 MAP_FILE|MAP_FIXED, /* flags */
50 TEST_FD, /* fd */
51 (unsigned long) 0xdecaffedbadc0dedULL /* offset */
52 };
53 const unsigned long page_size = get_page_size();
54 const unsigned long args2_c[6] = {
55 0,
56 page_size,
57 PROT_READ|PROT_WRITE,
58 MAP_PRIVATE|MAP_ANONYMOUS,
59 -1LU,
60 (unsigned long) 0xda7a1057faced000ULL & -page_size
61 };
62 void *args = tail_memdup(args1_c, sizeof(args1_c));
63
64 rc = syscall(__NR_mmap, args);
65 # if XLAT_RAW
66 printf("mmap(%#lx, %lu, %#x, %#x, %d, %#lx) = %s\n",
67 args1_c[0], args1_c[1], PROT_READ|PROT_EXEC, MAP_FILE | MAP_FIXED,
68 (int) args1_c[4], args1_c[5], sprintrc(rc));
69 # elif XLAT_VERBOSE
70 printf("mmap(%#lx, %lu, %#x /* PROT_READ|PROT_EXEC */"
71 ", %#x /* MAP_FILE|MAP_FIXED */, %d, %#lx) = %s\n",
72 args1_c[0], args1_c[1], PROT_READ|PROT_EXEC, MAP_FILE | MAP_FIXED,
73 (int) args1_c[4], args1_c[5], sprintrc(rc));
74 # else
75 printf("mmap(%#lx, %lu, PROT_READ|PROT_EXEC, MAP_FILE|MAP_FIXED"
76 ", %d, %#lx) = %s\n",
77 args1_c[0], args1_c[1], (int) args1_c[4], args1_c[5],
78 sprintrc(rc));
79 # endif
80
81 memcpy(args, args2_c, sizeof(args2_c));
82 rc = syscall(__NR_mmap, args);
83 # ifndef PATH_TRACING
84 const char *errstr;
85 if (implemented) {
86 char *str = xasprintf("%#lx", rc);
87 errstr = str;
88 } else {
89 errstr = sprintrc(rc);
90 }
91 # if XLAT_RAW
92 printf("mmap(NULL, %lu, %#x, %#x, %d, %#lx) = %s\n",
93 args2_c[1], PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
94 (int) args2_c[4], args2_c[5], errstr);
95 # elif XLAT_VERBOSE
96 printf("mmap(NULL, %lu, %#x /* PROT_READ|PROT_WRITE */"
97 ", %#x /* MAP_PRIVATE|MAP_ANONYMOUS */, %d, %#lx) = %s\n",
98 args2_c[1], PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
99 (int) args2_c[4], args2_c[5], errstr);
100 # else
101 printf("mmap(NULL, %lu, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS"
102 ", %d, %#lx) = %s\n",
103 args2_c[1], (int) args2_c[4], args2_c[5], errstr);
104 # endif
105 # endif
106
107 void *addr = (void *) rc;
108 if (implemented && mprotect(addr, page_size, PROT_NONE))
109 perror_msg_and_fail("mprotect(%p, %lu, PROT_NONE)",
110 addr, page_size);
111
112 puts("+++ exited with 0 +++");
113 return 0;
114 }
115
116 #else
117
118 SKIP_MAIN_UNDEFINED("defined __NR_mmap "
119 "&& (defined __arm__ || defined __i386__ || defined __m68k__ "
120 "|| defined __s390__ || defined __s390x__) "
121 "&& (defined PATH_TRACING || !(defined __s390x__ || defined __m68k__))")
122
123 #endif