]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/libMicro/mprotect.c
xnu-3248.60.10.tar.gz
[apple/xnu.git] / tools / tests / libMicro / mprotect.c
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms
5 * of the Common Development and Distribution License
6 * (the "License"). You may not use this file except
7 * in compliance with the License.
8 *
9 * You can obtain a copy of the license at
10 * src/OPENSOLARIS.LICENSE
11 * or http://www.opensolaris.org/os/licensing.
12 * See the License for the specific language governing
13 * permissions and limitations under the License.
14 *
15 * When distributing Covered Code, include this CDDL
16 * HEADER in each file and include the License file at
17 * usr/src/OPENSOLARIS.LICENSE. If applicable,
18 * add the following below this CDDL HEADER, with the
19 * fields enclosed by brackets "[]" replaced with your
20 * own identifying information: Portions Copyright [yyyy]
21 * [name of copyright owner]
22 *
23 * CDDL HEADER END
24 */
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <sys/mman.h>
35 #include <fcntl.h>
36 #include <strings.h>
37
38 #include "libmicro.h"
39
40 typedef volatile char vchar_t;
41
42 typedef struct {
43 int ts_batch;
44 int ts_res;
45 } tsd_t;
46
47 #define DEFF "/dev/zero"
48 #define DEFL 8192
49
50 static char *optf = DEFF;
51 static long long optl = DEFL;
52 static int optr = 0;
53 static int optw = 0;
54 static int opts = 0;
55 static int optt = 0;
56 static int fd = -1;
57 static int anon = 0;
58 static int foo = 0;
59 static vchar_t *seg;
60 static int pagesize;
61
62 int
63 benchmark_init()
64 {
65 lm_tsdsize = sizeof (tsd_t);
66
67 (void) sprintf(lm_optstr, "f:l:rstw");
68
69 (void) sprintf(lm_usage,
70 " [-f file-to-map (default %s)]\n"
71 " [-l mapping-length (default %d)]\n"
72 " [-r] (read a byte from each page)\n"
73 " [-w] (write a byte on each page)\n"
74 " [-s] (use MAP_SHARED)\n"
75 " [-t] (touch each page after restoring permissions)\n"
76 "notes: measures mprotect()\n",
77 DEFF, DEFL);
78
79 (void) sprintf(lm_header, "%8s %5s", "size", "flags");
80
81 return (0);
82 }
83
84 int
85 benchmark_optswitch(int opt, char *optarg)
86 {
87 switch (opt) {
88 case 'f':
89 optf = optarg;
90 anon = strcmp(optf, "MAP_ANON") == 0;
91 break;
92 case 'l':
93 optl = sizetoll(optarg);
94 break;
95 case 'r':
96 optr = 1;
97 break;
98 case 's':
99 opts = 1;
100 break;
101 case 't':
102 optt = 1;
103 break;
104 case 'w':
105 optw = 1;
106 break;
107 default:
108 return (-1);
109 }
110 return (0);
111 }
112
113 int
114 benchmark_initrun()
115 {
116 int flags;
117 int i;
118
119 if (!anon)
120 fd = open(optf, O_RDWR);
121
122 flags = opts ? MAP_SHARED : MAP_PRIVATE;
123 flags |= anon ? MAP_ANON : 0;
124
125 seg = (vchar_t *)mmap(NULL, lm_optB * optl, PROT_READ | PROT_WRITE,
126 flags, anon ? -1 : fd, 0L);
127
128 if (seg == MAP_FAILED) {
129 return (-1);
130 }
131
132 if (optr) {
133 for (i = 0; i < lm_optB * optl; i += 4096) {
134 foo += seg[i];
135 }
136 }
137
138 if (optw) {
139 for (i = 0; i < lm_optB * optl; i += 4096) {
140 seg[i] = 1;
141 }
142 }
143
144 pagesize = getpagesize();
145
146 return (0);
147 }
148
149 int
150 benchmark(void *tsd, result_t *res)
151 {
152 tsd_t *ts = (tsd_t *)tsd;
153 int i;
154 int us;
155 int prot = PROT_NONE;
156 int j, k;
157
158 #if !defined(__APPLE__)
159 us = (getpindex() * lm_optT) + gettindex();
160 #else
161 us = gettsdindex(tsd);
162 #endif /* __APPLE__ */
163
164 for (i = 0; i < lm_optB; i++) {
165 switch ((us + ts->ts_batch + i) % 2) {
166 case 0:
167 prot = PROT_NONE;
168 if (optt) {
169 for (j = k = 0; j < optl; j += pagesize)
170 k += seg[i * optl + j];
171 ts->ts_res += k;
172 }
173 break;
174 default:
175 prot = PROT_READ | PROT_WRITE;
176 break;
177 }
178
179 if (mprotect((void *)&seg[i * optl], optl, prot) == -1) {
180 res->re_errors++;
181 }
182 }
183 res->re_count += lm_optB;
184 ts->ts_batch++;
185
186 return (0);
187 }
188
189 char *
190 benchmark_result()
191 {
192 static char result[256];
193 char flags[6];
194
195 flags[0] = anon ? 'a' : '-';
196 flags[1] = optr ? 'r' : '-';
197 flags[2] = optw ? 'w' : '-';
198 flags[3] = opts ? 's' : '-';
199 flags[4] = optt ? 't' : '-';
200 flags[5] = 0;
201
202 (void) sprintf(result, "%8lld %5s", optl, flags);
203
204 return (result);
205 }