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