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