1 /* libunwind - a platform-independent unwind library
2    Copyright (C) 2004-2005 Hewlett-Packard Co
3 	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4 
5 This file is part of libunwind.
6 
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14 
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
25 
26 /* This file tests corner-cases of NaT-bit handling.  */
27 
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include <libunwind.h>
34 #include "compiler.h"
35 
36 #ifdef HAVE_SYS_UC_ACCESS_H
37 # include <sys/uc_access.h>
38 #endif
39 
40 #include "tdep-ia64/rse.h"
41 
42 #define NUM_RUNS		1024
43 //#define NUM_RUNS		1
44 #define MAX_CHECKS		1024
45 //#define MAX_CHECKS		2
46 #define MAX_VALUES_PER_FUNC	4
47 
48 #define panic(args...)							  \
49 	do { printf (args); ++nerrors; } while (0)
50 
51 typedef void save_func_t (void *funcs, unsigned long *vals);
52 typedef unw_word_t *check_func_t (unw_cursor_t *c, unsigned long *vals);
53 
54 extern void flushrs (void);
55 
56 extern save_func_t save_static_to_stacked;
57 static check_func_t check_static_to_stacked;
58 
59 extern save_func_t save_static_to_fr;
60 static check_func_t check_static_to_fr;
61 
62 extern save_func_t save_static_to_br;
63 static check_func_t check_static_to_br;
64 
65 extern save_func_t save_static_to_mem;
66 static check_func_t check_static_to_mem;
67 
68 extern save_func_t save_static_to_mem2;
69 static check_func_t check_static_to_mem2;
70 
71 extern save_func_t save_static_to_mem3;
72 static check_func_t check_static_to_mem3;
73 
74 extern save_func_t save_static_to_mem4;
75 static check_func_t check_static_to_mem4;
76 
77 extern save_func_t save_static_to_mem5;
78 static check_func_t check_static_to_mem5;
79 
80 extern save_func_t save_static_to_scratch;
81 static check_func_t check_static_to_scratch;
82 
83 extern save_func_t rotate_regs;
84 static check_func_t check_rotate_regs;
85 
86 extern save_func_t save_pr;
87 static check_func_t check_pr;
88 
89 static int verbose;
90 static int nerrors;
91 
92 static int num_checks;
93 static save_func_t *funcs[MAX_CHECKS + 1];
94 static check_func_t *checks[MAX_CHECKS];
95 static unw_word_t values[MAX_CHECKS*MAX_VALUES_PER_FUNC];
96 
97 static struct
98   {
99     save_func_t *func;
100     check_func_t *check;
101   }
102 all_funcs[] =
103   {
104     { save_static_to_stacked,	check_static_to_stacked },
105     { save_static_to_fr,	check_static_to_fr },
106     { save_static_to_br,	check_static_to_br },
107     { save_static_to_mem,	check_static_to_mem },
108     { save_static_to_mem2,	check_static_to_mem2 },
109     { save_static_to_mem3,	check_static_to_mem3 },
110     { save_static_to_mem4,	check_static_to_mem4 },
111     { save_static_to_mem5,	check_static_to_mem5 },
112     { save_static_to_scratch,	check_static_to_scratch },
113     { save_pr,			check_pr },
114     { rotate_regs,		check_rotate_regs },
115   };
116 
117 static unw_word_t
random_word(void)118 random_word (void)
119 {
120   unw_word_t val = random ();
121 
122   if (sizeof (unw_word_t) > 4)
123     val |= ((unw_word_t) random ()) << 32;
124 
125   return val;
126 }
127 
128 void
sighandler(int signal,void * siginfo,void * context)129 sighandler (int signal, void *siginfo, void *context)
130 {
131   unsigned long *bsp, *arg1;
132   save_func_t **arg0;
133   ucontext_t *uc = context;
134 
135 #if defined(__linux)
136   {
137     long sof;
138     int sp;
139 
140     if (verbose)
141       printf ("sighandler: signal %d sp=%p nat=%08lx pr=%lx\n",
142 	      signal, &sp, uc->uc_mcontext.sc_nat, uc->uc_mcontext.sc_pr);
143     sof = uc->uc_mcontext.sc_cfm & 0x7f;
144     bsp = (unsigned long *) rse_skip_regs (uc->uc_mcontext.sc_ar_bsp, -sof);
145   }
146 #elif defined(__hpux)
147   if (__uc_get_ar (uc, UNW_IA64_AR_BSP - UNW_IA64_AR, &bsp) != 0)
148     {
149       panic ("%s: reading of ar.bsp failed, errno=%d", __FUNCTION__, errno);
150       return;
151     }
152 #endif
153 
154   flushrs ();
155   arg0 = (save_func_t **) *bsp;
156   bsp = (unsigned long *) rse_skip_regs ((uint64_t) bsp, 1);
157   arg1 = (unsigned long *) *bsp;
158 
159   (*arg0[0]) (arg0 + 1, arg1);
160 
161   /* skip over the instruction which triggered sighandler() */
162 #if defined(__linux)
163   ++uc->uc_mcontext.sc_ip;
164 #elif defined(HAVE_SYS_UC_ACCESS_H)
165   {
166     unsigned long ip;
167 
168     if (__uc_get_ip (uc, &ip) != 0)
169       {
170 	panic ("%s: reading of ip failed, errno=%d", __FUNCTION__, errno);
171 	return;
172       }
173     if (__uc_set_ip (uc, ip) != 0)
174       {
175 	panic ("%s: writing of ip failed, errno=%d", __FUNCTION__, errno);
176 	return;
177       }
178   }
179 #endif
180 }
181 
182 static void
enable_sighandler(void)183 enable_sighandler (void)
184 {
185   struct sigaction act;
186 
187   memset (&act, 0, sizeof (act));
188   act.sa_handler = (void (*)(int)) sighandler;
189   act.sa_flags = SA_SIGINFO | SA_NODEFER;
190   if (sigaction (SIGSEGV, &act, NULL) < 0)
191     panic ("sigaction: %s\n", strerror (errno));
192 }
193 
194 static void
disable_sighandler(void)195 disable_sighandler (void)
196 {
197   struct sigaction act;
198 
199   memset (&act, 0, sizeof (act));
200   act.sa_handler = SIG_DFL;
201   act.sa_flags = SA_SIGINFO | SA_NODEFER;
202   if (sigaction (SIGSEGV, &act, NULL) < 0)
203     panic ("sigaction: %s\n", strerror (errno));
204 }
205 
206 static unw_word_t *
check_static_to_stacked(unw_cursor_t * c,unw_word_t * vals)207 check_static_to_stacked (unw_cursor_t *c, unw_word_t *vals)
208 {
209   unw_word_t r[4];
210   unw_word_t nat[4];
211   int i, ret;
212 
213   if (verbose)
214     printf ("  %s()\n", __FUNCTION__);
215 
216   vals -= 4;
217 
218   for (i = 0; i < 4; ++i)
219     if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0)
220       panic ("%s: failed to read register r%d, error=%d\n",
221 	     __FUNCTION__, 4 + i, ret);
222 
223   for (i = 0; i < 4; ++i)
224     if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0)
225       panic ("%s: failed to read register nat%d, error=%d\n",
226 	     __FUNCTION__, 4 + i, ret);
227 
228   for (i = 0; i < 4; ++i)
229     {
230       if (verbose)
231 	printf ("    r%d = %c%016lx (expected %c%016lx)\n",
232 		4 + i, nat[i] ? '*' : ' ', r[i],
233 		(vals[i] & 1) ? '*' : ' ', vals[i]);
234 
235       if (vals[i] & 1)
236 	{
237 	  if (!nat[i])
238 	    panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i);
239 	}
240       else
241 	{
242 	  if (nat[i])
243 	    panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i);
244 	  if (r[i] != vals[i])
245 	    panic ("%s: r%d=%lx instead of %lx!\n",
246 		   __FUNCTION__, 4 + i, r[i], vals[i]);
247 	}
248     }
249   return vals;
250 }
251 
252 static unw_word_t *
check_static_to_fr(unw_cursor_t * c,unw_word_t * vals)253 check_static_to_fr (unw_cursor_t *c, unw_word_t *vals)
254 {
255   unw_word_t r4;
256   unw_word_t nat4;
257   int ret;
258 
259   if (verbose)
260     printf ("  %s()\n", __FUNCTION__);
261 
262   vals -= 1;
263 
264   if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0)
265     panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret);
266 
267   if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0)
268     panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret);
269 
270   if (verbose)
271     printf ("    r4 = %c%016lx (expected %c%016lx)\n",
272 	    nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]);
273 
274   if (vals[0] & 1)
275     {
276       if (!nat4)
277 	panic ("%s: r4 not a NaT!\n", __FUNCTION__);
278     }
279   else
280     {
281       if (nat4)
282 	panic ("%s: r4 a NaT!\n", __FUNCTION__);
283       if (r4 != vals[0])
284 	panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]);
285     }
286   return vals;
287 }
288 
289 static unw_word_t *
check_static_to_br(unw_cursor_t * c,unw_word_t * vals)290 check_static_to_br (unw_cursor_t *c, unw_word_t *vals)
291 {
292   unw_word_t r4, nat4;
293   int ret;
294 
295   if (verbose)
296     printf ("  %s()\n", __FUNCTION__);
297 
298   vals -= 1;
299 
300   if ((ret = unw_get_reg (c, UNW_IA64_GR + 4, &r4)) < 0)
301     panic ("%s: failed to read register r4, error=%d\n", __FUNCTION__, ret);
302 
303   if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4, &nat4)) < 0)
304     panic ("%s: failed to read register nat4, error=%d\n", __FUNCTION__, ret);
305 
306   if (verbose)
307     printf ("    r4 = %c%016lx (expected %c%016lx)\n",
308 	    nat4 ? '*' : ' ', r4, (vals[0] & 1) ? '*' : ' ', vals[0]);
309 
310   if (vals[0] & 1)
311     {
312       if (!nat4)
313 	panic ("%s: r4 not a NaT!\n", __FUNCTION__);
314     }
315   else
316     {
317       if (nat4)
318 	panic ("%s: r4 a NaT!\n", __FUNCTION__);
319       if (r4 != vals[0])
320 	panic ("%s: r4=%lx instead of %lx!\n", __FUNCTION__, r4, vals[0]);
321     }
322   return vals;
323 }
324 
325 static unw_word_t *
check_static_to_mem(unw_cursor_t * c,unw_word_t * vals)326 check_static_to_mem (unw_cursor_t *c, unw_word_t *vals)
327 {
328   unw_word_t r5, nat5;
329   int ret;
330 
331   if (verbose)
332     printf ("  %s()\n", __FUNCTION__);
333 
334   vals -= 1;
335 
336   if ((ret = unw_get_reg (c, UNW_IA64_GR + 5, &r5)) < 0)
337     panic ("%s: failed to read register r5, error=%d\n", __FUNCTION__, ret);
338 
339   if ((ret = unw_get_reg (c, UNW_IA64_NAT + 5, &nat5)) < 0)
340     panic ("%s: failed to read register nat5, error=%d\n", __FUNCTION__, ret);
341 
342   if (verbose)
343     printf ("    r5 = %c%016lx (expected %c%016lx)\n",
344 	    nat5 ? '*' : ' ', r5, (vals[0] & 1) ? '*' : ' ', vals[0]);
345 
346   if (vals[0] & 1)
347     {
348       if (!nat5)
349 	panic ("%s: r5 not a NaT!\n", __FUNCTION__);
350     }
351   else
352     {
353       if (nat5)
354 	panic ("%s: r5 a NaT!\n", __FUNCTION__);
355       if (r5 != vals[0])
356 	panic ("%s: r5=%lx instead of %lx!\n", __FUNCTION__, r5, vals[0]);
357     }
358   return vals;
359 }
360 
361 static unw_word_t *
check_static_to_memN(unw_cursor_t * c,unw_word_t * vals,const char * func)362 check_static_to_memN (unw_cursor_t *c, unw_word_t *vals, const char *func)
363 {
364   unw_word_t r6, nat6;
365   int ret;
366 
367   if (verbose)
368     printf ("  %s()\n", func);
369 
370   vals -= 1;
371 
372   if ((ret = unw_get_reg (c, UNW_IA64_GR + 6, &r6)) < 0)
373     panic ("%s: failed to read register r6, error=%d\n", __FUNCTION__, ret);
374 
375   if ((ret = unw_get_reg (c, UNW_IA64_NAT + 6, &nat6)) < 0)
376     panic ("%s: failed to read register nat6, error=%d\n", __FUNCTION__, ret);
377 
378   if (verbose)
379     printf ("    r6 = %c%016lx (expected %c%016lx)\n",
380 	    nat6 ? '*' : ' ', r6, (vals[0] & 1) ? '*' : ' ', vals[0]);
381 
382   if (vals[0] & 1)
383     {
384       if (!nat6)
385 	panic ("%s: r6 not a NaT!\n", __FUNCTION__);
386     }
387   else
388     {
389       if (nat6)
390 	panic ("%s: r6 a NaT!\n", __FUNCTION__);
391       if (r6 != vals[0])
392 	panic ("%s: r6=%lx instead of %lx!\n", __FUNCTION__, r6, vals[0]);
393     }
394   return vals;
395 }
396 
397 static unw_word_t *
check_static_to_mem2(unw_cursor_t * c,unw_word_t * vals)398 check_static_to_mem2 (unw_cursor_t *c, unw_word_t *vals)
399 {
400   return check_static_to_memN (c, vals, __FUNCTION__);
401 }
402 
403 static unw_word_t *
check_static_to_mem3(unw_cursor_t * c,unw_word_t * vals)404 check_static_to_mem3 (unw_cursor_t *c, unw_word_t *vals)
405 {
406   return check_static_to_memN (c, vals, __FUNCTION__);
407 }
408 
409 static unw_word_t *
check_static_to_mem4(unw_cursor_t * c,unw_word_t * vals)410 check_static_to_mem4 (unw_cursor_t *c, unw_word_t *vals)
411 {
412   return check_static_to_memN (c, vals, __FUNCTION__);
413 }
414 
415 static unw_word_t *
check_static_to_mem5(unw_cursor_t * c,unw_word_t * vals)416 check_static_to_mem5 (unw_cursor_t *c, unw_word_t *vals)
417 {
418   return check_static_to_memN (c, vals, __FUNCTION__);
419 }
420 
421 static unw_word_t *
check_static_to_scratch(unw_cursor_t * c,unw_word_t * vals)422 check_static_to_scratch (unw_cursor_t *c, unw_word_t *vals)
423 {
424   unw_word_t r[4], nat[4], ec, expected;
425   unw_fpreg_t f4;
426   int i, ret;
427 
428   if (verbose)
429     printf ("  %s()\n", __FUNCTION__);
430 
431   vals -= 4;
432 
433   while (!unw_is_signal_frame (c))
434     if ((ret = unw_step (c)) < 0)
435       panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n",
436 	     __FUNCTION__, ret);
437   if ((ret = unw_step (c)) < 0)
438     panic ("%s: unw_step (ret=%d): Failed to skip over signal handler\n",
439 	   __FUNCTION__, ret);
440 
441   for (i = 0; i < 4; ++i)
442     if ((ret = unw_get_reg (c, UNW_IA64_GR + 4 + i, &r[i])) < 0)
443       panic ("%s: failed to read register r%d, error=%d\n",
444 	     __FUNCTION__, 4 + i, ret);
445 
446   for (i = 0; i < 4; ++i)
447     if ((ret = unw_get_reg (c, UNW_IA64_NAT + 4 + i, &nat[i])) < 0)
448       panic ("%s: failed to read register nat%d, error=%d\n",
449 	     __FUNCTION__, 4 + i, ret);
450 
451   for (i = 0; i < 4; ++i)
452     {
453       if (verbose)
454 	printf ("    r%d = %c%016lx (expected %c%016lx)\n",
455 		4 + i, nat[i] ? '*' : ' ', r[i],
456 		(vals[i] & 1) ? '*' : ' ', vals[i]);
457 
458       if (vals[i] & 1)
459 	{
460 	  if (!nat[i])
461 	    panic ("%s: r%d not a NaT!\n", __FUNCTION__, 4 + i);
462 	}
463       else
464 	{
465 	  if (nat[i])
466 	    panic ("%s: r%d a NaT!\n", __FUNCTION__, 4 + i);
467 	  if (r[i] != vals[i])
468 	    panic ("%s: r%d=%lx instead of %lx!\n",
469 		   __FUNCTION__, 4 + i, r[i], vals[i]);
470 	}
471     }
472   if ((ret = unw_get_fpreg (c, UNW_IA64_FR + 4, &f4)) < 0)
473     panic ("%s: failed to read f4, error=%d\n", __FUNCTION__, ret);
474 
475   /* These tests are little-endian specific: */
476   if (nat[0])
477     {
478       if (f4.raw.bits[0] != 0 || f4.raw.bits[1] != 0x1fffe)
479 	panic ("%s: f4=%016lx.%016lx instead of NaTVal!\n",
480 	       __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0]);
481     }
482   else
483     {
484       if (f4.raw.bits[0] != r[0] || f4.raw.bits[1] != 0x1003e)
485 	panic ("%s: f4=%016lx.%016lx instead of %lx!\n",
486 	       __FUNCTION__, f4.raw.bits[1], f4.raw.bits[0], r[0]);
487     }
488 
489   if ((unw_get_reg (c, UNW_IA64_AR_EC, &ec)) < 0)
490     panic ("%s: failed to read register ar.ec, error=%d\n", __FUNCTION__, ret);
491 
492   expected = vals[0] & 0x3f;
493   if (ec != expected)
494     panic ("%s: ar.ec=%016lx instead of %016lx!\n",
495 	   __FUNCTION__, ec, expected);
496 
497   return vals;
498 }
499 
500 static unw_word_t *
check_pr(unw_cursor_t * c,unw_word_t * vals)501 check_pr (unw_cursor_t *c, unw_word_t *vals)
502 {
503   unw_word_t pr, expected;
504   int ret;
505 # define BIT(n) ((unw_word_t) 1 << (n))
506 # define DONTCARE (BIT( 6) | BIT( 7) | BIT( 8) | BIT( 9) | BIT(10) \
507 		 | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15))
508 
509   if (verbose)
510     printf ("  %s()\n", __FUNCTION__);
511 
512   vals -= 1;
513 
514   if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0)
515     panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret);
516 
517   pr &= ~DONTCARE;
518   expected = (vals[0] & ~DONTCARE) | 1;
519 
520   if (verbose)
521     printf ("    pr = %016lx (expected %016lx)\n", pr, expected);
522 
523   if (pr != expected)
524     panic ("%s: pr=%lx instead of %lx!\n", __FUNCTION__, pr, expected);
525 
526   if ((ret = unw_set_reg (c, UNW_IA64_PR, vals[0])) < 0)
527     panic ("%s: failed to write register pr, error=%d\n", __FUNCTION__, ret);
528 
529   if ((ret = unw_get_reg (c, UNW_IA64_PR, &pr)) < 0)
530     panic ("%s: failed to read register pr, error=%d\n", __FUNCTION__, ret);
531 
532   if (pr != vals[0])
533     panic ("%s: secondary pr=%lx instead of %lx!\n",
534 	   __FUNCTION__, pr, vals[0]);
535   return vals;
536 }
537 
538 static unw_word_t *
check_rotate_regs(unw_cursor_t * c,unw_word_t * vals)539 check_rotate_regs (unw_cursor_t *c, unw_word_t *vals)
540 {
541   if (verbose)
542     printf ("  %s()\n", __FUNCTION__);
543   return check_pr (c, vals - 1);
544 }
545 
546 static void
start_checks(void * funcs,unsigned long * vals)547 start_checks (void *funcs, unsigned long *vals)
548 {
549   unw_context_t uc;
550   unw_cursor_t c;
551   int i, ret;
552 
553   disable_sighandler ();
554 
555   unw_getcontext (&uc);
556 
557   if ((ret = unw_init_local (&c, &uc)) < 0)
558     panic ("%s: unw_init_local (ret=%d)\n", __FUNCTION__, ret);
559 
560   if ((ret = unw_step (&c)) < 0)
561     panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret);
562 
563   for (i = 0; i < num_checks; ++i)
564     {
565       vals = (*checks[num_checks - 1 - i]) (&c, vals);
566 
567       if ((ret = unw_step (&c)) < 0)
568 	panic ("%s: unw_step (ret=%d)\n", __FUNCTION__, ret);
569     }
570 }
571 
572 static void
run_check(int test)573 run_check (int test)
574 {
575   int index, i;
576 
577   if (test == 1)
578     /* Make first test always go the full depth... */
579     num_checks = MAX_CHECKS;
580   else
581     num_checks = (random () % MAX_CHECKS) + 1;
582 
583   for (i = 0; i < num_checks * MAX_VALUES_PER_FUNC; ++i)
584     values[i] = random_word ();
585 
586   for (i = 0; i < num_checks; ++i)
587     {
588       if (test == 1)
589 	/* Make first test once go through each test... */
590 	index = i % (int) ARRAY_SIZE (all_funcs);
591       else
592 	index = random () % (int) ARRAY_SIZE (all_funcs);
593       funcs[i] = all_funcs[index].func;
594       checks[i] = all_funcs[index].check;
595     }
596 
597   funcs[num_checks] = start_checks;
598 
599   enable_sighandler ();
600   (*funcs[0]) (funcs + 1, values);
601 }
602 
603 int
main(int argc,char ** argv)604 main (int argc, char **argv)
605 {
606   int i;
607 
608   if (argc > 1)
609     verbose = 1;
610 
611   for (i = 0; i < NUM_RUNS; ++i)
612     {
613       if (verbose)
614 	printf ("Run %d\n", i + 1);
615       run_check (i + 1);
616     }
617 
618   if (nerrors > 0)
619     {
620       fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
621       exit (-1);
622     }
623   if (verbose)
624     printf ("SUCCESS.\n");
625   return 0;
626 }
627