Home | History | Annotate | Download | only in m_debuginfo
      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