Imported Upstream version 1.1
[platform/upstream/libunwind.git] / tests / Gia64-test-nat.c
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
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
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
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
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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
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
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
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 }