1 /* libunwind - a platform-independent unwind library 2 Copyright (C) 2004-2005 Hewlett-Packard Co 3 Contributed by David Mosberger-Tang <davidm (at) 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 } 627