t_ptrace_wait.h revision 1.4 1 1.4 kamil /* $NetBSD: t_ptrace_wait.h,v 1.4 2018/05/13 23:01:25 kamil Exp $ */
2 1.1 kamil
3 1.1 kamil /*-
4 1.1 kamil * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 1.1 kamil * All rights reserved.
6 1.1 kamil *
7 1.1 kamil * Redistribution and use in source and binary forms, with or without
8 1.1 kamil * modification, are permitted provided that the following conditions
9 1.1 kamil * are met:
10 1.1 kamil * 1. Redistributions of source code must retain the above copyright
11 1.1 kamil * notice, this list of conditions and the following disclaimer.
12 1.1 kamil * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 kamil * notice, this list of conditions and the following disclaimer in the
14 1.1 kamil * documentation and/or other materials provided with the distribution.
15 1.1 kamil *
16 1.1 kamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 kamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 kamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 kamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 kamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 kamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 kamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 kamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 kamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 kamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 kamil * POSSIBILITY OF SUCH DAMAGE.
27 1.1 kamil */
28 1.1 kamil
29 1.1 kamil /* Detect plain wait(2) use-case */
30 1.1 kamil #if !defined(TWAIT_WAITPID) && \
31 1.1 kamil !defined(TWAIT_WAITID) && \
32 1.1 kamil !defined(TWAIT_WAIT3) && \
33 1.1 kamil !defined(TWAIT_WAIT4) && \
34 1.1 kamil !defined(TWAIT_WAIT6)
35 1.1 kamil #define TWAIT_WAIT
36 1.1 kamil #endif
37 1.1 kamil
38 1.1 kamil /*
39 1.1 kamil * There are two classes of wait(2)-like functions:
40 1.1 kamil * - wait4(2)-like accepting pid_t, optional options parameter, struct rusage*
41 1.1 kamil * - wait6(2)-like accepting idtype_t, id_t, struct wrusage, mandatory options
42 1.1 kamil *
43 1.1 kamil * The TWAIT_FNAME value is to be used for convenience in debug messages.
44 1.1 kamil *
45 1.1 kamil * The TWAIT_GENERIC() macro is designed to reuse the same unmodified
46 1.1 kamil * code with as many wait(2)-like functions as possible.
47 1.1 kamil *
48 1.1 kamil * In a common use-case wait4(2) and wait6(2)-like function can work the almost
49 1.1 kamil * the same way, however there are few important differences:
50 1.1 kamil * wait6(2) must specify P_PID for idtype to match wpid from wait4(2).
51 1.1 kamil * To behave like wait4(2), wait6(2) the 'options' to wait must include
52 1.1 kamil * WEXITED|WTRUNCATED.
53 1.1 kamil *
54 1.1 kamil * There are two helper macros (they purpose it to mach more than one
55 1.1 kamil * wait(2)-like function):
56 1.1 kamil * The TWAIT_HAVE_STATUS - specifies whether a function can retrieve
57 1.1 kamil * status (as integer value).
58 1.1 kamil * The TWAIT_HAVE_PID - specifies whether a function can request
59 1.1 kamil * exact process identifier
60 1.1 kamil * The TWAIT_HAVE_RUSAGE - specifies whether a function can request
61 1.1 kamil * the struct rusage value
62 1.1 kamil *
63 1.1 kamil */
64 1.1 kamil
65 1.1 kamil #if defined(TWAIT_WAIT)
66 1.1 kamil # define TWAIT_FNAME "wait"
67 1.1 kamil # define TWAIT_WAIT4TYPE(a,b,c,d) wait((b))
68 1.1 kamil # define TWAIT_GENERIC(a,b,c) wait((b))
69 1.1 kamil # define TWAIT_HAVE_STATUS 1
70 1.1 kamil #elif defined(TWAIT_WAITPID)
71 1.1 kamil # define TWAIT_FNAME "waitpid"
72 1.1 kamil # define TWAIT_WAIT4TYPE(a,b,c,d) waitpid((a),(b),(c))
73 1.1 kamil # define TWAIT_GENERIC(a,b,c) waitpid((a),(b),(c))
74 1.1 kamil # define TWAIT_HAVE_PID 1
75 1.1 kamil # define TWAIT_HAVE_STATUS 1
76 1.1 kamil #elif defined(TWAIT_WAITID)
77 1.1 kamil # define TWAIT_FNAME "waitid"
78 1.1 kamil # define TWAIT_GENERIC(a,b,c) \
79 1.1 kamil waitid(P_PID,(a),NULL,(c)|WEXITED|WTRAPPED)
80 1.1 kamil # define TWAIT_WAIT6TYPE(a,b,c,d,e,f) waitid((a),(b),(f),(d))
81 1.1 kamil # define TWAIT_HAVE_PID 1
82 1.1 kamil #elif defined(TWAIT_WAIT3)
83 1.1 kamil # define TWAIT_FNAME "wait3"
84 1.1 kamil # define TWAIT_WAIT4TYPE(a,b,c,d) wait3((b),(c),(d))
85 1.1 kamil # define TWAIT_GENERIC(a,b,c) wait3((b),(c),NULL)
86 1.1 kamil # define TWAIT_HAVE_STATUS 1
87 1.1 kamil # define TWAIT_HAVE_RUSAGE 1
88 1.1 kamil #elif defined(TWAIT_WAIT4)
89 1.1 kamil # define TWAIT_FNAME "wait4"
90 1.1 kamil # define TWAIT_WAIT4TYPE(a,b,c,d) wait4((a),(b),(c),(d))
91 1.1 kamil # define TWAIT_GENERIC(a,b,c) wait4((a),(b),(c),NULL)
92 1.1 kamil # define TWAIT_HAVE_PID 1
93 1.1 kamil # define TWAIT_HAVE_STATUS 1
94 1.1 kamil # define TWAIT_HAVE_RUSAGE 1
95 1.1 kamil #elif defined(TWAIT_WAIT6)
96 1.1 kamil # define TWAIT_FNAME "wait6"
97 1.1 kamil # define TWAIT_WAIT6TYPE(a,b,c,d,e,f) wait6((a),(b),(c),(d),(e),(f))
98 1.1 kamil # define TWAIT_GENERIC(a,b,c) \
99 1.1 kamil wait6(P_PID,(a),(b),(c)|WEXITED|WTRAPPED,NULL,NULL)
100 1.1 kamil # define TWAIT_HAVE_PID 1
101 1.1 kamil # define TWAIT_HAVE_STATUS 1
102 1.1 kamil #endif
103 1.1 kamil
104 1.1 kamil /*
105 1.1 kamil * There are 3 groups of tests:
106 1.1 kamil * - TWAIT_GENERIC() (wait, wait2, waitpid, wait3, wait4, wait6)
107 1.1 kamil * - TWAIT_WAIT4TYPE() (wait2, waitpid, wait3, wait4)
108 1.1 kamil * - TWAIT_WAIT6TYPE() (waitid, wait6)
109 1.1 kamil *
110 1.1 kamil * Tests only in the above categories are allowed. However some tests are not
111 1.1 kamil * possible in the context requested functionality to be verified, therefore
112 1.1 kamil * there are helper macros:
113 1.1 kamil * - TWAIT_HAVE_PID (wait2, waitpid, waitid, wait4, wait6)
114 1.1 kamil * - TWAIT_HAVE_STATUS (wait, wait2, waitpid, wait3, wait4, wait6)
115 1.1 kamil * - TWAIT_HAVE_RUSAGE (wait3, wait4)
116 1.1 kamil * - TWAIT_HAVE_RETPID (wait, wait2, waitpid, wait3, wait4, wait6)
117 1.1 kamil *
118 1.1 kamil * If there is an intention to test e.g. wait6(2) specific features in the
119 1.1 kamil * ptrace(2) context, find the most matching group and with #ifdefs reduce
120 1.1 kamil * functionality of less featured than wait6(2) interface (TWAIT_WAIT6TYPE).
121 1.1 kamil *
122 1.1 kamil * For clarity never use negative preprocessor checks, like:
123 1.1 kamil * #if !defined(TWAIT_WAIT4)
124 1.1 kamil * always refer to checks for positive values.
125 1.1 kamil */
126 1.1 kamil
127 1.1 kamil #define TEST_REQUIRE_EQ(x, y) \
128 1.1 kamil do { \
129 1.1 kamil uintmax_t vx = (x); \
130 1.1 kamil uintmax_t vy = (y); \
131 1.1 kamil int ret = vx == vy; \
132 1.1 kamil if (!ret) \
133 1.1 kamil ATF_REQUIRE_EQ_MSG(vx, vy, "%s(%ju) == %s(%ju)", \
134 1.1 kamil #x, vx, #y, vy); \
135 1.1 kamil } while (/*CONSTCOND*/0)
136 1.1 kamil
137 1.1 kamil /*
138 1.1 kamil * A child process cannot call atf functions and expect them to magically
139 1.1 kamil * work like in the parent.
140 1.1 kamil * The printf(3) messaging from a child will not work out of the box as well
141 1.1 kamil * without estabilishing a communication protocol with its parent. To not
142 1.1 kamil * overcomplicate the tests - do not log from a child and use err(3)/errx(3)
143 1.1 kamil * wrapped with FORKEE_ASSERT()/FORKEE_ASSERTX() as that is guaranteed to work.
144 1.1 kamil */
145 1.1 kamil #define FORKEE_ASSERT_EQ(x, y) \
146 1.1 kamil do { \
147 1.1 kamil uintmax_t vx = (x); \
148 1.1 kamil uintmax_t vy = (y); \
149 1.1 kamil int ret = vx == vy; \
150 1.1 kamil if (!ret) \
151 1.1 kamil errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: " \
152 1.1 kamil "%s(%ju) == %s(%ju)", __FILE__, __LINE__, __func__, \
153 1.1 kamil #x, vx, #y, vy); \
154 1.1 kamil } while (/*CONSTCOND*/0)
155 1.1 kamil
156 1.1 kamil #define FORKEE_ASSERTX(x) \
157 1.1 kamil do { \
158 1.1 kamil int ret = (x); \
159 1.1 kamil if (!ret) \
160 1.1 kamil errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",\
161 1.1 kamil __FILE__, __LINE__, __func__, #x); \
162 1.1 kamil } while (/*CONSTCOND*/0)
163 1.1 kamil
164 1.1 kamil #define FORKEE_ASSERT(x) \
165 1.1 kamil do { \
166 1.1 kamil int ret = (x); \
167 1.1 kamil if (!ret) \
168 1.1 kamil err(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",\
169 1.1 kamil __FILE__, __LINE__, __func__, #x); \
170 1.1 kamil } while (/*CONSTCOND*/0)
171 1.1 kamil
172 1.1 kamil /*
173 1.1 kamil * Simplify logic for functions using general purpose registers add HAVE_GPREGS
174 1.1 kamil *
175 1.1 kamil * For platforms that do not implement all needed calls for simplicity assume
176 1.1 kamil * that they are unsupported at all.
177 1.1 kamil */
178 1.1 kamil #if defined(PT_GETREGS) \
179 1.1 kamil && defined(PT_SETREGS) \
180 1.1 kamil && defined(PTRACE_REG_PC) \
181 1.1 kamil && defined(PTRACE_REG_SET_PC) \
182 1.1 kamil && defined(PTRACE_REG_SP) \
183 1.1 kamil && defined(PTRACE_REG_INTRV)
184 1.1 kamil #define HAVE_GPREGS
185 1.1 kamil #endif
186 1.1 kamil
187 1.1 kamil /* Add guards for floating point registers */
188 1.1 kamil #if defined(PT_GETFPREGS) \
189 1.1 kamil && defined(PT_SETFPREGS)
190 1.1 kamil #define HAVE_FPREGS
191 1.1 kamil #endif
192 1.1 kamil
193 1.1 kamil /* Add guards for cpu debug registers */
194 1.1 kamil #if defined(PT_GETDBREGS) \
195 1.1 kamil && defined(PT_SETDBREGS)
196 1.1 kamil #define HAVE_DBREGS
197 1.1 kamil #endif
198 1.1 kamil
199 1.1 kamil /*
200 1.1 kamil * If waitid(2) returns because one or more processes have a state change to
201 1.1 kamil * report, 0 is returned. If an error is detected, a value of -1 is returned
202 1.1 kamil * and errno is set to indicate the error. If WNOHANG is specified and there
203 1.1 kamil * are no stopped, continued or exited children, 0 is returned.
204 1.1 kamil */
205 1.1 kamil #if defined(TWAIT_WAITID)
206 1.1 kamil #define TWAIT_REQUIRE_SUCCESS(a,b) TEST_REQUIRE_EQ((a), 0)
207 1.1 kamil #define TWAIT_REQUIRE_FAILURE(a,b) ATF_REQUIRE_ERRNO((a),(b) == -1)
208 1.1 kamil #define FORKEE_REQUIRE_SUCCESS(a,b) FORKEE_ASSERT_EQ(a, 0)
209 1.1 kamil #define FORKEE_REQUIRE_FAILURE(a,b) \
210 1.1 kamil FORKEE_ASSERTX(((a) == errno) && ((b) == -1))
211 1.1 kamil #else
212 1.1 kamil #define TWAIT_REQUIRE_SUCCESS(a,b) TEST_REQUIRE_EQ((a), (b))
213 1.1 kamil #define TWAIT_REQUIRE_FAILURE(a,b) ATF_REQUIRE_ERRNO((a),(b) == -1)
214 1.1 kamil #define FORKEE_REQUIRE_SUCCESS(a,b) FORKEE_ASSERT_EQ(a, b)
215 1.1 kamil #define FORKEE_REQUIRE_FAILURE(a,b) \
216 1.1 kamil FORKEE_ASSERTX(((a) == errno) && ((b) == -1))
217 1.1 kamil #endif
218 1.1 kamil
219 1.1 kamil /*
220 1.1 kamil * Helper tools to verify whether status reports exited value
221 1.1 kamil */
222 1.1 kamil #if TWAIT_HAVE_STATUS
223 1.1 kamil static void __used
224 1.1 kamil validate_status_exited(int status, int expected)
225 1.1 kamil {
226 1.1 kamil ATF_REQUIRE_MSG(WIFEXITED(status), "Reported !exited process");
227 1.1 kamil ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process");
228 1.1 kamil ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process");
229 1.1 kamil ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process");
230 1.1 kamil
231 1.1 kamil ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), expected,
232 1.1 kamil "The process has exited with invalid value %d != %d",
233 1.1 kamil WEXITSTATUS(status), expected);
234 1.1 kamil }
235 1.1 kamil
236 1.1 kamil static void __used
237 1.1 kamil forkee_status_exited(int status, int expected)
238 1.1 kamil {
239 1.1 kamil FORKEE_ASSERTX(WIFEXITED(status));
240 1.1 kamil FORKEE_ASSERTX(!WIFCONTINUED(status));
241 1.1 kamil FORKEE_ASSERTX(!WIFSIGNALED(status));
242 1.1 kamil FORKEE_ASSERTX(!WIFSTOPPED(status));
243 1.1 kamil
244 1.1 kamil FORKEE_ASSERT_EQ(WEXITSTATUS(status), expected);
245 1.1 kamil }
246 1.1 kamil
247 1.1 kamil static void __used
248 1.1 kamil validate_status_continued(int status)
249 1.1 kamil {
250 1.1 kamil ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process");
251 1.1 kamil ATF_REQUIRE_MSG(WIFCONTINUED(status), "Reported !continued process");
252 1.1 kamil ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process");
253 1.1 kamil ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process");
254 1.1 kamil }
255 1.1 kamil
256 1.1 kamil static void __used
257 1.1 kamil forkee_status_continued(int status)
258 1.1 kamil {
259 1.1 kamil FORKEE_ASSERTX(!WIFEXITED(status));
260 1.1 kamil FORKEE_ASSERTX(WIFCONTINUED(status));
261 1.1 kamil FORKEE_ASSERTX(!WIFSIGNALED(status));
262 1.1 kamil FORKEE_ASSERTX(!WIFSTOPPED(status));
263 1.1 kamil }
264 1.1 kamil
265 1.1 kamil static void __used
266 1.1 kamil validate_status_signaled(int status, int expected_termsig, int expected_core)
267 1.1 kamil {
268 1.1 kamil ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process");
269 1.1 kamil ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process");
270 1.1 kamil ATF_REQUIRE_MSG(WIFSIGNALED(status), "Reported !signaled process");
271 1.1 kamil ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process");
272 1.1 kamil
273 1.1 kamil ATF_REQUIRE_EQ_MSG(WTERMSIG(status), expected_termsig,
274 1.1 kamil "Unexpected signal received");
275 1.1 kamil
276 1.3 kamil ATF_REQUIRE_EQ_MSG(!!WCOREDUMP(status), expected_core,
277 1.1 kamil "Unexpectedly core file %s generated", expected_core ? "not" : "");
278 1.1 kamil }
279 1.1 kamil
280 1.1 kamil static void __used
281 1.1 kamil forkee_status_signaled(int status, int expected_termsig, int expected_core)
282 1.1 kamil {
283 1.1 kamil FORKEE_ASSERTX(!WIFEXITED(status));
284 1.1 kamil FORKEE_ASSERTX(!WIFCONTINUED(status));
285 1.1 kamil FORKEE_ASSERTX(WIFSIGNALED(status));
286 1.1 kamil FORKEE_ASSERTX(!WIFSTOPPED(status));
287 1.1 kamil
288 1.1 kamil FORKEE_ASSERT_EQ(WTERMSIG(status), expected_termsig);
289 1.3 kamil FORKEE_ASSERT_EQ(!!WCOREDUMP(status), expected_core);
290 1.1 kamil }
291 1.1 kamil
292 1.1 kamil static void __used
293 1.1 kamil validate_status_stopped(int status, int expected)
294 1.1 kamil {
295 1.1 kamil ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process");
296 1.1 kamil ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process");
297 1.1 kamil ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process");
298 1.1 kamil ATF_REQUIRE_MSG(WIFSTOPPED(status), "Reported !stopped process");
299 1.1 kamil
300 1.1 kamil char st[128], ex[128];
301 1.1 kamil strlcpy(st, strsignal(WSTOPSIG(status)), sizeof(st));
302 1.1 kamil strlcpy(ex, strsignal(expected), sizeof(ex));
303 1.1 kamil
304 1.1 kamil ATF_REQUIRE_EQ_MSG(WSTOPSIG(status), expected,
305 1.1 kamil "Unexpected stop signal received [%s] != [%s]", st, ex);
306 1.1 kamil }
307 1.1 kamil
308 1.1 kamil static void __used
309 1.1 kamil forkee_status_stopped(int status, int expected)
310 1.1 kamil {
311 1.1 kamil FORKEE_ASSERTX(!WIFEXITED(status));
312 1.1 kamil FORKEE_ASSERTX(!WIFCONTINUED(status));
313 1.1 kamil FORKEE_ASSERTX(!WIFSIGNALED(status));
314 1.1 kamil FORKEE_ASSERTX(WIFSTOPPED(status));
315 1.1 kamil
316 1.1 kamil FORKEE_ASSERT_EQ(WSTOPSIG(status), expected);
317 1.1 kamil }
318 1.1 kamil #else
319 1.1 kamil #define validate_status_exited(a,b)
320 1.1 kamil #define forkee_status_exited(a,b)
321 1.1 kamil #define validate_status_continued(a,b)
322 1.1 kamil #define forkee_status_continued(a,b)
323 1.1 kamil #define validate_status_signaled(a,b,c)
324 1.1 kamil #define forkee_status_signaled(a,b,c)
325 1.1 kamil #define validate_status_stopped(a,b)
326 1.1 kamil #define forkee_status_stopped(a,b)
327 1.1 kamil #endif
328 1.1 kamil
329 1.1 kamil /* This function is currently designed to be run in the main/parent process */
330 1.1 kamil static void __used
331 1.2 kamil await_zombie_raw(pid_t process, useconds_t ms)
332 1.1 kamil {
333 1.1 kamil struct kinfo_proc2 p;
334 1.1 kamil size_t len = sizeof(p);
335 1.1 kamil
336 1.1 kamil const int name[] = {
337 1.1 kamil [0] = CTL_KERN,
338 1.1 kamil [1] = KERN_PROC2,
339 1.1 kamil [2] = KERN_PROC_PID,
340 1.1 kamil [3] = process,
341 1.1 kamil [4] = sizeof(p),
342 1.1 kamil [5] = 1
343 1.1 kamil };
344 1.1 kamil
345 1.1 kamil const size_t namelen = __arraycount(name);
346 1.1 kamil
347 1.1 kamil /* Await the process becoming a zombie */
348 1.1 kamil while(1) {
349 1.1 kamil ATF_REQUIRE(sysctl(name, namelen, &p, &len, NULL, 0) == 0);
350 1.1 kamil
351 1.1 kamil if (p.p_stat == LSZOMB)
352 1.1 kamil break;
353 1.1 kamil
354 1.2 kamil if (ms > 0) {
355 1.2 kamil ATF_REQUIRE(usleep(ms) == 0);
356 1.2 kamil }
357 1.1 kamil }
358 1.1 kamil }
359 1.1 kamil
360 1.2 kamil static void __used
361 1.2 kamil await_zombie(pid_t process)
362 1.2 kamil {
363 1.2 kamil
364 1.2 kamil await_zombie_raw(process, 1000);
365 1.2 kamil }
366 1.2 kamil
367 1.1 kamil /* Happy number sequence -- this function is used to just consume cpu cycles */
368 1.1 kamil #define HAPPY_NUMBER 1
369 1.1 kamil
370 1.1 kamil /* If n is not happy then its sequence ends in the cycle:
371 1.1 kamil * 4, 16, 37, 58, 89, 145, 42, 20, 4, ... */
372 1.1 kamil #define SAD_NUMBER 4
373 1.1 kamil
374 1.1 kamil /* Calculate the sum of the squares of the digits of n */
375 1.1 kamil static unsigned __used
376 1.1 kamil dsum(unsigned n)
377 1.1 kamil {
378 1.1 kamil unsigned sum, x;
379 1.1 kamil for (sum = 0; n; n /= 10) {
380 1.1 kamil x = n % 10;
381 1.1 kamil sum += x * x;
382 1.1 kamil }
383 1.1 kamil return sum;
384 1.1 kamil }
385 1.1 kamil
386 1.1 kamil /*
387 1.1 kamil * XXX: Disabled optimization is required to make tests for hardware assisted
388 1.1 kamil * traps in .text functional
389 1.1 kamil *
390 1.1 kamil * Tested with GCC 5.4 on NetBSD 7.99.47 amd64
391 1.1 kamil */
392 1.1 kamil static int __used
393 1.1 kamil #ifdef __clang__
394 1.1 kamil __attribute__((__optnone__))
395 1.1 kamil #else
396 1.1 kamil __attribute__((__optimize__("O0")))
397 1.1 kamil #endif
398 1.1 kamil check_happy(unsigned n)
399 1.1 kamil {
400 1.1 kamil for (;;) {
401 1.1 kamil unsigned total = dsum(n);
402 1.1 kamil
403 1.1 kamil if (total == HAPPY_NUMBER)
404 1.1 kamil return 1;
405 1.1 kamil if (total == SAD_NUMBER)
406 1.1 kamil return 0;
407 1.1 kamil
408 1.1 kamil n = total;
409 1.1 kamil }
410 1.1 kamil }
411 1.1 kamil
412 1.4 kamil #if defined(HAVE_DBREGS)
413 1.4 kamil static bool
414 1.4 kamil can_we_set_dbregs(void)
415 1.4 kamil {
416 1.4 kamil static long euid = -1;
417 1.4 kamil static int user_set_dbregs = -1;
418 1.4 kamil size_t user_set_dbregs_len = sizeof(user_set_dbregs);
419 1.4 kamil
420 1.4 kamil if (euid == -1)
421 1.4 kamil euid = geteuid();
422 1.4 kamil
423 1.4 kamil if (euid == 0)
424 1.4 kamil return true;
425 1.4 kamil
426 1.4 kamil if (user_set_dbregs == -1) {
427 1.4 kamil if (sysctlbyname("security.models.extensions.user_set_dbregs",
428 1.4 kamil &user_set_dbregs, &user_set_dbregs_len, NULL, 0)
429 1.4 kamil == -1) {
430 1.4 kamil return false;
431 1.4 kamil }
432 1.4 kamil }
433 1.4 kamil
434 1.4 kamil if (user_set_dbregs > 0)
435 1.4 kamil return true;
436 1.4 kamil else
437 1.4 kamil return false;
438 1.4 kamil }
439 1.4 kamil #endif
440 1.4 kamil
441 1.1 kamil #if defined(TWAIT_HAVE_PID)
442 1.1 kamil #define ATF_TP_ADD_TC_HAVE_PID(a,b) ATF_TP_ADD_TC(a,b)
443 1.1 kamil #else
444 1.1 kamil #define ATF_TP_ADD_TC_HAVE_PID(a,b)
445 1.1 kamil #endif
446 1.1 kamil
447 1.1 kamil #if defined(HAVE_GPREGS)
448 1.1 kamil #define ATF_TP_ADD_TC_HAVE_GPREGS(a,b) ATF_TP_ADD_TC(a,b)
449 1.1 kamil #else
450 1.1 kamil #define ATF_TP_ADD_TC_HAVE_GPREGS(a,b)
451 1.1 kamil #endif
452 1.1 kamil
453 1.1 kamil #if defined(HAVE_FPREGS)
454 1.1 kamil #define ATF_TP_ADD_TC_HAVE_FPREGS(a,b) ATF_TP_ADD_TC(a,b)
455 1.1 kamil #else
456 1.1 kamil #define ATF_TP_ADD_TC_HAVE_FPREGS(a,b)
457 1.1 kamil #endif
458 1.1 kamil
459 1.1 kamil #if defined(HAVE_DBREGS)
460 1.1 kamil #define ATF_TP_ADD_TC_HAVE_DBREGS(a,b) ATF_TP_ADD_TC(a,b)
461 1.1 kamil #else
462 1.1 kamil #define ATF_TP_ADD_TC_HAVE_DBREGS(a,b)
463 1.1 kamil #endif
464 1.1 kamil
465 1.1 kamil #if defined(PT_STEP)
466 1.1 kamil #define ATF_TP_ADD_TC_PT_STEP(a,b) ATF_TP_ADD_TC(a,b)
467 1.1 kamil #else
468 1.1 kamil #define ATF_TP_ADD_TC_PT_STEP(a,b)
469 1.1 kamil #endif
470