blob: 47d7ad69570579c51cb0650eb1330d00a0eafd55 [file] [log] [blame]
mostang.com!davidm05a91012004-02-14 07:53:31 +00001/* libunwind - a platform-independent unwind library
mostang.com!davidma2a13252004-02-19 08:05:27 +00002 Copyright (C) 2004 Hewlett-Packard Co
mostang.com!davidm05a91012004-02-14 07:53:31 +00003 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
mostang.com!davidma2a13252004-02-19 08:05:27 +000026/* This file tests corner-cases of NaT-bit handling. */
mostang.com!davidm05a91012004-02-14 07:53:31 +000027
hp.com!davidmad73ee32004-02-27 00:59:41 +000028#include <errno.h>
mostang.com!davidm05a91012004-02-14 07:53:31 +000029#include <stdio.h>
30#include <stdlib.h>
hp.com!davidmad73ee32004-02-27 00:59:41 +000031#include <string.h>
mostang.com!davidm05a91012004-02-14 07:53:31 +000032
33#include <libunwind.h>
34
mostang.com!davidm6fbd6392004-05-04 22:16:57 +000035#ifdef HAVE_SYS_UC_ACCESS_H
36# include <sys/uc_access.h>
37#endif
38
39#include "ia64/rse.h"
hp.com!davidmad73ee32004-02-27 00:59:41 +000040
hp.com!davidm77a27f02004-03-19 02:38:39 +000041#define NUM_RUNS 1024
42//#define NUM_RUNS 1
43#define MAX_CHECKS 1024
hp.com!davidm61d42cc2004-03-20 06:27:55 +000044//#define MAX_CHECKS 2
mostang.com!davidm05a91012004-02-14 07:53:31 +000045#define MAX_VALUES_PER_FUNC 4
46
47#define panic(args...) \
hp.com!davidm77a27f02004-03-19 02:38:39 +000048 do { printf (args); ++nerrors; } while (0)
mostang.com!davidm05a91012004-02-14 07:53:31 +000049
mostang.com!davidm05a91012004-02-14 07:53:31 +000050typedef void save_func_t (void *funcs, unsigned long *vals);
51typedef unw_word_t *check_func_t (unw_cursor_t *c, unsigned long *vals);
52
hp.com!davidm77a27f02004-03-19 02:38:39 +000053extern void flushrs (void);
54
mostang.com!davidm05a91012004-02-14 07:53:31 +000055extern save_func_t save_static_to_stacked;
56static check_func_t check_static_to_stacked;
57
mostang.com!davidma2a13252004-02-19 08:05:27 +000058extern save_func_t save_static_to_fr;
59static check_func_t check_static_to_fr;
60
61extern save_func_t save_static_to_br;
62static check_func_t check_static_to_br;
63
64extern save_func_t save_static_to_mem;
65static check_func_t check_static_to_mem;
hp.com!davidm330d2b52004-02-19 01:32:27 +000066
hp.com!davidm61d42cc2004-03-20 06:27:55 +000067extern save_func_t save_static_to_mem2;
68static check_func_t check_static_to_mem2;
69
70extern save_func_t save_static_to_mem3;
71static check_func_t check_static_to_mem3;
72
73extern save_func_t save_static_to_mem4;
74static check_func_t check_static_to_mem4;
75
76extern save_func_t save_static_to_mem5;
77static check_func_t check_static_to_mem5;
78
hp.com!davidmad73ee32004-02-27 00:59:41 +000079extern save_func_t save_static_to_scratch;
80static check_func_t check_static_to_scratch;
81
hp.com!davidm77a27f02004-03-19 02:38:39 +000082extern save_func_t rotate_regs;
83static check_func_t check_rotate_regs;
84
mostang.com!davidm05a91012004-02-14 07:53:31 +000085static int verbose;
86static int nerrors;
87
88static int num_checks;
89static save_func_t *funcs[MAX_CHECKS + 1];
90static check_func_t *checks[MAX_CHECKS];
91static unw_word_t values[MAX_CHECKS*MAX_VALUES_PER_FUNC];
92
93static struct
94 {
95 save_func_t *func;
96 check_func_t *check;
97 }
98all_funcs[] =
99 {
mostang.com!davidm18d33f32004-03-19 08:18:44 +0000100 { save_static_to_stacked, check_static_to_stacked },
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000101 { save_static_to_fr, check_static_to_fr },
102 { save_static_to_br, check_static_to_br },
hp.com!davidm77a27f02004-03-19 02:38:39 +0000103 { save_static_to_mem, check_static_to_mem },
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000104 { save_static_to_mem2, check_static_to_mem2 },
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000105 { save_static_to_mem3, check_static_to_mem3 },
106 { save_static_to_mem4, check_static_to_mem4 },
107 { save_static_to_mem5, check_static_to_mem5 },
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000108 { save_static_to_scratch, check_static_to_scratch },
hp.com!davidm77a27f02004-03-19 02:38:39 +0000109 { rotate_regs, check_rotate_regs },
mostang.com!davidm05a91012004-02-14 07:53:31 +0000110 };
111
hp.com!davidmad73ee32004-02-27 00:59:41 +0000112void
113sighandler (int signal, void *siginfo, void *context)
114{
115 unsigned long *bsp, *arg1;
116 save_func_t **arg0;
117 ucontext_t *uc = context;
hp.com!davidmad73ee32004-02-27 00:59:41 +0000118
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000119#if defined(__linux)
120 {
121 long sof;
122 int sp;
hp.com!davidmad73ee32004-02-27 00:59:41 +0000123
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000124 if (verbose)
125 printf ("sighandler: signal %d sp=%p nat=%08lx pr=%lx\n",
126 signal, &sp, uc->uc_mcontext.sc_nat, uc->uc_mcontext.sc_pr);
127 sof = uc->uc_mcontext.sc_cfm & 0x7f;
mostang.com!davidm2d2129a2004-05-05 01:59:36 +0000128 bsp = (unsigned long *) ia64_rse_skip_regs (uc->uc_mcontext.sc_ar_bsp,
129 -sof);
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000130 }
131#elif defined(__hpux)
132 if (__uc_get_ar (uc, UNW_IA64_AR_BSP - UNW_IA64_AR, &bsp) != 0)
133 {
134 panic ("%s: reading of ar.bsp failed, errno=%d", __FUNCTION__, errno);
135 return;
136 }
137#endif
hp.com!davidm77a27f02004-03-19 02:38:39 +0000138
139 flushrs ();
hp.com!davidmad73ee32004-02-27 00:59:41 +0000140 arg0 = (save_func_t **) *bsp;
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000141 bsp = (unsigned long *) ia64_rse_skip_regs ((uint64_t) bsp, 1);
hp.com!davidmad73ee32004-02-27 00:59:41 +0000142 arg1 = (unsigned long *) *bsp;
143
144 (*arg0[0]) (arg0 + 1, arg1);
145
146 /* skip over the instruction which triggered sighandler() */
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000147#if defined(__linux)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000148 ++uc->uc_mcontext.sc_ip;
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000149#elif defined(HAVE_SYS_UC_ACCESS_H)
150 {
151 unsigned long ip;
152
153 if (__uc_get_ip (uc, &ip) != 0)
154 {
155 panic ("%s: reading of ip failed, errno=%d", __FUNCTION__, errno);
156 return;
157 }
158 if (__uc_set_ip (uc, ip) != 0)
159 {
160 panic ("%s: writing of ip failed, errno=%d", __FUNCTION__, errno);
161 return;
162 }
163 }
164#endif
hp.com!davidmad73ee32004-02-27 00:59:41 +0000165}
166
167static void
168enable_sighandler (void)
169{
170 struct sigaction act;
171
172 memset (&act, 0, sizeof (act));
173 act.sa_handler = (void (*)(int)) sighandler;
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000174 act.sa_flags = SA_SIGINFO | SA_NODEFER;
hp.com!davidmad73ee32004-02-27 00:59:41 +0000175 if (sigaction (SIGSEGV, &act, NULL) < 0)
176 panic ("sigaction: %s\n", strerror (errno));
177}
178
179static void
180disable_sighandler (void)
181{
182 struct sigaction act;
183
184 memset (&act, 0, sizeof (act));
185 act.sa_handler = SIG_DFL;
mostang.com!davidm6fbd6392004-05-04 22:16:57 +0000186 act.sa_flags = SA_SIGINFO | SA_NODEFER;
hp.com!davidmad73ee32004-02-27 00:59:41 +0000187 if (sigaction (SIGSEGV, &act, NULL) < 0)
188 panic ("sigaction: %s\n", strerror (errno));
189}
190
mostang.com!davidm05a91012004-02-14 07:53:31 +0000191static unw_word_t *
192check_static_to_stacked (unw_cursor_t *c, unw_word_t *vals)
193{
194 unw_word_t r[4];
195 unw_word_t nat[4];
196 int i, ret;
197
198 if (verbose)
hp.com!davidm330d2b52004-02-19 01:32:27 +0000199 printf (" %s()\n", __FUNCTION__);
mostang.com!davidm05a91012004-02-14 07:53:31 +0000200
201 vals -= 4;
202
203 for (i = 0; i < 4; ++i)
204 if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000205 panic ("%s: failed to read register r%d, error=%d\n",
mostang.com!davidm05a91012004-02-14 07:53:31 +0000206 __FUNCTION__, 4 + i, ret);
207
208 for (i = 0; i < 4; ++i)
209 if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000210 panic ("%s: failed to read register nat%d, error=%d\n",
mostang.com!davidm05a91012004-02-14 07:53:31 +0000211 __FUNCTION__, 4 + i, ret);
212
213 for (i = 0; i < 4; ++i)
214 {
215 if (verbose)
hp.com!davidm330d2b52004-02-19 01:32:27 +0000216 printf (" r%d = %c%016lx (expected %c%016lx)\n",
mostang.com!davidm05a91012004-02-14 07:53:31 +0000217 4 + i, nat[i] ? '*' : ' ', r[i],
218 (vals[i] & 1) ? '*' : ' ', vals[i]);
219
220 if (vals[i] & 1)
221 {
222 if (!nat[i])
223 panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i);
224 }
225 else
226 {
227 if (nat[i])
228 panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i);
229 if (r[i] != vals[i])
230 panic ("%s: r%d=%lx instead of %lx!\n",
231 __FUNCTION__, 4 + i, r[i], vals[i]);
232 }
233 }
234 return vals;
235}
236
hp.com!davidm330d2b52004-02-19 01:32:27 +0000237static unw_word_t *
mostang.com!davidma2a13252004-02-19 08:05:27 +0000238check_static_to_fr (unw_cursor_t *c, unw_word_t *vals)
hp.com!davidm330d2b52004-02-19 01:32:27 +0000239{
240 unw_word_t r4;
241 unw_word_t nat4;
242 int ret;
243
244 if (verbose)
245 printf (" %s()\n", __FUNCTION__);
246
247 vals -= 1;
248
249 if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000250 panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret);
hp.com!davidm330d2b52004-02-19 01:32:27 +0000251
252 if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000253 panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret);
hp.com!davidm330d2b52004-02-19 01:32:27 +0000254
255 if (verbose)
256 printf (" r4 = %c%016lx (expected %c%016lx)\n",
257 nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]);
258
259 if (vals[0] & 1)
260 {
261 if (!nat4)
262 panic ("%s: r4 not a NaT!\n", __FUNCTION__);
263 }
264 else
265 {
266 if (nat4)
267 panic ("%s: r4 a NaT!\n", __FUNCTION__);
268 if (r4 != vals[0])
269 panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]);
270 }
271 return vals;
272}
273
mostang.com!davidma2a13252004-02-19 08:05:27 +0000274static unw_word_t *
275check_static_to_br (unw_cursor_t *c, unw_word_t *vals)
276{
hp.com!davidm77a27f02004-03-19 02:38:39 +0000277 unw_word_t r4, nat4;
mostang.com!davidma2a13252004-02-19 08:05:27 +0000278 int ret;
279
280 if (verbose)
281 printf (" %s()\n", __FUNCTION__);
282
mostang.com!davidma2a13252004-02-19 08:05:27 +0000283 vals -= 1;
284
285 if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000286 panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret);
mostang.com!davidma2a13252004-02-19 08:05:27 +0000287
288 if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000289 panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret);
mostang.com!davidma2a13252004-02-19 08:05:27 +0000290
291 if (verbose)
292 printf (" r4 = %c%016lx (expected %c%016lx)\n",
293 nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]);
294
295 if (vals[0] & 1)
296 {
297 if (!nat4)
298 panic ("%s: r4 not a NaT!\n", __FUNCTION__);
299 }
300 else
301 {
302 if (nat4)
303 panic ("%s: r4 a NaT!\n", __FUNCTION__);
304 if (r4 != vals[0])
305 panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]);
306 }
307 return vals;
308}
309
310static unw_word_t *
311check_static_to_mem (unw_cursor_t *c, unw_word_t *vals)
312{
313 unw_word_t r5, nat5;
314 int ret;
315
316 if (verbose)
317 printf (" %s()\n", __FUNCTION__);
318
319 vals -= 1;
320
321 if ((ret = unw_get_reg (c, UNW_IA64_GR + 5, &r5)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000322 panic ("%s: failed to read register r5, error=%d\n", __FUNCTION__, ret);
mostang.com!davidma2a13252004-02-19 08:05:27 +0000323
324 if ((ret = unw_get_reg (c, UNW_IA64_NAT + 5, &nat5)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000325 panic ("%s: failed to read register nat5, error=%d\n", __FUNCTION__, ret);
mostang.com!davidma2a13252004-02-19 08:05:27 +0000326
327 if (verbose)
328 printf (" r5 = %c%016lx (expected %c%016lx)\n",
329 nat5 ? '*' : ' ', r5, (vals[0] & 1) ? '*' : ' ', vals[0]);
330
331 if (vals[0] & 1)
332 {
333 if (!nat5)
334 panic ("%s: r5 not a NaT!\n", __FUNCTION__);
335 }
336 else
337 {
338 if (nat5)
339 panic ("%s: r5 a NaT!\n", __FUNCTION__);
340 if (r5 != vals[0])
341 panic ("%s: r5=%lx instead of %lx!\n", __FUNCTION__, r5, vals[0]);
342 }
343 return vals;
344}
345
hp.com!davidmad73ee32004-02-27 00:59:41 +0000346static unw_word_t *
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000347check_static_to_memN (unw_cursor_t *c, unw_word_t *vals, const char *func)
348{
349 unw_word_t r6, nat6;
350 int ret;
351
352 if (verbose)
353 printf (" %s()\n", func);
354
355 vals -= 1;
356
357 if ((ret = unw_get_reg (c, UNW_IA64_GR + 6, &r6)) < 0)
358 panic ("%s: failed to read register r6, error=%d\n", __FUNCTION__, ret);
359
360 if ((ret = unw_get_reg (c, UNW_IA64_NAT + 6, &nat6)) < 0)
361 panic ("%s: failed to read register nat6, error=%d\n", __FUNCTION__, ret);
362
363 if (verbose)
364 printf (" r6 = %c%016lx (expected %c%016lx)\n",
365 nat6 ? '*' : ' ', r6, (vals[0] & 1) ? '*' : ' ', vals[0]);
366
367 if (vals[0] & 1)
368 {
369 if (!nat6)
370 panic ("%s: r6 not a NaT!\n", __FUNCTION__);
371 }
372 else
373 {
374 if (nat6)
375 panic ("%s: r6 a NaT!\n", __FUNCTION__);
376 if (r6 != vals[0])
377 panic ("%s: r6=%lx instead of %lx!\n", __FUNCTION__, r6, vals[0]);
378 }
379 return vals;
380}
381
382static unw_word_t *
383check_static_to_mem2 (unw_cursor_t *c, unw_word_t *vals)
384{
385 return check_static_to_memN (c, vals, __FUNCTION__);
386}
387
388static unw_word_t *
389check_static_to_mem3 (unw_cursor_t *c, unw_word_t *vals)
390{
391 return check_static_to_memN (c, vals, __FUNCTION__);
392}
393
394static unw_word_t *
395check_static_to_mem4 (unw_cursor_t *c, unw_word_t *vals)
396{
397 return check_static_to_memN (c, vals, __FUNCTION__);
398}
399
400static unw_word_t *
401check_static_to_mem5 (unw_cursor_t *c, unw_word_t *vals)
402{
403 return check_static_to_memN (c, vals, __FUNCTION__);
404}
405
406static unw_word_t *
hp.com!davidmad73ee32004-02-27 00:59:41 +0000407check_static_to_scratch (unw_cursor_t *c, unw_word_t *vals)
408{
409 unw_word_t r[4], nat[4];
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000410 unw_fpreg_t f4;
hp.com!davidmad73ee32004-02-27 00:59:41 +0000411 int i, ret;
412
413 if (verbose)
414 printf (" %s()\n", __FUNCTION__);
415
416 vals -= 4;
417
418 while (!unw_is_signal_frame (c))
419 if ((ret = unw_step (c)) < 0)
420 panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n",
421 __FUNCTION__, ret);
422 if ((ret = unw_step (c)) < 0)
423 panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n",
424 __FUNCTION__, ret);
425
426 for (i = 0; i < 4; ++i)
427 if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0)
428 panic ("%s: failed to read register r%d, error=%d\n",
429 __FUNCTION__, 4 + i, ret);
430
431 for (i = 0; i < 4; ++i)
432 if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0)
433 panic ("%s: failed to read register nat%d, error=%d\n",
434 __FUNCTION__, 4 + i, ret);
435
436 for (i = 0; i < 4; ++i)
437 {
438 if (verbose)
439 printf (" r%d = %c%016lx (expected %c%016lx)\n",
440 4 + i, nat[i] ? '*' : ' ', r[i],
441 (vals[i] & 1) ? '*' : ' ', vals[i]);
442
443 if (vals[i] & 1)
444 {
445 if (!nat[i])
446 panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i);
447 }
448 else
449 {
450 if (nat[i])
451 panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i);
452 if (r[i] != vals[i])
453 panic ("%s: r%d=%lx instead of %lx!\n",
454 __FUNCTION__, 4 + i, r[i], vals[i]);
455 }
456 }
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000457 if ((ret = unw_get_fpreg (c, UNW_IA64_FR + 4, &f4)) < 0)
458 panic ("%s: failed to read f4, error=%d\n", __FUNCTION__, ret);
459
460 /* These tests are little-endian specific: */
461 if (nat[0])
462 {
463 if (f4.raw.bits[0] != 0 || f4.raw.bits[1] != 0x1fffe)
464 panic ("%s: f4=%016lx.%016lx instead of NaTVal!\n",
hp.com!davidmd0de2832004-04-23 00:12:51 +0000465 __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0]);
hp.com!davidm61d42cc2004-03-20 06:27:55 +0000466 }
467 else
468 {
469 if (f4.raw.bits[0] != r[0] || f4.raw.bits[1] != 0x1003e)
470 panic ("%s: f4=%016lx.%016lx instead of %lx!\n",
471 __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0], r[0]);
472 }
hp.com!davidmad73ee32004-02-27 00:59:41 +0000473 return vals;
474}
475
hp.com!davidm77a27f02004-03-19 02:38:39 +0000476static unw_word_t *
477check_rotate_regs (unw_cursor_t *c, unw_word_t *vals)
478{
mostang.com!davidm18d33f32004-03-19 08:18:44 +0000479 if (verbose)
480 printf (" %s()\n", __FUNCTION__);
481 return vals - 1;
hp.com!davidm77a27f02004-03-19 02:38:39 +0000482}
483
mostang.com!davidm05a91012004-02-14 07:53:31 +0000484static void
485start_checks (void *funcs, unsigned long *vals)
486{
487 unw_context_t uc;
488 unw_cursor_t c;
489 int i, ret;
490
hp.com!davidmad73ee32004-02-27 00:59:41 +0000491 disable_sighandler ();
492
mostang.com!davidm05a91012004-02-14 07:53:31 +0000493 unw_getcontext (&uc);
494
495 if ((ret = unw_init_local (&c, &uc)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000496 panic ("%s: unw_init_local (ret=%d)\n", __FUNCTION__, ret);
mostang.com!davidm05a91012004-02-14 07:53:31 +0000497
498 if ((ret = unw_step (&c)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000499 panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret);
mostang.com!davidm05a91012004-02-14 07:53:31 +0000500
501 for (i = 0; i < num_checks; ++i)
502 {
hp.com!davidm77a27f02004-03-19 02:38:39 +0000503 vals = (*checks[num_checks - 1 - i]) (&c, vals);
mostang.com!davidm05a91012004-02-14 07:53:31 +0000504
505 if ((ret = unw_step (&c)) < 0)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000506 panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret);
mostang.com!davidm05a91012004-02-14 07:53:31 +0000507 }
508}
509
510static void
511run_check (int test)
512{
513 int index, i;
514
hp.com!davidm77a27f02004-03-19 02:38:39 +0000515 if (test == 1)
516 /* Make first test always go the full depth... */
517 num_checks = MAX_CHECKS;
518 else
519 num_checks = (random () % MAX_CHECKS) + 1;
mostang.com!davidm05a91012004-02-14 07:53:31 +0000520
521 for (i = 0; i < num_checks * MAX_VALUES_PER_FUNC; ++i)
522 values[i] = random ();
523
524 for (i = 0; i < num_checks; ++i)
525 {
hp.com!davidm77a27f02004-03-19 02:38:39 +0000526 if (test == 1)
527 /* Make first test once go through each test... */
528 index = i % NELEMS (all_funcs);
529 else
530 index = random () % NELEMS (all_funcs);
mostang.com!davidm05a91012004-02-14 07:53:31 +0000531 funcs[i] = all_funcs[index].func;
532 checks[i] = all_funcs[index].check;
533 }
534
535 funcs[num_checks] = start_checks;
536
hp.com!davidmad73ee32004-02-27 00:59:41 +0000537 enable_sighandler ();
mostang.com!davidm05a91012004-02-14 07:53:31 +0000538 (*funcs[0]) (funcs + 1, values);
539}
540
541int
542main (int argc, char **argv)
543{
544 int i;
545
546 if (argc > 1)
547 verbose = 1;
548
549 for (i = 0; i < NUM_RUNS; ++i)
hp.com!davidm330d2b52004-02-19 01:32:27 +0000550 {
551 if (verbose)
hp.com!davidmad73ee32004-02-27 00:59:41 +0000552 printf ("Run %d\n", i + 1);
hp.com!davidm330d2b52004-02-19 01:32:27 +0000553 run_check (i + 1);
554 }
mostang.com!davidm05a91012004-02-14 07:53:31 +0000555
556 if (nerrors > 0)
557 {
558 fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
559 exit (-1);
560 }
561 if (verbose)
562 printf ("SUCCESS.\n");
563 return 0;
564}