1 2 /*--------------------------------------------------------------------*/ 3 /*--- Extract type info from debug info. symtypes.h ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2005 Julian Seward 11 jseward (a] acm.org 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #include "pub_core_basics.h" 32 #include "pub_core_debuginfo.h" 33 #include "pub_core_debuglog.h" // For VG_(debugLog_vprintf) 34 #include "pub_core_libcbase.h" 35 #include "pub_core_libcassert.h" 36 #include "pub_core_libcprint.h" 37 #include "pub_core_libcsignal.h" 38 #include "pub_core_machine.h" 39 #include "pub_core_mallocfree.h" 40 41 #include "priv_symtypes.h" 42 43 typedef enum { 44 TyUnknown, /* unknown type */ 45 TyUnresolved, /* unresolved type */ 46 TyError, /* error type */ 47 48 TyVoid, /* void */ 49 50 TyInt, /* integer */ 51 TyBool, /* boolean */ 52 TyChar, /* character */ 53 TyFloat, /* float */ 54 55 TyRange, /* type subrange */ 56 57 TyEnum, /* enum */ 58 59 TyPointer, /* pointer */ 60 TyArray, /* array */ 61 TyStruct, /* structure/class */ 62 TyUnion, /* union */ 63 64 TyTypedef /* typedef */ 65 } TyKind; 66 67 static const Char *ppkind(TyKind k) 68 { 69 switch(k) { 70 #define S(x) case x: return #x 71 S(TyUnknown); 72 S(TyUnresolved); 73 S(TyError); 74 S(TyVoid); 75 S(TyInt); 76 S(TyBool); 77 S(TyChar); 78 S(TyRange); 79 S(TyFloat); 80 S(TyEnum); 81 S(TyPointer); 82 S(TyArray); 83 S(TyStruct); 84 S(TyUnion); 85 S(TyTypedef); 86 #undef S 87 default: 88 return "Ty???"; 89 } 90 } 91 92 /* struct/union field */ 93 typedef struct _StField { 94 UInt offset; /* offset into structure (0 for union) (in bits) */ 95 UInt size; /* size (in bits) */ 96 SymType *type; /* type of element */ 97 Char *name; /* name of element */ 98 } StField; 99 100 /* enum tag */ 101 typedef struct _EnTag { 102 const Char *name; /* name */ 103 UInt val; /* value */ 104 } EnTag; 105 106 struct _SymType { 107 TyKind kind; /* type descriminator */ 108 UInt size; /* sizeof(type) */ 109 Char *name; /* useful name */ 110 111 union { 112 /* TyInt,TyBool,TyChar */ 113 struct { 114 Bool issigned; /* signed or not */ 115 } t_scalar; 116 117 /* TyFloat */ 118 struct { 119 Bool isdouble; /* is double prec */ 120 } t_float; 121 122 /* TyRange */ 123 struct { 124 Int min; 125 Int max; 126 SymType *type; 127 } t_range; 128 129 /* TyPointer */ 130 struct { 131 SymType *type; /* *type */ 132 } t_pointer; 133 134 /* TyArray */ 135 struct { 136 SymType *idxtype; 137 SymType *type; 138 } t_array; 139 140 /* TyEnum */ 141 struct { 142 UInt ntag; /* number of tags */ 143 EnTag *tags; /* tags */ 144 } t_enum; 145 146 /* TyStruct, TyUnion */ 147 struct { 148 UInt nfield; /* number of fields */ 149 UInt nfieldalloc; /* number of fields allocated */ 150 StField *fields; /* fields */ 151 } t_struct; 152 153 /* TyTypedef */ 154 struct { 155 SymType *type; /* type */ 156 } t_typedef; 157 158 /* TyUnresolved - reference to unresolved type */ 159 struct { 160 /* some kind of symtab reference */ 161 SymResolver *resolver; /* symtab reader's resolver */ 162 void *data; /* data for resolver */ 163 } t_unresolved; 164 } u; 165 }; 166 167 168 Bool ML_(st_isstruct)(SymType *ty) 169 { 170 return ty->kind == TyStruct; 171 } 172 173 Bool ML_(st_isunion)(SymType *ty) 174 { 175 return ty->kind == TyUnion; 176 } 177 178 Bool ML_(st_isenum)(SymType *ty) 179 { 180 return ty->kind == TyEnum; 181 } 182 183 static inline SymType *alloc(SymType *st) 184 { 185 if (st == NULL) { 186 st = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(*st)); 187 st->kind = TyUnknown; 188 st->name = NULL; 189 } 190 191 return st; 192 } 193 194 static void resolve(SymType *st) 195 { 196 if (st->kind != TyUnresolved) 197 return; 198 199 (*st->u.t_unresolved.resolver)(st, st->u.t_unresolved.data); 200 201 if (st->kind == TyUnresolved) 202 st->kind = TyError; 203 } 204 205 SymType *ML_(st_mkunresolved)(SymType *st, SymResolver *resolver, void *data) 206 { 207 st = alloc(st); 208 209 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 210 211 st->kind = TyUnresolved; 212 st->size = 0; 213 st->u.t_unresolved.resolver = resolver; 214 st->u.t_unresolved.data = data; 215 216 return st; 217 } 218 219 void ML_(st_unresolved_setdata)(SymType *st, SymResolver *resolver, void *data) 220 { 221 if (st->kind != TyUnresolved) 222 return; 223 224 st->u.t_unresolved.resolver = resolver; 225 st->u.t_unresolved.data = data; 226 } 227 228 Bool ML_(st_isresolved)(SymType *st) 229 { 230 return st->kind != TyUnresolved; 231 } 232 233 void ML_(st_setname)(SymType *st, Char *name) 234 { 235 if (st->name != NULL) 236 st->name = name; 237 } 238 239 SymType *ML_(st_mkvoid)(SymType *st) 240 { 241 st = alloc(st); 242 243 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 244 245 st->kind = TyVoid; 246 st->size = 1; /* for address calculations */ 247 st->name = "void"; 248 return st; 249 } 250 251 SymType *ML_(st_mkint)(SymType *st, UInt size, Bool isSigned) 252 { 253 st = alloc(st); 254 255 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 256 257 st->kind = TyInt; 258 st->size = size; 259 st->u.t_scalar.issigned = isSigned; 260 261 return st; 262 } 263 264 SymType *ML_(st_mkfloat)(SymType *st, UInt size) 265 { 266 st = alloc(st); 267 268 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 269 270 st->kind = TyFloat; 271 st->size = size; 272 st->u.t_scalar.issigned = True; 273 274 return st; 275 } 276 277 SymType *ML_(st_mkbool)(SymType *st, UInt size) 278 { 279 st = alloc(st); 280 281 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 282 283 st->kind = TyBool; 284 st->size = size; 285 286 return st; 287 } 288 289 290 SymType *ML_(st_mkpointer)(SymType *st, SymType *ptr) 291 { 292 st = alloc(st); 293 294 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 295 296 st->kind = TyPointer; 297 st->size = sizeof(void *); 298 st->u.t_pointer.type = ptr; 299 300 return st; 301 } 302 303 SymType *ML_(st_mkrange)(SymType *st, SymType *ty, Int min, Int max) 304 { 305 st = alloc(st); 306 307 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 308 309 st->kind = TyRange; 310 st->size = 0; /* ? */ 311 st->u.t_range.type = ty; 312 st->u.t_range.min = min; 313 st->u.t_range.max = max; 314 315 return st; 316 } 317 318 SymType *ML_(st_mkstruct)(SymType *st, UInt size, UInt nfields) 319 { 320 st = alloc(st); 321 322 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown || st->kind == TyStruct); 323 324 vg_assert(st->kind != TyStruct || st->u.t_struct.nfield == 0); 325 326 st->kind = TyStruct; 327 st->size = size; 328 st->u.t_struct.nfield = 0; 329 st->u.t_struct.nfieldalloc = nfields; 330 if (nfields != 0) 331 st->u.t_struct.fields = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(StField) * nfields); 332 else 333 st->u.t_struct.fields = NULL; 334 335 return st; 336 } 337 338 SymType *ML_(st_mkunion)(SymType *st, UInt size, UInt nfields) 339 { 340 st = alloc(st); 341 342 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown || st->kind == TyUnion); 343 344 vg_assert(st->kind != TyUnion || st->u.t_struct.nfield == 0); 345 346 st->kind = TyUnion; 347 st->size = size; 348 st->u.t_struct.nfield = 0; 349 st->u.t_struct.nfieldalloc = nfields; 350 if (nfields != 0) 351 st->u.t_struct.fields = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(StField) * nfields); 352 else 353 st->u.t_struct.fields = NULL; 354 355 return st; 356 } 357 358 void ML_(st_addfield)(SymType *st, Char *name, SymType *type, UInt off, UInt size) 359 { 360 StField *f; 361 362 vg_assert(st->kind == TyStruct || st->kind == TyUnion); 363 364 if (st->u.t_struct.nfieldalloc == st->u.t_struct.nfield) { 365 StField *n = VG_(arena_malloc)(VG_AR_SYMTAB, 366 sizeof(StField) * (st->u.t_struct.nfieldalloc + 2)); 367 VG_(memcpy)(n, st->u.t_struct.fields, sizeof(*n) * st->u.t_struct.nfield); 368 if (st->u.t_struct.fields != NULL) 369 VG_(arena_free)(VG_AR_SYMTAB, st->u.t_struct.fields); 370 st->u.t_struct.nfieldalloc++; 371 st->u.t_struct.fields = n; 372 } 373 374 f = &st->u.t_struct.fields[st->u.t_struct.nfield++]; 375 f->name = name; 376 f->type = type; 377 f->offset = off; 378 f->size = size; 379 } 380 381 382 SymType *ML_(st_mkenum)(SymType *st, UInt ntags) 383 { 384 st = alloc(st); 385 386 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown || st->kind == TyEnum); 387 388 st->kind = TyEnum; 389 st->u.t_enum.ntag = 0; 390 st->u.t_enum.tags = NULL; 391 392 return st; 393 } 394 395 SymType *ML_(st_mkarray)(SymType *st, SymType *idxtype, SymType *type) 396 { 397 st = alloc(st); 398 399 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown); 400 401 st->kind = TyArray; 402 st->u.t_array.type = type; 403 st->u.t_array.idxtype = idxtype; 404 405 return st; 406 } 407 408 SymType *ML_(st_mktypedef)(SymType *st, Char *name, SymType *type) 409 { 410 st = alloc(st); 411 412 vg_assert(st != type); 413 vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown || 414 st->kind == TyStruct || st->kind == TyUnion || 415 st->kind == TyTypedef); 416 417 st->kind = TyTypedef; 418 st->name = name; 419 st->u.t_typedef.type = type; 420 421 return st; 422 } 423 424 425 SymType *ML_(st_basetype)(SymType *type, Bool do_resolve) 426 { 427 while (type->kind == TyTypedef || (do_resolve && type->kind == TyUnresolved)) { 428 if (do_resolve) 429 resolve(type); 430 431 if (type->kind == TyTypedef) 432 type = type->u.t_typedef.type; 433 } 434 435 return type; 436 } 437 438 UInt ML_(st_sizeof)(SymType *ty) 439 { 440 return ty->size; 441 } 442 443 #ifndef TEST 444 /* 445 Hash of visited addresses, so we don't get stuck in loops. It isn't 446 simply enough to keep track of addresses, since we need to interpret 447 the memory according to the type. If a given location has multiple 448 pointers with different types (for example, void * and struct foo *), 449 then we need to look at it under each type. 450 */ 451 struct visited { 452 Addr a; 453 SymType *ty; 454 struct visited *next; 455 }; 456 457 #define VISIT_HASHSZ 1021 458 459 static struct visited *visit_hash[VISIT_HASHSZ]; 460 461 static inline Bool test_visited(Addr a, SymType *type) 462 { 463 struct visited *v; 464 UInt b = (UInt)a % VISIT_HASHSZ; 465 Bool ret = False; 466 467 for(v = visit_hash[b]; v != NULL; v = v->next) { 468 if (v->a == a && v->ty == type) { 469 ret = True; 470 break; 471 } 472 } 473 474 return ret; 475 } 476 477 static Bool has_visited(Addr a, SymType *type) 478 { 479 static const Bool debug = False; 480 Bool ret; 481 482 ret = test_visited(a, type); 483 484 if (!ret) { 485 UInt b = (UInt)a % VISIT_HASHSZ; 486 struct visited * v = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(*v)); 487 488 v->a = a; 489 v->ty = type; 490 v->next = visit_hash[b]; 491 visit_hash[b] = v; 492 } 493 494 if (debug) 495 VG_(printf)("has_visited(a=%p, ty=%p) -> %d\n", a, type, ret); 496 497 return ret; 498 } 499 500 static void clear_visited(void) 501 { 502 UInt i; 503 504 for(i = 0; i < VISIT_HASHSZ; i++) { 505 struct visited *v, *n; 506 for(v = visit_hash[i]; v != NULL; v = n) { 507 n = v->next; 508 VG_(arena_free)(VG_AR_SYMTAB, v); 509 } 510 visit_hash[i] = NULL; 511 } 512 } 513 514 static 515 void bprintf(void (*send)(HChar, void*), void *send_arg, const Char *fmt, ...) 516 { 517 va_list vargs; 518 519 va_start(vargs, fmt); 520 VG_(debugLog_vprintf)(send, send_arg, fmt, vargs); 521 va_end(vargs); 522 } 523 524 #define SHADOWCHUNK 0 /* no longer have a core allocator */ 525 526 #if SHADOWCHUNK 527 static ShadowChunk *findchunk(Addr a) 528 { 529 Bool find(ShadowChunk *sc) { 530 return a >= sc->data && a < (sc->data+sc->size); 531 } 532 return VG_(any_matching_mallocd_ShadowChunks)(find); 533 } 534 #endif 535 536 static struct vki_sigaction sigbus_saved; 537 static struct vki_sigaction sigsegv_saved; 538 static vki_sigset_t blockmask_saved; 539 static jmp_buf valid_addr_jmpbuf; 540 541 static void valid_addr_handler(int sig) 542 { 543 //VG_(printf)("OUCH! %d\n", sig); 544 __builtin_longjmp(valid_addr_jmpbuf, 1); 545 } 546 547 /* catch badness signals because we're going to be 548 playing around in untrusted memory */ 549 static void setup_signals(void) 550 { 551 Int res; 552 struct vki_sigaction sigbus_new; 553 struct vki_sigaction sigsegv_new; 554 vki_sigset_t unblockmask_new; 555 556 /* Temporarily install a new sigsegv and sigbus handler, and make 557 sure SIGBUS, SIGSEGV and SIGTERM are unblocked. (Perhaps the 558 first two can never be blocked anyway?) */ 559 560 sigbus_new.ksa_handler = valid_addr_handler; 561 sigbus_new.sa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART; 562 sigbus_new.sa_restorer = NULL; 563 res = VG_(sigemptyset)( &sigbus_new.sa_mask ); 564 vg_assert(res == 0); 565 566 sigsegv_new.ksa_handler = valid_addr_handler; 567 sigsegv_new.sa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART; 568 sigsegv_new.sa_restorer = NULL; 569 res = VG_(sigemptyset)( &sigsegv_new.sa_mask ); 570 vg_assert(res == 0+0); 571 572 res = VG_(sigemptyset)( &unblockmask_new ); 573 res |= VG_(sigaddset)( &unblockmask_new, VKI_SIGBUS ); 574 res |= VG_(sigaddset)( &unblockmask_new, VKI_SIGSEGV ); 575 res |= VG_(sigaddset)( &unblockmask_new, VKI_SIGTERM ); 576 vg_assert(res == 0+0+0); 577 578 res = VG_(sigaction)( VKI_SIGBUS, &sigbus_new, &sigbus_saved ); 579 vg_assert(res == 0+0+0+0); 580 581 res = VG_(sigaction)( VKI_SIGSEGV, &sigsegv_new, &sigsegv_saved ); 582 vg_assert(res == 0+0+0+0+0); 583 584 res = VG_(sigprocmask)( VKI_SIG_UNBLOCK, &unblockmask_new, &blockmask_saved ); 585 vg_assert(res == 0+0+0+0+0+0); 586 } 587 588 static void restore_signals(void) 589 { 590 Int res; 591 592 /* Restore signal state to whatever it was before. */ 593 res = VG_(sigaction)( VKI_SIGBUS, &sigbus_saved, NULL ); 594 vg_assert(res == 0 +0); 595 596 res = VG_(sigaction)( VKI_SIGSEGV, &sigsegv_saved, NULL ); 597 vg_assert(res == 0 +0 +0); 598 599 res = VG_(sigprocmask)( VKI_SIG_SETMASK, &blockmask_saved, NULL ); 600 vg_assert(res == 0 +0 +0 +0); 601 } 602 603 /* if false, setup and restore signals for every access */ 604 #define LAZYSIG 1 605 606 static Bool is_valid_addr(Addr a) 607 { 608 static SymType faulted = { TyError }; 609 static const Bool debug = False; 610 volatile Bool ret = False; 611 612 if ((a > VKI_PAGE_SIZE) && !test_visited(a, &faulted)) { 613 if (!LAZYSIG) 614 setup_signals(); 615 616 if (__builtin_setjmp(valid_addr_jmpbuf) == 0) { 617 volatile UInt *volatile ptr = (volatile UInt *)a; 618 619 *ptr; 620 621 ret = True; 622 } else { 623 /* cache bad addresses in visited table */ 624 has_visited(a, &faulted); 625 ret = False; 626 } 627 628 if (!LAZYSIG) 629 restore_signals(); 630 } 631 632 if (debug) 633 VG_(printf)("is_valid_addr(%p) -> %d\n", a, ret); 634 635 return ret; 636 } 637 638 static Int free_varlist(Variable *list) 639 { 640 Variable *next; 641 Int count = 0; 642 643 for(; list != NULL; list = next) { 644 next = list->next; 645 count++; 646 if (list->name) 647 VG_(arena_free)(VG_AR_SYMTAB, list->name); 648 VG_(arena_free)(VG_AR_SYMTAB, list); 649 } 650 return count; 651 } 652 653 /* Composite: struct, union, array 654 Non-composite: everything else 655 */ 656 static inline Bool is_composite(SymType *ty) 657 { 658 switch(ty->kind) { 659 case TyUnion: 660 case TyStruct: 661 case TyArray: 662 return True; 663 664 default: 665 return False; 666 } 667 } 668 669 /* There's something at the end of the rainbow */ 670 static inline Bool is_followable(SymType *ty) 671 { 672 return ty->kind == TyPointer || is_composite(ty); 673 } 674 675 /* Result buffer */ 676 static Char *describe_addr_buf; 677 static UInt describe_addr_bufidx; 678 static UInt describe_addr_bufsz; 679 680 /* Add a character to the result buffer */ 681 static void describe_addr_addbuf(HChar c,void *p) { 682 if ((describe_addr_bufidx+1) >= describe_addr_bufsz) { 683 Char *n; 684 685 if (describe_addr_bufsz == 0) 686 describe_addr_bufsz = 8; 687 else 688 describe_addr_bufsz *= 2; 689 690 /* use tool malloc so that the tool can free it */ 691 n = VG_(malloc)(describe_addr_bufsz); 692 if (describe_addr_buf != NULL && describe_addr_bufidx != 0) 693 VG_(memcpy)(n, describe_addr_buf, describe_addr_bufidx); 694 if (describe_addr_buf != NULL) 695 VG_(free)(describe_addr_buf); 696 describe_addr_buf = n; 697 } 698 describe_addr_buf[describe_addr_bufidx++] = c; 699 describe_addr_buf[describe_addr_bufidx] = '\0'; 700 } 701 702 #define MAX_PLY 7 /* max depth we go */ 703 #define MAX_ELEMENTS 5000 /* max number of array elements we scan */ 704 #define MAX_VARS 10000 /* max number of variables total traversed */ 705 706 static const Bool memaccount = False; /* match creates to frees */ 707 static const Bool debug = False; 708 709 /* Add a new variable to the list */ 710 static Bool newvar(Char *name, SymType *ty, Addr valuep, UInt size, 711 Variable *var, Int *numvars, Int *created, 712 Variable **newlist, Variable **newlistend) { 713 Variable *v; 714 715 /* have we been here before? */ 716 if (has_visited(valuep, ty)) 717 return False; 718 719 /* are we too deep? */ 720 if (var->distance > MAX_PLY) 721 return False; 722 723 /* have we done too much? */ 724 if ((*numvars)-- == 0) 725 return False; 726 727 if (memaccount) 728 (*created)++; 729 730 v = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(*v)); 731 732 if (name) 733 v->name = VG_(arena_strdup)(VG_AR_SYMTAB, name); 734 else 735 v->name = NULL; 736 v->type = ML_(st_basetype)(ty, False); 737 v->valuep = valuep; 738 v->size = size == -1 ? ty->size : size; 739 v->container = var; 740 v->distance = var->distance + 1; 741 v->next = NULL; 742 743 if (*newlist == NULL) 744 *newlist = *newlistend = v; 745 else { 746 (*newlistend)->next = v; 747 *newlistend = v; 748 } 749 750 if (debug) 751 VG_(printf)(" --> %d: name=%s type=%p(%s %s) container=%p &val=%p\n", 752 v->distance, v->name, v->type, ppkind(v->type->kind), 753 v->type->name ? (char *)v->type->name : "", 754 v->container, v->valuep); 755 return True; 756 } 757 758 static void genstring(Variable *v, Variable *inner, Int *len, Char **ep, 759 Char **sp) { 760 Variable *c = v->container; 761 762 if (c != NULL) 763 genstring(c, v, len, ep, sp); 764 765 if (v->name != NULL) { 766 *len = VG_(strlen)(v->name); 767 VG_(memcpy)(*ep, v->name, *len); 768 (*ep) += *len; 769 } 770 771 switch(v->type->kind) { 772 case TyPointer: 773 /* pointer-to-structure/union handled specially */ 774 if (inner == NULL || 775 !(inner->type->kind == TyStruct || inner->type->kind == TyUnion)) { 776 *--(*sp) = '*'; 777 *--(*sp) = '('; 778 *(*ep)++ = ')'; 779 } 780 break; 781 782 case TyStruct: 783 case TyUnion: 784 if (c && c->type->kind == TyPointer) { 785 *(*ep)++ = '-'; 786 *(*ep)++ = '>'; 787 } else 788 *(*ep)++ = '.'; 789 break; 790 791 default: 792 break; 793 } 794 } 795 796 Char *VG_(describe_addr)(ThreadId tid, Addr addr) 797 { 798 Addr eip; /* thread's EIP */ 799 Variable *list; /* worklist */ 800 Variable *keeplist; /* container variables */ 801 Variable *found; /* the chain we found */ 802 Int created=0, freed=0; 803 Int numvars = MAX_VARS; 804 805 describe_addr_buf = NULL; 806 describe_addr_bufidx = 0; 807 describe_addr_bufsz = 0; 808 809 clear_visited(); 810 811 found = NULL; 812 keeplist = NULL; 813 814 eip = VG_(get_IP)(tid); 815 list = ML_(get_scope_variables)(tid); 816 817 if (memaccount) { 818 Variable *v; 819 820 for(v = list; v != NULL; v = v->next) 821 created++; 822 } 823 824 if (debug) { 825 Char file[100]; 826 Int line; 827 if (!VG_(get_filename_linenum)(eip, file, sizeof(file), 828 NULL, 0, NULL, &line)) 829 file[0] = 0; 830 VG_(printf)("describing address %p for tid=%d @ %s:%d\n", addr, tid, file, line); 831 } 832 833 if (LAZYSIG) 834 setup_signals(); 835 836 /* breadth-first traversal of all memory visible to the program at 837 the current point */ 838 while(list != NULL && found == NULL) { 839 Variable **prev = &list; 840 Variable *var, *next; 841 Variable *newlist = NULL, *newlistend = NULL; 842 843 if (debug) 844 VG_(printf)("----------------------------------------\n"); 845 846 for(var = list; var != NULL; var = next) { 847 SymType *type = var->type; 848 Bool keep = False; 849 850 next = var->next; 851 852 if (debug) 853 VG_(printf)(" %d: name=%s type=%p(%s %s) container=%p &val=%p\n", 854 var->distance, var->name, 855 var->type, ppkind(var->type->kind), 856 var->type->name ? (char *)var->type->name : "", 857 var->container, var->valuep); 858 859 if (0 && has_visited(var->valuep, var->type)) { 860 /* advance prev; we're keeping this one on the doomed list */ 861 prev = &var->next; 862 continue; 863 } 864 865 if (!is_composite(var->type) && 866 addr >= var->valuep && addr < (var->valuep + var->size)) { 867 /* at hit - remove it from the list, add it to the 868 keeplist and set found */ 869 found = var; 870 *prev = var->next; 871 var->next = keeplist; 872 keeplist = var; 873 break; 874 } 875 876 type = ML_(st_basetype)(type, True); 877 878 switch(type->kind) { 879 case TyUnion: 880 case TyStruct: { 881 Int i; 882 883 if (debug) 884 VG_(printf)(" %d fields\n", type->u.t_struct.nfield); 885 for(i = 0; i < type->u.t_struct.nfield; i++) { 886 StField *f = &type->u.t_struct.fields[i]; 887 if(newvar(f->name, f->type, var->valuep + (f->offset / 8), 888 (f->size + 7) / 8, var, &numvars, &created, &newlist, 889 &newlistend)) 890 keep = True; 891 } 892 break; 893 } 894 895 case TyArray: { 896 Int i; 897 Int offset; /* offset of index for non-0-based arrays */ 898 Int min, max; /* range of indicies we care about (0 based) */ 899 SymType *ty = type->u.t_array.type; 900 vg_assert(type->u.t_array.idxtype->kind == TyRange); 901 902 offset = type->u.t_array.idxtype->u.t_range.min; 903 min = 0; 904 max = type->u.t_array.idxtype->u.t_range.max - offset; 905 906 if ((max-min+1) == 0) { 907 #if SHADOWCHUNK 908 /* zero-sized array - look at allocated memory */ 909 ShadowChunk *sc = findchunk(var->valuep); 910 911 if (sc != NULL) { 912 max = ((sc->data + sc->size - var->valuep) / ty->size) + min; 913 if (debug) 914 VG_(printf)(" zero sized array: using min=%d max=%d\n", 915 min, max); 916 } 917 #endif 918 } 919 920 /* If this array's elements can't take us anywhere useful, 921 just look to see if an element itself is being pointed 922 to; otherwise just skip the whole thing */ 923 if (!is_followable(ty)) { 924 UInt sz = ty->size * (max+1); 925 926 if (debug) 927 VG_(printf)(" non-followable array (sz=%d): checking addr %p in range %p-%p\n", 928 sz, addr, var->valuep, (var->valuep + sz)); 929 if (ty->size > 0 && addr >= var->valuep && addr <= (var->valuep + sz)) 930 min = max = (addr - var->valuep) / ty->size; 931 else 932 break; 933 } 934 935 /* truncate array if it's too big */ 936 if (max-min+1 > MAX_ELEMENTS) 937 max = min+MAX_ELEMENTS; 938 939 if (debug) 940 VG_(printf)(" array index %d - %d\n", min, max); 941 for(i = min; i <= max; i++) { 942 Char b[10]; 943 VG_(sprintf)(b, "[%d]", i+offset); 944 if(newvar(b, ty, var->valuep + (i * ty->size), -1, var, 945 &numvars, &created, &newlist, &newlistend)) 946 keep = True; 947 } 948 949 break; 950 } 951 952 case TyPointer: 953 /* follow */ 954 /* XXX work out a way of telling whether a pointer is 955 actually a decayed array, and treat it accordingly */ 956 if (is_valid_addr(var->valuep)) 957 if(newvar(NULL, type->u.t_pointer.type, *(Addr *)var->valuep, 958 -1, var, &numvars, &created, &newlist, &newlistend)) 959 keep = True; 960 break; 961 962 case TyUnresolved: 963 VG_(printf)("var %s is unresolved (type=%p)\n", var->name, type); 964 break; 965 966 default: 967 /* Simple non-composite, non-pointer type */ 968 break; 969 } 970 971 if (keep) { 972 /* ironically, keep means remove it from the list */ 973 *prev = next; 974 975 /* being kept - add it if not already there */ 976 if (keeplist != var) { 977 var->next = keeplist; 978 keeplist = var; 979 } 980 } else { 981 /* advance prev; we're keeping it on the doomed list */ 982 prev = &var->next; 983 } 984 } 985 986 /* kill old list */ 987 freed += free_varlist(list); 988 list = NULL; 989 990 if (found) { 991 /* kill new list too */ 992 freed += free_varlist(newlist); 993 newlist = newlistend = NULL; 994 } else { 995 /* new list becomes old list */ 996 list = newlist; 997 } 998 } 999 1000 if (LAZYSIG) 1001 restore_signals(); 1002 1003 if (found != NULL) { 1004 Int len = 0; 1005 Char file[100]; 1006 Int line; 1007 1008 /* Try to generate an idiomatic C-like expression from what 1009 we've found. */ 1010 1011 { 1012 Variable *v; 1013 for(v = found; v != NULL; v = v->container) { 1014 if (debug) 1015 VG_(printf)("v=%p (%s) %s\n", 1016 v, v->name ? v->name : (Char *)"", 1017 ppkind(v->type->kind)); 1018 1019 len += (v->name ? VG_(strlen)(v->name) : 0) + 5; 1020 } 1021 } 1022 1023 /* now that we know how long the expression will be 1024 (approximately) build it up */ 1025 { 1026 Char expr[len*2]; 1027 Char *sp = &expr[len]; /* pointer at start of string */ 1028 Char *ep = sp; /* pointer at end of string */ 1029 Bool ptr = True; 1030 1031 /* If the result is already a pointer, just use that as the 1032 value, otherwise generate &(...) around the expression. */ 1033 if (found->container && found->container->type->kind == TyPointer) { 1034 vg_assert(found->name == NULL); 1035 1036 found->name = found->container->name; 1037 found->container->name = NULL; 1038 found->container = found->container->container; 1039 } else { 1040 bprintf(describe_addr_addbuf, 0, "&("); 1041 ptr = False; 1042 } 1043 1044 genstring(found, NULL, &len, &ep, &sp); 1045 1046 if (!ptr) 1047 *ep++ = ')'; 1048 1049 *ep++ = '\0'; 1050 1051 bprintf(describe_addr_addbuf, 0, sp); 1052 1053 if (addr != found->valuep) 1054 bprintf(describe_addr_addbuf, 0, "+%d", addr - found->valuep); 1055 1056 if (VG_(get_filename_linenum)(eip, file, sizeof(file), 1057 NULL, 0, NULL, &line)) 1058 bprintf(describe_addr_addbuf, 0, " at %s:%d", file, line, addr); 1059 } 1060 } 1061 1062 freed += free_varlist(keeplist); 1063 1064 if (memaccount) 1065 VG_(printf)("created %d, freed %d\n", created, freed); 1066 1067 clear_visited(); 1068 1069 if (debug) 1070 VG_(printf)("returning buf=%s\n", describe_addr_buf); 1071 1072 return describe_addr_buf; 1073 } 1074 #endif /* TEST */ 1075 1076 /*--------------------------------------------------------------------*/ 1077 /*--- end ---*/ 1078 /*--------------------------------------------------------------------*/ 1079 1080 /*--------------------------------------------------------------------*/ 1081 /*--- Header for symbol table stuff. priv_symtab.h ---*/ 1082 /*--------------------------------------------------------------------*/ 1083 1084 /* 1085 This file is part of Valgrind, a dynamic binary instrumentation 1086 framework. 1087 1088 Copyright (C) 2000-2005 Julian Seward 1089 jseward (a] acm.org 1090 1091 This program is free software; you can redistribute it and/or 1092 modify it under the terms of the GNU General Public License as 1093 published by the Free Software Foundation; either version 2 of the 1094 License, or (at your option) any later version. 1095 1096 This program is distributed in the hope that it will be useful, but 1097 WITHOUT ANY WARRANTY; without even the implied warranty of 1098 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1099 General Public License for more details. 1100 1101 You should have received a copy of the GNU General Public License 1102 along with this program; if not, write to the Free Software 1103 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 1104 02111-1307, USA. 1105 1106 The GNU General Public License is contained in the file COPYING. 1107 */ 1108 1109 #ifndef __PRIV_SYMTAB_H 1110 #define __PRIV_SYMTAB_H 1111 1112 /* A structure to hold an ELF symbol (very crudely). */ 1113 typedef 1114 struct { 1115 Addr addr; /* lowest address of entity */ 1116 UInt size; /* size in bytes */ 1117 Char *name; /* name */ 1118 Addr tocptr; /* ppc64-linux only: value that R2 should have */ 1119 } 1120 RiSym; 1121 1122 /* Line count at which overflow happens, due to line numbers being stored as 1123 * shorts in `struct nlist' in a.out.h. */ 1124 #define LINENO_OVERFLOW (1 << (sizeof(short) * 8)) 1125 1126 #define LINENO_BITS 20 1127 #define LOC_SIZE_BITS (32 - LINENO_BITS) 1128 #define MAX_LINENO ((1 << LINENO_BITS) - 1) 1129 1130 /* Unlikely to have any lines with instruction ranges > 4096 bytes */ 1131 #define MAX_LOC_SIZE ((1 << LOC_SIZE_BITS) - 1) 1132 1133 /* Number used to detect line number overflows; if one line is 60000-odd 1134 * smaller than the previous, is was probably an overflow. 1135 */ 1136 #define OVERFLOW_DIFFERENCE (LINENO_OVERFLOW - 5000) 1137 1138 /* A structure to hold addr-to-source info for a single line. There can be a 1139 * lot of these, hence the dense packing. */ 1140 typedef 1141 struct { 1142 /* Word 1 */ 1143 Addr addr; /* lowest address for this line */ 1144 /* Word 2 */ 1145 UShort size:LOC_SIZE_BITS; /* byte size; we catch overflows of this */ 1146 UInt lineno:LINENO_BITS; /* source line number, or zero */ 1147 /* Word 3 */ 1148 Char* filename; /* source filename */ 1149 /* Word 4 */ 1150 Char* dirname; /* source directory name */ 1151 } 1152 RiLoc; 1153 1154 1155 /* A structure to hold a set of variables in a particular scope */ 1156 typedef struct _Scope Scope; /* a set of symbols in one scope */ 1157 typedef struct _Sym Sym; /* a single symbol */ 1158 typedef struct _ScopeRange ScopeRange; /* a range of code addreses a scope covers */ 1159 1160 typedef enum { 1161 SyESPrel, /* on the stack (relative to ESP) */ 1162 SyEBPrel, /* on the stack (relative to EBP) */ 1163 SyReg, /* in a register */ 1164 SyType, /* a type definition */ 1165 SyStatic, /* a static variable */ 1166 SyGlobal, /* a global variable (XXX any different to static 1167 in an outer scope?) */ 1168 } SyKind; 1169 1170 struct _Sym { 1171 SymType *type; /* type */ 1172 Char *name; /* name */ 1173 SyKind kind; /* kind of symbol */ 1174 1175 /* a value, depending on kind */ 1176 union { 1177 OffT offset; /* offset on stack (-ve -> ebp; +ve -> esp) */ 1178 Int regno; /* register number */ 1179 Addr addr; /* static or global address */ 1180 } u; 1181 }; 1182 1183 struct _Scope { 1184 Scope *outer; /* outer (containing) scope */ 1185 UInt nsyms; /* number of symbols in this scope */ 1186 UInt depth; /* depth of scope */ 1187 Sym *syms; /* the symbols */ 1188 }; 1189 1190 /* A structure to map a scope to a range of code addresses; scopes may 1191 be broken into multiple ranges (before and after a nested scope) */ 1192 struct _ScopeRange { 1193 Addr addr; /* start address of this scope */ 1194 Int size; /* length of scope */ 1195 Scope *scope; /* symbols in scope */ 1196 }; 1197 1198 #define STRCHUNKSIZE (64*1024) 1199 1200 1201 /* A structure to summarise CFI summary info for the code address 1202 range [base .. base+len-1]. In short, if you know (sp,fp,ip) at 1203 some point and ip is in the range [base .. base+len-1], it tells 1204 you how to calculate (sp,fp) for the caller of the current 1205 frame and also ra, the return address of the current frame. 1206 1207 First off, calculate CFA, the Canonical Frame Address, thusly: 1208 1209 cfa = if cfa_sprel then sp+cfa_off else fp+cfa_off 1210 1211 Once that is done, the previous frame's sp/fp values and this 1212 frame's ra value can be calculated like this: 1213 1214 old_sp/fp/ra 1215 = case sp/fp/ra_how of 1216 CFIR_UNKNOWN -> we don't know, sorry 1217 CFIR_SAME -> same as it was before (sp/fp only) 1218 CFIR_CFAREL -> cfa + sp/fp/ra_off 1219 CFIR_MEMCFAREL -> *( cfa + sp/fp/ra_off ) 1220 */ 1221 1222 #define CFIR_UNKNOWN ((UChar)0) 1223 #define CFIR_SAME ((UChar)1) 1224 #define CFIR_CFAREL ((UChar)2) 1225 #define CFIR_MEMCFAREL ((UChar)3) 1226 1227 typedef 1228 struct { 1229 Addr base; 1230 UInt len; 1231 Bool cfa_sprel; 1232 UChar ra_how; /* a CFIR_ value */ 1233 UChar sp_how; /* a CFIR_ value */ 1234 UChar fp_how; /* a CFIR_ value */ 1235 Int cfa_off; 1236 Int ra_off; 1237 Int sp_off; 1238 Int fp_off; 1239 } 1240 CfiSI; 1241 1242 extern void ML_(ppCfiSI) ( CfiSI* ); 1243 1244 1245 /* A structure which contains information pertaining to one mapped 1246 text segment. This type is exported only abstractly - in 1247 pub_tool_debuginfo.h. */ 1248 struct _SegInfo { 1249 struct _SegInfo* next; /* list of SegInfos */ 1250 1251 Int ref; 1252 1253 /* Description of the mapped segment. */ 1254 Addr start; 1255 UInt size; 1256 Char* filename; /* in mallocville */ 1257 OffT foffset; 1258 Char* soname; 1259 1260 /* An expandable array of symbols. */ 1261 RiSym* symtab; 1262 UInt symtab_used; 1263 UInt symtab_size; 1264 /* An expandable array of locations. */ 1265 RiLoc* loctab; 1266 UInt loctab_used; 1267 UInt loctab_size; 1268 /* An expandable array of scope ranges. */ 1269 ScopeRange *scopetab; 1270 UInt scopetab_used; 1271 UInt scopetab_size; 1272 /* An expandable array of CFI summary info records. Also includes 1273 summary address bounds, showing the min and max address covered 1274 by any of the records, as an aid to fast searching. */ 1275 CfiSI* cfisi; 1276 UInt cfisi_used; 1277 UInt cfisi_size; 1278 Addr cfisi_minaddr; 1279 Addr cfisi_maxaddr; 1280 1281 /* Expandable arrays of characters -- the string table. 1282 Pointers into this are stable (the arrays are not reallocated) 1283 */ 1284 struct strchunk { 1285 UInt strtab_used; 1286 struct strchunk *next; 1287 Char strtab[STRCHUNKSIZE]; 1288 } *strchunks; 1289 1290 /* offset is what we need to add to symbol table entries 1291 to get the real location of that symbol in memory. 1292 */ 1293 OffT offset; 1294 1295 /* Bounds of data, BSS, PLT, GOT and OPD (for ppc64-linux) so that 1296 tools can see what section an address is in. In the running image! */ 1297 Addr plt_start_vma; 1298 UInt plt_size; 1299 Addr got_start_vma; 1300 UInt got_size; 1301 Addr opd_start_vma; 1302 UInt opd_size; 1303 Addr data_start_vma; 1304 UInt data_size; 1305 Addr bss_start_vma; 1306 UInt bss_size; 1307 1308 /* data used by stabs parser */ 1309 struct _StabTypeTab *stab_typetab; 1310 }; 1311 1312 extern 1313 Char *ML_(addStr) ( SegInfo* si, Char* str, Int len ); 1314 1315 extern 1316 void ML_(addScopeInfo) ( SegInfo* si, Addr this, Addr next, Scope *scope); 1317 1318 extern 1319 void ML_(addLineInfo) ( SegInfo* si, 1320 Char* filename, 1321 Char* dirname, /* NULL is allowable */ 1322 Addr this, Addr next, Int lineno, Int entry); 1323 1324 extern 1325 void ML_(addCfiSI) ( SegInfo* si, CfiSI* cfisi ); 1326 1327 /* Non-fatal -- use vg_panic if terminal. */ 1328 extern 1329 void ML_(symerr) ( Char* msg ); 1330 1331 /* -------------------- 1332 Stabs reader 1333 -------------------- */ 1334 extern 1335 void ML_(read_debuginfo_stabs) ( SegInfo* si, 1336 UChar* stabC, Int stab_sz, 1337 UChar* stabstr, Int stabstr_sz ); 1338 1339 /* -------------------- 1340 DWARF2 reader 1341 -------------------- */ 1342 extern 1343 void ML_(read_debuginfo_dwarf2) 1344 ( SegInfo* si, 1345 UChar* debuginfo, Int debug_info_sz, /* .debug_info */ 1346 UChar* debugabbrev, /* .debug_abbrev */ 1347 UChar* debugline, Int debug_line_sz, /* .debug_line */ 1348 UChar* debugstr ); 1349 1350 /* -------------------- 1351 DWARF1 reader 1352 -------------------- */ 1353 extern 1354 void ML_(read_debuginfo_dwarf1) ( SegInfo* si, 1355 UChar* dwarf1d, Int dwarf1d_sz, 1356 UChar* dwarf1l, Int dwarf1l_sz ); 1357 1358 /* -------------------- 1359 CFI reader 1360 -------------------- */ 1361 extern 1362 void ML_(read_callframe_info_dwarf2) 1363 ( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz, Addr ehframe_addr ); 1364 1365 1366 #endif // __PRIV_SYMTAB_H 1367 1368 /*--------------------------------------------------------------------*/ 1369 /*--- end ---*/ 1370 /*--------------------------------------------------------------------*/ 1371 1372 /*--------------------------------------------------------------------*/ 1373 /*--- Intra-Valgrind interfaces for symtypes.c. priv_symtypes.h ---*/ 1374 /*--------------------------------------------------------------------*/ 1375 1376 /* 1377 This file is part of Valgrind, a dynamic binary instrumentation 1378 framework. 1379 1380 Copyright (C) 2000-2005 Julian Seward 1381 jseward (a] acm.org 1382 1383 This program is free software; you can redistribute it and/or 1384 modify it under the terms of the GNU General Public License as 1385 published by the Free Software Foundation; either version 2 of the 1386 License, or (at your option) any later version. 1387 1388 This program is distributed in the hope that it will be useful, but 1389 WITHOUT ANY WARRANTY; without even the implied warranty of 1390 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1391 General Public License for more details. 1392 1393 You should have received a copy of the GNU General Public License 1394 along with this program; if not, write to the Free Software 1395 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 1396 02111-1307, USA. 1397 1398 The GNU General Public License is contained in the file COPYING. 1399 */ 1400 1401 #ifndef __PRIV_SYMTYPES_H 1402 #define __PRIV_SYMTYPES_H 1403 1404 /* Lets try to make these opaque */ 1405 typedef struct _SymType SymType; 1406 1407 /* ------------------------------------------------------------ 1408 Constructors for various SymType nodes 1409 ------------------------------------------------------------ */ 1410 1411 /* Find the basetype for a given type: that is, if type is a typedef, 1412 return the typedef'd type. If resolve is true, it will resolve 1413 unresolved symbols. If type is not a typedef, then this is just 1414 returns type. 1415 */ 1416 SymType *ML_(st_basetype)(SymType *type, Bool resolve); 1417 1418 void ML_(st_setname)(SymType *ty, Char *name); 1419 1420 typedef void (SymResolver)(SymType *, void *); 1421 1422 /* Create an unresolved type */ 1423 SymType *ML_(st_mkunresolved)(SymType *, SymResolver *resolve, void *data); 1424 1425 /* update an unresolved type's data */ 1426 void ML_(st_unresolved_setdata)(SymType *, SymResolver *resolve, void *data); 1427 1428 Bool ML_(st_isresolved)(SymType *); 1429 UInt ML_(st_sizeof)(SymType *); 1430 1431 /* Unknown type (unparsable) */ 1432 SymType *ML_(st_mkunknown)(SymType *); 1433 1434 SymType *ML_(st_mkvoid)(SymType *); 1435 1436 SymType *ML_(st_mkint)(SymType *, UInt size, Bool isSigned); 1437 SymType *ML_(st_mkbool)(SymType *, UInt size); 1438 SymType *ML_(st_mkchar)(SymType *, Bool isSigned); 1439 SymType *ML_(st_mkfloat)(SymType *, UInt size); 1440 SymType *ML_(st_mkdouble)(SymType *, UInt size); 1441 1442 SymType *ML_(st_mkpointer)(SymType *, SymType *); 1443 SymType *ML_(st_mkrange)(SymType *, SymType *, Int min, Int max); 1444 1445 SymType *ML_(st_mkstruct)(SymType *, UInt size, UInt nfields); 1446 SymType *ML_(st_mkunion)(SymType *, UInt size, UInt nfields); 1447 void ML_(st_addfield)(SymType *, Char *name, SymType *, UInt off, UInt size); 1448 1449 SymType *ML_(st_mkenum)(SymType *, UInt ntags); 1450 SymType *ML_(st_addtag)(SymType *, Char *name, Int val); 1451 1452 SymType *ML_(st_mkarray)(SymType *, SymType *idxtype, SymType *artype); 1453 1454 SymType *ML_(st_mktypedef)(SymType *, Char *name, SymType *type); 1455 1456 Bool ML_(st_isstruct)(SymType *); 1457 Bool ML_(st_isunion)(SymType *); 1458 Bool ML_(st_isenum)(SymType *); 1459 1460 /* ------------------------------------------------------------ 1461 Interface with symtab.c 1462 ------------------------------------------------------------ */ 1463 1464 /* Typed value */ 1465 typedef struct _Variable Variable; 1466 1467 struct _Variable { 1468 Char *name; /* name */ 1469 SymType *type; /* type of value */ 1470 Addr valuep; /* pointer to value */ 1471 UInt size; /* size of value */ 1472 UInt distance; /* "distance" from site of interest */ 1473 Variable *next; 1474 Variable *container; 1475 }; 1476 1477 Variable *ML_(get_scope_variables)(ThreadId tid); 1478 1479 #endif // __PRIV_SYMTYPES_H 1480 1481 /*--------------------------------------------------------------------*/ 1482 /*--- end ---*/ 1483 /*--------------------------------------------------------------------*/ 1484