Home | History | Annotate | Download | only in m_debuginfo
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Top level management of symbols and debugging information.   ---*/
      4 /*---                                                  debuginfo.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2000-2013 Julian Seward
     12       jseward (at) acm.org
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 #include "pub_core_basics.h"
     33 #include "pub_core_vki.h"
     34 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
     35 #include "pub_core_threadstate.h"
     36 #include "pub_core_debuginfo.h"  /* self */
     37 #include "pub_core_demangle.h"
     38 #include "pub_core_libcbase.h"
     39 #include "pub_core_libcassert.h"
     40 #include "pub_core_libcprint.h"
     41 #include "pub_core_libcfile.h"
     42 #include "pub_core_libcproc.h"   // VG_(getenv)
     43 #include "pub_core_seqmatch.h"
     44 #include "pub_core_options.h"
     45 #include "pub_core_redir.h"      // VG_(redir_notify_{new,delete}_SegInfo)
     46 #include "pub_core_aspacemgr.h"
     47 #include "pub_core_machine.h"    // VG_PLAT_USES_PPCTOC
     48 #include "pub_core_xarray.h"
     49 #include "pub_core_oset.h"
     50 #include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency
     51 #include "pub_core_ume.h"
     52 
     53 #include "priv_misc.h"           /* dinfo_zalloc/free */
     54 #include "priv_image.h"
     55 #include "priv_d3basics.h"       /* ML_(pp_GX) */
     56 #include "priv_tytypes.h"
     57 #include "priv_storage.h"
     58 #include "priv_readdwarf.h"
     59 #include "priv_readstabs.h"
     60 #if defined(VGO_linux)
     61 # include "priv_readelf.h"
     62 # include "priv_readdwarf3.h"
     63 # include "priv_readpdb.h"
     64 #elif defined(VGO_darwin)
     65 # include "priv_readmacho.h"
     66 # include "priv_readpdb.h"
     67 #endif
     68 
     69 
     70 /*------------------------------------------------------------*/
     71 /*--- The _svma / _avma / _image / _bias naming scheme     ---*/
     72 /*------------------------------------------------------------*/
     73 
     74 /* JRS 11 Jan 07: I find the different kinds of addresses involved in
     75    debuginfo reading confusing.  Recently I arrived at some
     76    terminology which makes it clearer (to me, at least).  There are 3
     77    kinds of address used in the debuginfo reading process:
     78 
     79    stated VMAs - the address where (eg) a .so says a symbol is, that
     80                  is, what it tells you if you consider the .so in
     81                  isolation
     82 
     83    actual VMAs - the address where (eg) said symbol really wound up
     84                  after the .so was mapped into memory
     85 
     86    image addresses - pointers into the copy of the .so (etc)
     87                      transiently mmaped aboard whilst we read its info
     88 
     89    Additionally I use the term 'bias' to denote the difference
     90    between stated and actual VMAs for a given entity.
     91 
     92    This terminology is not used consistently, but a start has been
     93    made.  readelf.c and the call-frame info reader in readdwarf.c now
     94    use it.  Specifically, various variables and structure fields have
     95    been annotated with _avma / _svma / _image / _bias.  In places _img
     96    is used instead of _image for the sake of brevity.
     97 */
     98 
     99 
    100 /*------------------------------------------------------------*/
    101 /*--- fwdses                                               ---*/
    102 /*------------------------------------------------------------*/
    103 
    104 static UInt CF_info_generation = 0;
    105 static void cfsi_cache__invalidate ( void );
    106 
    107 
    108 /*------------------------------------------------------------*/
    109 /*--- Root structure                                       ---*/
    110 /*------------------------------------------------------------*/
    111 
    112 /* The root structure for the entire debug info system.  It is a
    113    linked list of DebugInfos. */
    114 static DebugInfo* debugInfo_list = NULL;
    115 
    116 
    117 /* Find 'di' in the debugInfo_list and move it one step closer the the
    118    front of the list, so as to make subsequent searches for it
    119    cheaper.  When used in a controlled way, makes a major improvement
    120    in some DebugInfo-search-intensive situations, most notably stack
    121    unwinding on amd64-linux. */
    122 static void move_DebugInfo_one_step_forward ( DebugInfo* di )
    123 {
    124    DebugInfo *di0, *di1, *di2;
    125    if (di == debugInfo_list)
    126       return; /* already at head of list */
    127    vg_assert(di != NULL);
    128    di0 = debugInfo_list;
    129    di1 = NULL;
    130    di2 = NULL;
    131    while (True) {
    132       if (di0 == NULL || di0 == di) break;
    133       di2 = di1;
    134       di1 = di0;
    135       di0 = di0->next;
    136    }
    137    vg_assert(di0 == di);
    138    if (di0 != NULL && di1 != NULL && di2 != NULL) {
    139       DebugInfo* tmp;
    140       /* di0 points to di, di1 to its predecessor, and di2 to di1's
    141          predecessor.  Swap di0 and di1, that is, move di0 one step
    142          closer to the start of the list. */
    143       vg_assert(di2->next == di1);
    144       vg_assert(di1->next == di0);
    145       tmp = di0->next;
    146       di2->next = di0;
    147       di0->next = di1;
    148       di1->next = tmp;
    149    }
    150    else
    151    if (di0 != NULL && di1 != NULL && di2 == NULL) {
    152       /* it's second in the list. */
    153       vg_assert(debugInfo_list == di1);
    154       vg_assert(di1->next == di0);
    155       di1->next = di0->next;
    156       di0->next = di1;
    157       debugInfo_list = di0;
    158    }
    159 }
    160 
    161 
    162 /*------------------------------------------------------------*/
    163 /*--- Notification (acquire/discard) helpers               ---*/
    164 /*------------------------------------------------------------*/
    165 
    166 /* Gives out unique abstract handles for allocated DebugInfos.  See
    167    comment in priv_storage.h, declaration of struct _DebugInfo, for
    168    details. */
    169 static ULong handle_counter = 1;
    170 
    171 /* Allocate and zero out a new DebugInfo record. */
    172 static
    173 DebugInfo* alloc_DebugInfo( const HChar* filename )
    174 {
    175    Bool       traceme;
    176    DebugInfo* di;
    177 
    178    vg_assert(filename);
    179 
    180    di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo));
    181    di->handle       = handle_counter++;
    182    di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename);
    183    di->fsm.maps     = VG_(newXA)(
    184                          ML_(dinfo_zalloc), "di.debuginfo.aDI.3",
    185                          ML_(dinfo_free), sizeof(struct _DebugInfoMapping));
    186 
    187    /* Everything else -- pointers, sizes, arrays -- is zeroed by
    188       ML_(dinfo_zalloc).  Now set up the debugging-output flags. */
    189    traceme
    190       = VG_(string_match)( VG_(clo_trace_symtab_patt), filename );
    191    if (traceme) {
    192       di->trace_symtab = VG_(clo_trace_symtab);
    193       di->trace_cfi    = VG_(clo_trace_cfi);
    194       di->ddump_syms   = VG_(clo_debug_dump_syms);
    195       di->ddump_line   = VG_(clo_debug_dump_line);
    196       di->ddump_frames = VG_(clo_debug_dump_frames);
    197    }
    198 
    199    return di;
    200 }
    201 
    202 
    203 /* Free a DebugInfo, and also all the stuff hanging off it. */
    204 static void free_DebugInfo ( DebugInfo* di )
    205 {
    206    Word i, j, n;
    207    struct strchunk *chunk, *next;
    208    TyEnt* ent;
    209    GExpr* gexpr;
    210 
    211    vg_assert(di != NULL);
    212    if (di->fsm.maps)     VG_(deleteXA)(di->fsm.maps);
    213    if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename);
    214    if (di->soname)       ML_(dinfo_free)(di->soname);
    215    if (di->loctab)       ML_(dinfo_free)(di->loctab);
    216    if (di->cfsi)         ML_(dinfo_free)(di->cfsi);
    217    if (di->cfsi_exprs)   VG_(deleteXA)(di->cfsi_exprs);
    218    if (di->fpo)          ML_(dinfo_free)(di->fpo);
    219 
    220    if (di->symtab) {
    221       /* We have to visit all the entries so as to free up any
    222          sec_names arrays that might exist. */
    223       n = di->symtab_used;
    224       for (i = 0; i < n; i++) {
    225          DiSym* sym = &di->symtab[i];
    226          if (sym->sec_names)
    227             ML_(dinfo_free)(sym->sec_names);
    228       }
    229       /* and finally .. */
    230       ML_(dinfo_free)(di->symtab);
    231    }
    232 
    233    for (chunk = di->strchunks; chunk != NULL; chunk = next) {
    234       next = chunk->next;
    235       ML_(dinfo_free)(chunk);
    236    }
    237 
    238    /* Delete the two admin arrays.  These lists exist primarily so
    239       that we can visit each object exactly once when we need to
    240       delete them. */
    241    if (di->admin_tyents) {
    242       n = VG_(sizeXA)(di->admin_tyents);
    243       for (i = 0; i < n; i++) {
    244          ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i);
    245          /* Dump anything hanging off this ent */
    246          ML_(TyEnt__make_EMPTY)(ent);
    247       }
    248       VG_(deleteXA)(di->admin_tyents);
    249       di->admin_tyents = NULL;
    250    }
    251 
    252    if (di->admin_gexprs) {
    253       n = VG_(sizeXA)(di->admin_gexprs);
    254       for (i = 0; i < n; i++) {
    255          gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i);
    256          ML_(dinfo_free)(gexpr);
    257       }
    258       VG_(deleteXA)(di->admin_gexprs);
    259       di->admin_gexprs = NULL;
    260    }
    261 
    262    /* Dump the variable info.  This is kinda complex: we must take
    263       care not to free items which reside in either the admin lists
    264       (as we have just freed them) or which reside in the DebugInfo's
    265       string table. */
    266    if (di->varinfo) {
    267       for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
    268          OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
    269          if (!scope) continue;
    270          /* iterate over all entries in 'scope' */
    271          VG_(OSetGen_ResetIter)(scope);
    272          while (True) {
    273             DiAddrRange* arange = VG_(OSetGen_Next)(scope);
    274             if (!arange) break;
    275             /* for each var in 'arange' */
    276             vg_assert(arange->vars);
    277             for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) {
    278                DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j);
    279                vg_assert(var);
    280                /* Nothing to free in var: all the pointer fields refer
    281                   to stuff either on an admin list, or in
    282                   .strchunks */
    283             }
    284             VG_(deleteXA)(arange->vars);
    285             /* Don't free arange itself, as OSetGen_Destroy does
    286                that */
    287          }
    288          VG_(OSetGen_Destroy)(scope);
    289       }
    290       VG_(deleteXA)(di->varinfo);
    291    }
    292 
    293    ML_(dinfo_free)(di);
    294 }
    295 
    296 
    297 /* 'si' is a member of debugInfo_list.  Find it, remove it from the
    298    list, notify m_redir that this has happened, and free all storage
    299    reachable from it.
    300 */
    301 static void discard_DebugInfo ( DebugInfo* di )
    302 {
    303    const HChar* reason = "munmap";
    304 
    305    DebugInfo** prev_next_ptr = &debugInfo_list;
    306    DebugInfo*  curr          =  debugInfo_list;
    307 
    308    while (curr) {
    309       if (curr == di) {
    310          /* Found it;  remove from list and free it. */
    311          if (curr->have_dinfo
    312              && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)))
    313             VG_(message)(Vg_DebugMsg,
    314                          "Discarding syms at %#lx-%#lx in %s due to %s()\n",
    315                          di->text_avma,
    316                          di->text_avma + di->text_size,
    317                          curr->fsm.filename ? curr->fsm.filename
    318                                             : "???",
    319                          reason);
    320          vg_assert(*prev_next_ptr == curr);
    321          *prev_next_ptr = curr->next;
    322          if (curr->have_dinfo)
    323             VG_(redir_notify_delete_DebugInfo)( curr );
    324          free_DebugInfo(curr);
    325          return;
    326       }
    327       prev_next_ptr = &curr->next;
    328       curr          =  curr->next;
    329    }
    330 
    331    /* Not found. */
    332 }
    333 
    334 
    335 /* Repeatedly scan debugInfo_list, looking for DebugInfos with text
    336    AVMAs intersecting [start,start+length), and call discard_DebugInfo
    337    to get rid of them.  This modifies the list, hence the multiple
    338    iterations.  Returns True iff any such DebugInfos were found.
    339 */
    340 static Bool discard_syms_in_range ( Addr start, SizeT length )
    341 {
    342    Bool       anyFound = False;
    343    Bool       found;
    344    DebugInfo* curr;
    345 
    346    while (True) {
    347       found = False;
    348 
    349       curr = debugInfo_list;
    350       while (True) {
    351          if (curr == NULL)
    352             break;
    353          if (curr->text_present
    354              && curr->text_size > 0
    355              && (start+length - 1 < curr->text_avma
    356                  || curr->text_avma + curr->text_size - 1 < start)) {
    357             /* no overlap */
    358 	 } else {
    359 	    found = True;
    360 	    break;
    361 	 }
    362 	 curr = curr->next;
    363       }
    364 
    365       if (!found) break;
    366       anyFound = True;
    367       discard_DebugInfo( curr );
    368    }
    369 
    370    return anyFound;
    371 }
    372 
    373 
    374 /* Does [s1,+len1) overlap [s2,+len2) ?  Note: does not handle
    375    wraparound at the end of the address space -- just asserts in that
    376    case. */
    377 static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
    378 {
    379    Addr e1, e2;
    380    if (len1 == 0 || len2 == 0)
    381       return False;
    382    e1 = s1 + len1 - 1;
    383    e2 = s2 + len2 - 1;
    384    /* Assert that we don't have wraparound.  If we do it would imply
    385       that file sections are getting mapped around the end of the
    386       address space, which sounds unlikely. */
    387    vg_assert(s1 <= e1);
    388    vg_assert(s2 <= e2);
    389    if (e1 < s2 || e2 < s1) return False;
    390    return True;
    391 }
    392 
    393 
    394 /* Do the basic mappings of the two DebugInfos overlap in any way? */
    395 static Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 )
    396 {
    397    Word i, j;
    398    vg_assert(di1);
    399    vg_assert(di2);
    400    for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) {
    401       struct _DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i);
    402       for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
    403          struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
    404          if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size))
    405             return True;
    406       }
    407    }
    408 
    409    return False;
    410 }
    411 
    412 
    413 /* Discard all elements of debugInfo_list whose .mark bit is set.
    414 */
    415 static void discard_marked_DebugInfos ( void )
    416 {
    417    DebugInfo* curr;
    418 
    419    while (True) {
    420 
    421       curr = debugInfo_list;
    422       while (True) {
    423          if (!curr)
    424             break;
    425          if (curr->mark)
    426             break;
    427 	 curr = curr->next;
    428       }
    429 
    430       if (!curr) break;
    431       discard_DebugInfo( curr );
    432 
    433    }
    434 }
    435 
    436 
    437 /* Discard any elements of debugInfo_list which overlap with diRef.
    438    Clearly diRef must have its mapping information set to something sane. */
    439 static void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef )
    440 {
    441    DebugInfo* di;
    442    /* Mark all the DebugInfos in debugInfo_list that need to be
    443       deleted.  First, clear all the mark bits; then set them if they
    444       overlap with siRef.  Since siRef itself is in this list we at
    445       least expect its own mark bit to be set. */
    446    for (di = debugInfo_list; di; di = di->next) {
    447       di->mark = do_DebugInfos_overlap( di, diRef );
    448       if (di == diRef) {
    449          vg_assert(di->mark);
    450          di->mark = False;
    451       }
    452    }
    453    discard_marked_DebugInfos();
    454 }
    455 
    456 
    457 /* Find the existing DebugInfo for |filename| or if not found, create
    458    one.  In the latter case |filename| is strdup'd into VG_AR_DINFO,
    459    and the new DebugInfo is added to debugInfo_list. */
    460 static DebugInfo* find_or_create_DebugInfo_for ( HChar* filename )
    461 {
    462    DebugInfo* di;
    463    vg_assert(filename);
    464    for (di = debugInfo_list; di; di = di->next) {
    465       vg_assert(di->fsm.filename);
    466       if (0==VG_(strcmp)(di->fsm.filename, filename))
    467          break;
    468    }
    469    if (!di) {
    470       di = alloc_DebugInfo(filename);
    471       vg_assert(di);
    472       di->next = debugInfo_list;
    473       debugInfo_list = di;
    474    }
    475    return di;
    476 }
    477 
    478 
    479 /* Debuginfo reading for 'di' has just been successfully completed.
    480    Check that the invariants stated in
    481    "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
    482    priv_storage.h are observed. */
    483 static void check_CFSI_related_invariants ( DebugInfo* di )
    484 {
    485    DebugInfo* di2 = NULL;
    486    Bool has_nonempty_rx = False;
    487    Bool cfsi_fits = False;
    488    Word i, j;
    489    vg_assert(di);
    490    /* This fn isn't called until after debuginfo for this object has
    491       been successfully read.  And that shouldn't happen until we have
    492       both a r-x and rw- mapping for the object.  Hence: */
    493    vg_assert(di->fsm.have_rx_map);
    494    vg_assert(di->fsm.have_rw_map);
    495    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
    496       struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
    497       /* We are interested in r-x mappings only */
    498       if (!map->rx)
    499          continue;
    500 
    501       /* degenerate case: r-x section is empty */
    502       if (map->size == 0)
    503          continue;
    504       has_nonempty_rx = True;
    505 
    506       /* normal case: r-x section is nonempty */
    507       /* invariant (0) */
    508       vg_assert(map->size > 0);
    509 
    510       /* invariant (1) */
    511       for (di2 = debugInfo_list; di2; di2 = di2->next) {
    512          if (di2 == di)
    513             continue;
    514          for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
    515             struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
    516             if (!map2->rx || map2->size == 0)
    517                continue;
    518             vg_assert(!ranges_overlap(map->avma,  map->size,
    519                                       map2->avma, map2->size));
    520          }
    521       }
    522       di2 = NULL;
    523 
    524       /* invariant (2) */
    525       if (di->cfsi) {
    526          vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */
    527          /* Assume the csfi fits completely into one individual mapping
    528             for now. This might need to be improved/reworked later. */
    529          if (di->cfsi_minavma >= map->avma &&
    530              di->cfsi_maxavma <  map->avma + map->size)
    531             cfsi_fits = True;
    532       }
    533    }
    534 
    535    /* degenerate case: all r-x sections are empty */
    536    if (!has_nonempty_rx) {
    537       vg_assert(di->cfsi == NULL);
    538       return;
    539    }
    540 
    541    /* invariant (2) - cont. */
    542    if (di->cfsi)
    543       vg_assert(cfsi_fits);
    544 
    545    /* invariants (3) and (4) */
    546    if (di->cfsi) {
    547       vg_assert(di->cfsi_used > 0);
    548       vg_assert(di->cfsi_size > 0);
    549       for (i = 0; i < di->cfsi_used; i++) {
    550          DiCfSI* cfsi = &di->cfsi[i];
    551          vg_assert(cfsi->len > 0);
    552          vg_assert(cfsi->base >= di->cfsi_minavma);
    553          vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma);
    554          if (i > 0) {
    555             DiCfSI* cfsip = &di->cfsi[i-1];
    556             vg_assert(cfsip->base + cfsip->len <= cfsi->base);
    557          }
    558       }
    559    } else {
    560       vg_assert(di->cfsi_used == 0);
    561       vg_assert(di->cfsi_size == 0);
    562    }
    563 }
    564 
    565 
    566 /*--------------------------------------------------------------*/
    567 /*---                                                        ---*/
    568 /*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM             ---*/
    569 /*---                                                        ---*/
    570 /*--------------------------------------------------------------*/
    571 
    572 void VG_(di_initialise) ( void )
    573 {
    574    /* There's actually very little to do here, since everything
    575       centers around the DebugInfos in debugInfo_list, they are
    576       created and destroyed on demand, and each one is treated more or
    577       less independently. */
    578    vg_assert(debugInfo_list == NULL);
    579 
    580    /* flush the CFI fast query cache. */
    581    cfsi_cache__invalidate();
    582 }
    583 
    584 
    585 /*--------------------------------------------------------------*/
    586 /*---                                                        ---*/
    587 /*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
    588 /*---                                                        ---*/
    589 /*--------------------------------------------------------------*/
    590 
    591 #if defined(VGO_linux)  ||  defined(VGO_darwin)
    592 
    593 /* The debug info system is driven by notifications that a text
    594    segment has been mapped in, or unmapped, or when sections change
    595    permission.  It's all a bit kludgey and basically means watching
    596    syscalls, trying to second-guess when the system's dynamic linker
    597    is done with mapping in a new object for execution.  This is all
    598    tracked using the DebugInfoFSM struct for the object.  Anyway, once
    599    we finally decide we've got to an accept state, this section then
    600    will acquire whatever info is available for the corresponding
    601    object.  This section contains the notification handlers, which
    602    update the FSM and determine when an accept state has been reached.
    603 */
    604 
    605 /* When the sequence of observations causes a DebugInfoFSM to move
    606    into the accept state, call here to actually get the debuginfo read
    607    in.  Returns a ULong whose purpose is described in comments
    608    preceding VG_(di_notify_mmap) just below.
    609 */
    610 static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
    611 {
    612    ULong di_handle;
    613    Bool  ok;
    614 
    615    vg_assert(di->fsm.filename);
    616    TRACE_SYMTAB("\n");
    617    TRACE_SYMTAB("------ start ELF OBJECT "
    618                 "------------------------------\n");
    619    TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
    620    TRACE_SYMTAB("\n");
    621 
    622    /* We're going to read symbols and debug info for the avma
    623       ranges specified in the _DebugInfoFsm mapping array. First
    624       get rid of any other DebugInfos which overlap any of those
    625       ranges (to avoid total confusion). */
    626    discard_DebugInfos_which_overlap_with( di );
    627 
    628    /* .. and acquire new info. */
    629 #  if defined(VGO_linux)
    630    ok = ML_(read_elf_debug_info)( di );
    631 #  elif defined(VGO_darwin)
    632    ok = ML_(read_macho_debug_info)( di );
    633 #  else
    634 #    error "unknown OS"
    635 #  endif
    636 
    637    if (ok) {
    638 
    639       TRACE_SYMTAB("\n------ Canonicalising the "
    640                    "acquired info ------\n");
    641       /* invalidate the CFI unwind cache. */
    642       cfsi_cache__invalidate();
    643       /* prepare read data for use */
    644       ML_(canonicaliseTables)( di );
    645       /* notify m_redir about it */
    646       TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
    647       VG_(redir_notify_new_DebugInfo)( di );
    648       /* Note that we succeeded */
    649       di->have_dinfo = True;
    650       tl_assert(di->handle > 0);
    651       di_handle = di->handle;
    652       /* Check invariants listed in
    653          Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
    654          priv_storage.h. */
    655       check_CFSI_related_invariants(di);
    656 
    657    } else {
    658       TRACE_SYMTAB("\n------ ELF reading failed ------\n");
    659       /* Something went wrong (eg. bad ELF file).  Should we delete
    660          this DebugInfo?  No - it contains info on the rw/rx
    661          mappings, at least. */
    662       di_handle = 0;
    663       vg_assert(di->have_dinfo == False);
    664    }
    665 
    666    TRACE_SYMTAB("\n");
    667    TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
    668    TRACE_SYMTAB("------ end ELF OBJECT "
    669                 "------------------------------\n");
    670    TRACE_SYMTAB("\n");
    671 
    672    return di_handle;
    673 }
    674 
    675 
    676 /* Notify the debuginfo system about a new mapping.  This is the way
    677    new debug information gets loaded.  If allow_SkFileV is True, it
    678    will try load debug info if the mapping at 'a' belongs to Valgrind;
    679    whereas normally (False) it will not do that.  This allows us to
    680    carefully control when the thing will read symbols from the
    681    Valgrind executable itself.
    682 
    683    If use_fd is not -1, that is used instead of the filename; this
    684    avoids perturbing fcntl locks, which are released by simply
    685    re-opening and closing the same file (even via different fd!).
    686 
    687    If a call to VG_(di_notify_mmap) causes debug info to be read, then
    688    the returned ULong is an abstract handle which can later be used to
    689    refer to the debuginfo read as a result of this specific mapping,
    690    in later queries to m_debuginfo.  In this case the handle value
    691    will be one or above.  If the returned value is zero, no debug info
    692    was read. */
    693 
    694 ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
    695 {
    696    NSegment const * seg;
    697    HChar*     filename;
    698    Bool       is_rx_map, is_rw_map, is_ro_map;
    699    DebugInfo* di;
    700    Int        actual_fd, oflags;
    701    SysRes     preadres;
    702    HChar      buf1k[1024];
    703    Bool       debug = False;
    704    SysRes     statres;
    705    struct vg_stat statbuf;
    706 
    707    vg_assert(use_fd >= -1);
    708 
    709    /* In short, figure out if this mapping is of interest to us, and
    710       if so, try to guess what ld.so is doing and when/if we should
    711       read debug info. */
    712    seg = VG_(am_find_nsegment)(a);
    713    vg_assert(seg);
    714 
    715    if (debug)
    716       VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n",
    717                   seg->start, seg->end,
    718                   seg->hasR ? 'r' : '-',
    719                   seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
    720 
    721    /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
    722    vg_assert(seg->end > seg->start);
    723 
    724    /* Ignore non-file mappings */
    725    if ( ! (seg->kind == SkFileC
    726            || (seg->kind == SkFileV && allow_SkFileV)) )
    727       return 0;
    728 
    729    /* If the file doesn't have a name, we're hosed.  Give up. */
    730    filename = VG_(am_get_filename)( seg );
    731    if (!filename)
    732       return 0;
    733 
    734    /*
    735     * Cannot read from these magic files:
    736     * --20208-- WARNING: Serious error when reading debug info
    737     * --20208-- When reading debug info from /proc/xen/privcmd:
    738     * --20208-- can't read file to inspect ELF header
    739     */
    740    if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0)
    741       return 0;
    742 
    743    if (debug)
    744       VG_(printf)("di_notify_mmap-2: %s\n", filename);
    745 
    746    /* Only try to read debug information from regular files.  */
    747    statres = VG_(stat)(filename, &statbuf);
    748 
    749    /* stat dereferences symlinks, so we don't expect it to succeed and
    750       yet produce something that is a symlink. */
    751    vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode));
    752 
    753    /* Don't let the stat call fail silently.  Filter out some known
    754       sources of noise before complaining, though. */
    755    if (sr_isError(statres)) {
    756       DebugInfo fake_di;
    757       Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL;
    758       if (!quiet && VG_(clo_verbosity) > 1) {
    759          VG_(memset)(&fake_di, 0, sizeof(fake_di));
    760          fake_di.fsm.filename = filename;
    761          ML_(symerr)(&fake_di, True, "failed to stat64/stat this file");
    762       }
    763       return 0;
    764    }
    765 
    766    /* Finally, the point of all this stattery: if it's not a regular file,
    767       don't try to read debug info from it. */
    768    if (! VKI_S_ISREG(statbuf.mode))
    769       return 0;
    770 
    771    /* no uses of statbuf below here. */
    772 
    773    /* Now we have to guess if this is a text-like mapping, a data-like
    774       mapping, neither or both.  The rules are:
    775 
    776         text if:   x86-linux    r and x
    777                    other-linux  r and x and not w
    778 
    779         data if:   x86-linux    r and w
    780                    other-linux  r and w and not x
    781 
    782       Background: On x86-linux, objects are typically mapped twice:
    783 
    784       1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
    785       1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
    786 
    787       whereas ppc32-linux mysteriously does this:
    788 
    789       118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
    790       118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
    791       118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
    792 
    793       The third mapping should not be considered to have executable
    794       code in.  Therefore a test which works for both is: r and x and
    795       NOT w.  Reading symbols from the rwx segment -- which overlaps
    796       the r-x segment in the file -- causes the redirection mechanism
    797       to redirect to addresses in that third segment, which is wrong
    798       and causes crashes.
    799 
    800       JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
    801       produce executables with a single rwx segment rather than a
    802       (r-x,rw-) pair. That means the rules have to be modified thusly:
    803 
    804       x86-linux:   consider if r and x
    805       all others:  consider if r and x and not w
    806 
    807       2009 Aug 16: apply similar kludge to ppc32-linux.
    808       See http://bugs.kde.org/show_bug.cgi?id=190820
    809 
    810       There are two modes on s390x: with and without the noexec kernel
    811       parameter. Together with some older kernels, this leads to several
    812       variants:
    813       executable: r and x
    814       data:       r and w and x
    815       or
    816       executable: r and x
    817       data:       r and w
    818    */
    819    is_rx_map = False;
    820    is_rw_map = False;
    821    is_ro_map = False;
    822 
    823 #  if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \
    824       || defined(VGA_mips64)
    825    is_rx_map = seg->hasR && seg->hasX;
    826    is_rw_map = seg->hasR && seg->hasW;
    827 #  elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_arm) \
    828         || defined(VGA_arm64)
    829    is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
    830    is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
    831 #  elif defined(VGP_s390x_linux)
    832    is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
    833    is_rw_map = seg->hasR && seg->hasW;
    834 #  else
    835 #    error "Unknown platform"
    836 #  endif
    837 
    838 #  if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7
    839    is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
    840 #  endif
    841 
    842    if (debug)
    843       VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n",
    844                   (Int)is_rx_map, (Int)is_rw_map);
    845 
    846    /* Ignore mappings with permissions we can't possibly be interested in. */
    847    if (!(is_rx_map || is_rw_map || is_ro_map))
    848       return 0;
    849 
    850    /* Peer at the first few bytes of the file, to see if it is an ELF */
    851    /* object file. Ignore the file if we do not have read permission. */
    852    VG_(memset)(buf1k, 0, sizeof(buf1k));
    853    oflags = VKI_O_RDONLY;
    854 #  if defined(VKI_O_LARGEFILE)
    855    oflags |= VKI_O_LARGEFILE;
    856 #  endif
    857 
    858    if (use_fd == -1) {
    859       SysRes fd = VG_(open)( filename, oflags, 0 );
    860       if (sr_isError(fd)) {
    861          if (sr_Err(fd) != VKI_EACCES) {
    862             DebugInfo fake_di;
    863             VG_(memset)(&fake_di, 0, sizeof(fake_di));
    864             fake_di.fsm.filename = filename;
    865             ML_(symerr)(&fake_di, True,
    866                         "can't open file to inspect ELF header");
    867          }
    868          return 0;
    869       }
    870       actual_fd = sr_Res(fd);
    871    } else {
    872       actual_fd = use_fd;
    873    }
    874 
    875    preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 );
    876    if (use_fd == -1) {
    877       VG_(close)( actual_fd );
    878    }
    879 
    880    if (sr_isError(preadres)) {
    881       DebugInfo fake_di;
    882       VG_(memset)(&fake_di, 0, sizeof(fake_di));
    883       fake_di.fsm.filename = filename;
    884       ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header");
    885       return 0;
    886    }
    887    if (sr_Res(preadres) == 0)
    888       return 0;
    889    vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) );
    890 
    891    /* We're only interested in mappings of object files. */
    892 #  if defined(VGO_linux)
    893    if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False ))
    894       return 0;
    895 #  elif defined(VGO_darwin)
    896    if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
    897       return 0;
    898 #  else
    899 #    error "unknown OS"
    900 #  endif
    901 
    902    /* See if we have a DebugInfo for this filename.  If not,
    903       create one. */
    904    di = find_or_create_DebugInfo_for( filename );
    905    vg_assert(di);
    906 
    907    /* Note the details about the mapping. */
    908    struct _DebugInfoMapping map;
    909    map.avma = a;
    910    map.size = seg->end + 1 - seg->start;
    911    map.foff = seg->offset;
    912    map.rx   = is_rx_map;
    913    map.rw   = is_rw_map;
    914    map.ro   = is_ro_map;
    915    VG_(addToXA)(di->fsm.maps, &map);
    916 
    917    /* Update flags about what kind of mappings we've already seen. */
    918    di->fsm.have_rx_map |= is_rx_map;
    919    di->fsm.have_rw_map |= is_rw_map;
    920    di->fsm.have_ro_map |= is_ro_map;
    921 
    922    /* So, finally, are we in an accept state? */
    923    if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
    924       /* Ok, so, finally, we found what we need, and we haven't
    925          already read debuginfo for this object.  So let's do so now.
    926          Yee-ha! */
    927       return di_notify_ACHIEVE_ACCEPT_STATE ( di );
    928    } else {
    929       /* If we don't have an rx and rw mapping, or if we already have
    930          debuginfo for this mapping for whatever reason, go no
    931          further. */
    932       return 0;
    933    }
    934 }
    935 
    936 
    937 /* Unmap is simpler - throw away any SegInfos intersecting
    938    [a, a+len).  */
    939 void VG_(di_notify_munmap)( Addr a, SizeT len )
    940 {
    941    Bool anyFound;
    942    if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len);
    943    anyFound = discard_syms_in_range(a, len);
    944    if (anyFound)
    945       cfsi_cache__invalidate();
    946 }
    947 
    948 
    949 /* Uh, this doesn't do anything at all.  IIRC glibc (or ld.so, I don't
    950    remember) does a bunch of mprotects on itself, and if we follow
    951    through here, it causes the debug info for that object to get
    952    discarded. */
    953 void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
    954 {
    955    Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
    956 #  if defined(VGA_x86)
    957    exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
    958 #  endif
    959    if (0 && !exe_ok) {
    960       Bool anyFound = discard_syms_in_range(a, len);
    961       if (anyFound)
    962          cfsi_cache__invalidate();
    963    }
    964 }
    965 
    966 
    967 /* This is a MacOSX 10.7 32-bit only special.  See comments on the
    968    declaration of struct _DebugInfoFSM for details. */
    969 void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
    970 {
    971    Bool do_nothing = True;
    972 #  if defined(VGP_x86_darwin) && (DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8)
    973    do_nothing = False;
    974 #  endif
    975    if (do_nothing /* wrong platform */)
    976       return;
    977 
    978    Bool r_ok = toBool(prot & VKI_PROT_READ);
    979    Bool w_ok = toBool(prot & VKI_PROT_WRITE);
    980    Bool x_ok = toBool(prot & VKI_PROT_EXEC);
    981    if (! (r_ok && !w_ok && x_ok))
    982       return; /* not an upgrade to r-x */
    983 
    984    /* Find a DebugInfo containing a FSM that has [a, +len) previously
    985       observed as a r-- mapping, plus some other rw- mapping.  If such
    986       is found, conclude we're in an accept state and read debuginfo
    987       accordingly. */
    988    DebugInfo* di;
    989    struct _DebugInfoMapping *map = NULL;
    990    Word i;
    991    for (di = debugInfo_list; di; di = di->next) {
    992       vg_assert(di->fsm.filename);
    993       if (di->have_dinfo)
    994          continue; /* already have debuginfo for this object */
    995       if (!di->fsm.have_ro_map)
    996          continue; /* need to have a r-- mapping for this object */
    997       if (di->fsm.have_rx_map)
    998          continue; /* rx- mapping already exists */
    999       if (!di->fsm.have_rw_map)
   1000          continue; /* need to have a rw- mapping */
   1001       /* Try to find a mapping matching the memory area. */
   1002       for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1003          map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i);
   1004          if (map->ro && map->avma == a && map->size == len)
   1005             break;
   1006          map = NULL;
   1007       }
   1008       if (!map)
   1009          continue; /* this isn't an upgrade of an r-- mapping */
   1010       /* looks like we're in luck! */
   1011       break;
   1012    }
   1013    if (di == NULL)
   1014       return; /* didn't find anything */
   1015 
   1016    /* Do the upgrade.  Simply update the flags of the mapping
   1017       and pretend we never saw the RO map at all. */
   1018    vg_assert(di->fsm.have_ro_map);
   1019    map->rx = True;
   1020    map->ro = False;
   1021    di->fsm.have_rx_map = True;
   1022    di->fsm.have_ro_map = False;
   1023    /* See if there are any more ro mappings */
   1024    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1025       map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i);
   1026       if (map->ro) {
   1027          di->fsm.have_ro_map = True;
   1028          break;
   1029       }
   1030    }
   1031 
   1032    /* Check if we're now in an accept state and read debuginfo.  Finally. */
   1033    if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
   1034       ULong di_handle __attribute__((unused))
   1035          = di_notify_ACHIEVE_ACCEPT_STATE( di );
   1036       /* di_handle is ignored. That's not a problem per se -- it just
   1037          means nobody will ever be able to refer to this debuginfo by
   1038          handle since nobody will know what the handle value is. */
   1039    }
   1040 }
   1041 
   1042 
   1043 /*--------- PDB (windows debug info) reading --------- */
   1044 
   1045 /* this should really return ULong, as per VG_(di_notify_mmap). */
   1046 void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
   1047                                    SizeT total_size, PtrdiffT bias_obj )
   1048 {
   1049    Int    i, r, sz_exename;
   1050    ULong  obj_mtime, pdb_mtime;
   1051    HChar  exename[VKI_PATH_MAX];
   1052    HChar* pdbname = NULL;
   1053    HChar* dot;
   1054    SysRes sres;
   1055    Int    fd_pdbimage;
   1056    SizeT  n_pdbimage;
   1057    struct vg_stat stat_buf;
   1058 
   1059    if (VG_(clo_verbosity) > 0) {
   1060       VG_(message)(Vg_UserMsg, "\n");
   1061       VG_(message)(Vg_UserMsg,
   1062          "LOAD_PDB_DEBUGINFO: clreq:   fd=%d, avma=%#lx, total_size=%lu, "
   1063          "bias=%#lx\n",
   1064          fd_obj, avma_obj, total_size, bias_obj
   1065       );
   1066    }
   1067 
   1068    /* 'fd' refers to the .exe/.dll we're dealing with.  Get its modification
   1069       time into obj_mtime. */
   1070    r = VG_(fstat)(fd_obj, &stat_buf);
   1071    if (r == -1)
   1072       goto out; /* stat failed ?! */
   1073    vg_assert(r == 0);
   1074    obj_mtime = stat_buf.mtime;
   1075 
   1076    /* and get its name into exename[]. */
   1077    vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */
   1078    VG_(memset)(exename, 0, sizeof(exename));
   1079    VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj);
   1080    /* convert exename from a symlink to real name .. overwrites the
   1081       old contents of the buffer.  Ick. */
   1082    sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 );
   1083    if (sz_exename == -1)
   1084       goto out; /* readlink failed ?! */
   1085    vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename));
   1086    vg_assert(exename[sizeof(exename)-1] == 0);
   1087 
   1088    if (VG_(clo_verbosity) > 0) {
   1089       VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
   1090    }
   1091 
   1092    /* Try to get the PDB file name from the executable. */
   1093    pdbname = ML_(find_name_of_pdb_file)(exename);
   1094    if (pdbname) {
   1095       vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */
   1096       /* So we successfully extracted a name from the PE file.  But it's
   1097          likely to be of the form
   1098             e:\foo\bar\xyzzy\wibble.pdb
   1099          and we need to change it into something we can actually open
   1100          in Wine-world, which basically means turning it into
   1101             $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
   1102          We also take into account $WINEPREFIX, if it is set.
   1103          For the moment, if the name isn't fully qualified, just forget it
   1104          (we'd have to root around to find where the pdb actually is)
   1105       */
   1106       /* Change all the backslashes to forward slashes */
   1107       for (i = 0; pdbname[i]; i++) {
   1108          if (pdbname[i] == '\\')
   1109             pdbname[i] = '/';
   1110       }
   1111       Bool is_quald
   1112          = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z')
   1113            && pdbname[1] == ':'
   1114            && pdbname[2] == '/';
   1115       HChar* home = VG_(getenv)("HOME");
   1116       HChar* wpfx = VG_(getenv)("WINEPREFIX");
   1117       if (is_quald && wpfx) {
   1118          /* Change e:/foo/bar/xyzzy/wibble.pdb
   1119                 to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb
   1120          */
   1121          Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/;
   1122          HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB);
   1123          VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s",
   1124                        wpfx, pdbname[0], &pdbname[2]);
   1125          vg_assert(mashed[mashedSzB-1] == 0);
   1126          ML_(dinfo_free)(pdbname);
   1127          pdbname = mashed;
   1128       }
   1129       else if (is_quald && home && !wpfx) {
   1130          /* Change e:/foo/bar/xyzzy/wibble.pdb
   1131                 to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
   1132          */
   1133          Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/;
   1134          HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB);
   1135          VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s",
   1136 		       home, pdbname[0], &pdbname[2]);
   1137          vg_assert(mashed[mashedSzB-1] == 0);
   1138          ML_(dinfo_free)(pdbname);
   1139          pdbname = mashed;
   1140       } else {
   1141          /* It's not a fully qualified path, or neither $HOME nor $WINE
   1142             are set (strange).  Give up. */
   1143          ML_(dinfo_free)(pdbname);
   1144          pdbname = NULL;
   1145       }
   1146    }
   1147 
   1148    /* Try s/exe/pdb/ if we don't have a valid pdbname. */
   1149    if (!pdbname) {
   1150       /* Try to find a matching PDB file from which to read debuginfo.
   1151          Windows PE files have symbol tables and line number information,
   1152          but MSVC doesn't seem to use them. */
   1153       /* Why +5 ?  Because in the worst case, we could find a dot as the
   1154          last character of pdbname, and we'd then put "pdb" right after
   1155          it, hence extending it a bit. */
   1156       pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5);
   1157       VG_(strcpy)(pdbname, exename);
   1158       vg_assert(pdbname[sz_exename+5-1] == 0);
   1159       dot = VG_(strrchr)(pdbname, '.');
   1160       if (!dot)
   1161          goto out; /* there's no dot in the exe's name ?! */
   1162       if (dot[1] == 0)
   1163          goto out; /* hmm, path ends in "." */
   1164 
   1165       if ('A' <= dot[1] && dot[1] <= 'Z')
   1166          VG_(strcpy)(dot, ".PDB");
   1167       else
   1168          VG_(strcpy)(dot, ".pdb");
   1169 
   1170       vg_assert(pdbname[sz_exename+5-1] == 0);
   1171    }
   1172 
   1173    /* See if we can find it, and check it's in-dateness. */
   1174    sres = VG_(stat)(pdbname, &stat_buf);
   1175    if (sr_isError(sres)) {
   1176       VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
   1177                                pdbname);
   1178    if (VG_(clo_verbosity) > 0)
   1179       VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
   1180       goto out;
   1181    }
   1182    pdb_mtime = stat_buf.mtime;
   1183 
   1184    if (obj_mtime > pdb_mtime + 60ULL) {
   1185       /* PDB file is older than PE file.  Really, the PDB should be
   1186          newer than the PE, but that doesn't always seem to be the
   1187          case.  Allow the PDB to be up to one minute older.
   1188          Otherwise, it's probably out of date, in which case ignore it
   1189          or we will either (a) print wrong stack traces or more likely
   1190          (b) crash.
   1191       */
   1192       VG_(message)(Vg_UserMsg,
   1193                    "Warning:       %s (mtime = %llu)\n"
   1194                    " is older than %s (mtime = %llu)\n",
   1195                    pdbname, pdb_mtime, exename, obj_mtime);
   1196    }
   1197 
   1198    sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
   1199    if (sr_isError(sres)) {
   1200       VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
   1201       goto out;
   1202    }
   1203 
   1204    /* Looks promising; go on to try and read stuff from it.  But don't
   1205       mmap the file.  Instead mmap free space and read the file into
   1206       it.  This is because files on CIFS filesystems that are mounted
   1207       '-o directio' can't be mmap'd, and that mount option is needed
   1208       to make CIFS work reliably.  (See
   1209       http://www.nabble.com/Corrupted-data-on-write-to-
   1210                             Windows-2003-Server-t2782623.html)
   1211       This is slower, but at least it works reliably. */
   1212    fd_pdbimage = sr_Res(sres);
   1213    n_pdbimage  = stat_buf.size;
   1214    if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) {
   1215       // 0x7FFFFFFF: why?  Because the VG_(read) just below only
   1216       // can deal with a signed int as the size of data to read,
   1217       // so we can't reliably check for read failure for files
   1218       // greater than that size.  Hence just skip them; we're
   1219       // unlikely to encounter a PDB that large anyway.
   1220       VG_(close)(fd_pdbimage);
   1221       goto out;
   1222    }
   1223    sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage );
   1224    if (sr_isError(sres)) {
   1225       VG_(close)(fd_pdbimage);
   1226       goto out;
   1227    }
   1228 
   1229    void* pdbimage = (void*)sr_Res(sres);
   1230    r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage );
   1231    if (r < 0 || r != (Int)n_pdbimage) {
   1232       VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
   1233       VG_(close)(fd_pdbimage);
   1234       goto out;
   1235    }
   1236 
   1237    if (VG_(clo_verbosity) > 0)
   1238       VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
   1239 
   1240    /* play safe; always invalidate the CFI cache.  I don't know if
   1241       this is necessary, but anyway .. */
   1242    cfsi_cache__invalidate();
   1243    /* dump old info for this range, if any */
   1244    discard_syms_in_range( avma_obj, total_size );
   1245 
   1246    { DebugInfo* di = find_or_create_DebugInfo_for(exename);
   1247 
   1248      /* this di must be new, since we just nuked any old stuff in the range */
   1249      vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map);
   1250      vg_assert(!di->have_dinfo);
   1251 
   1252      /* don't set up any of the di-> fields; let
   1253         ML_(read_pdb_debug_info) do it. */
   1254      ML_(read_pdb_debug_info)( di, avma_obj, bias_obj,
   1255                                pdbimage, n_pdbimage, pdbname, pdb_mtime );
   1256      // JRS fixme: take notice of return value from read_pdb_debug_info,
   1257      // and handle failure
   1258      vg_assert(di->have_dinfo); // fails if PDB read failed
   1259      VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
   1260      VG_(close)(fd_pdbimage);
   1261 
   1262      if (VG_(clo_verbosity) > 0) {
   1263         VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done:    "
   1264                                  "%lu syms, %lu src locs, %lu fpo recs\n",
   1265                      di->symtab_used, di->loctab_used, di->fpo_size);
   1266      }
   1267    }
   1268 
   1269   out:
   1270    if (pdbname) ML_(dinfo_free)(pdbname);
   1271 }
   1272 
   1273 #endif /* defined(VGO_linux) || defined(VGO_darwin) */
   1274 
   1275 
   1276 /*------------------------------------------------------------*/
   1277 /*---                                                      ---*/
   1278 /*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO              ---*/
   1279 /*---                                                      ---*/
   1280 /*------------------------------------------------------------*/
   1281 
   1282 void VG_(di_discard_ALL_debuginfo)( void )
   1283 {
   1284    DebugInfo *di, *di2;
   1285    di = debugInfo_list;
   1286    while (di) {
   1287       di2 = di->next;
   1288       VG_(printf)("XXX rm %p\n", di);
   1289       free_DebugInfo( di );
   1290       di = di2;
   1291    }
   1292 }
   1293 
   1294 
   1295 struct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di,
   1296                                                  Addr lo, Addr hi )
   1297 {
   1298    Word i;
   1299    vg_assert(lo <= hi);
   1300 
   1301    /* Optimization: Try to use the last matched rx mapping first */
   1302    if (   di->last_rx_map
   1303        && lo >= di->last_rx_map->avma
   1304        && hi <  di->last_rx_map->avma + di->last_rx_map->size)
   1305       return di->last_rx_map;
   1306 
   1307    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
   1308       struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
   1309       if (   map->rx && map->size > 0
   1310           && lo >= map->avma && hi < map->avma + map->size) {
   1311          di->last_rx_map = map;
   1312          return map;
   1313       }
   1314    }
   1315 
   1316    return NULL;
   1317 }
   1318 
   1319 
   1320 /*------------------------------------------------------------*/
   1321 /*--- Use of symbol table & location info to create        ---*/
   1322 /*--- plausible-looking stack dumps.                       ---*/
   1323 /*------------------------------------------------------------*/
   1324 
   1325 /* Search all symtabs that we know about to locate ptr.  If found, set
   1326    *pdi to the relevant DebugInfo, and *symno to the symtab entry
   1327    *number within that.  If not found, *psi is set to NULL.
   1328    If findText==True,  only text symbols are searched for.
   1329    If findText==False, only data symbols are searched for.
   1330 */
   1331 static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
   1332                                            /*OUT*/Word* symno,
   1333                                  Bool match_anywhere_in_sym,
   1334                                  Bool findText )
   1335 {
   1336    Word       sno;
   1337    DebugInfo* di;
   1338    Bool       inRange;
   1339 
   1340    for (di = debugInfo_list; di != NULL; di = di->next) {
   1341 
   1342       if (findText) {
   1343          /* Consider any symbol in the r-x mapped area to be text.
   1344             See Comment_Regarding_Text_Range_Checks in storage.c for
   1345             details. */
   1346          inRange = di->fsm.have_rx_map
   1347                    && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL);
   1348       } else {
   1349          inRange = (di->data_present
   1350                     && di->data_size > 0
   1351                     && di->data_avma <= ptr
   1352                     && ptr < di->data_avma + di->data_size)
   1353                    ||
   1354                    (di->sdata_present
   1355                     && di->sdata_size > 0
   1356                     && di->sdata_avma <= ptr
   1357                     && ptr < di->sdata_avma + di->sdata_size)
   1358                    ||
   1359                    (di->bss_present
   1360                     && di->bss_size > 0
   1361                     && di->bss_avma <= ptr
   1362                     && ptr < di->bss_avma + di->bss_size)
   1363                    ||
   1364                    (di->sbss_present
   1365                     && di->sbss_size > 0
   1366                     && di->sbss_avma <= ptr
   1367                     && ptr < di->sbss_avma + di->sbss_size)
   1368                    ||
   1369                    (di->rodata_present
   1370                     && di->rodata_size > 0
   1371                     && di->rodata_avma <= ptr
   1372                     && ptr < di->rodata_avma + di->rodata_size);
   1373       }
   1374 
   1375       if (!inRange) continue;
   1376 
   1377       sno = ML_(search_one_symtab) (
   1378                di, ptr, match_anywhere_in_sym, findText );
   1379       if (sno == -1) goto not_found;
   1380       *symno = sno;
   1381       *pdi = di;
   1382       return;
   1383 
   1384    }
   1385   not_found:
   1386    *pdi = NULL;
   1387 }
   1388 
   1389 
   1390 /* Search all loctabs that we know about to locate ptr.  If found, set
   1391    *pdi to the relevant DebugInfo, and *locno to the loctab entry
   1392    *number within that.  If not found, *pdi is set to NULL. */
   1393 static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
   1394                                            /*OUT*/Word* locno )
   1395 {
   1396    Word       lno;
   1397    DebugInfo* di;
   1398    for (di = debugInfo_list; di != NULL; di = di->next) {
   1399       if (di->text_present
   1400           && di->text_size > 0
   1401           && di->text_avma <= ptr
   1402           && ptr < di->text_avma + di->text_size) {
   1403          lno = ML_(search_one_loctab) ( di, ptr );
   1404          if (lno == -1) goto not_found;
   1405          *locno = lno;
   1406          *pdi = di;
   1407          return;
   1408       }
   1409    }
   1410   not_found:
   1411    *pdi = NULL;
   1412 }
   1413 
   1414 
   1415 /* The whole point of this whole big deal: map a code address to a
   1416    plausible symbol name.  Returns False if no idea; otherwise True.
   1417    Caller supplies buf and nbuf.  If do_cxx_demangling is False, don't do
   1418    C++ demangling, regardless of VG_(clo_demangle) -- probably because the
   1419    call has come from VG_(get_fnname_raw)().  findText
   1420    indicates whether we're looking for a text symbol or a data symbol
   1421    -- caller must choose one kind or the other. */
   1422 static
   1423 Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling,
   1424                     Bool do_below_main_renaming,
   1425                     Addr a, HChar* buf, Int nbuf,
   1426                     Bool match_anywhere_in_sym, Bool show_offset,
   1427                     Bool findText, /*OUT*/PtrdiffT* offsetP )
   1428 {
   1429    DebugInfo* di;
   1430    Word       sno;
   1431    PtrdiffT   offset;
   1432 
   1433    search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
   1434    if (di == NULL)
   1435       return False;
   1436 
   1437    vg_assert(di->symtab[sno].pri_name);
   1438    VG_(demangle) ( do_cxx_demangling, do_z_demangling,
   1439                    di->symtab[sno].pri_name, buf, nbuf );
   1440 
   1441    /* Do the below-main hack */
   1442    // To reduce the endless nuisance of multiple different names
   1443    // for "the frame below main()" screwing up the testsuite, change all
   1444    // known incarnations of said into a single name, "(below main)", if
   1445    // --show-below-main=yes.
   1446    if ( do_below_main_renaming && ! VG_(clo_show_below_main) &&
   1447         Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) )
   1448    {
   1449       VG_(strncpy_safely)(buf, "(below main)", nbuf);
   1450    }
   1451    offset = a - di->symtab[sno].addr;
   1452    if (offsetP) *offsetP = offset;
   1453 
   1454    if (show_offset && offset != 0) {
   1455       HChar    buf2[12];
   1456       HChar*   symend = buf + VG_(strlen)(buf);
   1457       HChar*   end = buf + nbuf;
   1458       Int      len;
   1459 
   1460       len = VG_(sprintf)(buf2, "%c%ld",
   1461 			 offset < 0 ? '-' : '+',
   1462 			 offset < 0 ? -offset : offset);
   1463       vg_assert(len < (Int)sizeof(buf2));
   1464 
   1465       if (len < (end - symend)) {
   1466 	 HChar *cp = buf2;
   1467 	 VG_(memcpy)(symend, cp, len+1);
   1468       }
   1469    }
   1470 
   1471    buf[nbuf-1] = 0; /* paranoia */
   1472 
   1473    return True;
   1474 }
   1475 
   1476 /* ppc64-linux only: find the TOC pointer (R2 value) that should be in
   1477    force at the entry point address of the function containing
   1478    guest_code_addr.  Returns 0 if not known. */
   1479 Addr VG_(get_tocptr) ( Addr guest_code_addr )
   1480 {
   1481    DebugInfo* si;
   1482    Word       sno;
   1483    search_all_symtabs ( guest_code_addr,
   1484                         &si, &sno,
   1485                         True/*match_anywhere_in_fun*/,
   1486                         True/*consider text symbols only*/ );
   1487    if (si == NULL)
   1488       return 0;
   1489    else
   1490       return si->symtab[sno].tocptr;
   1491 }
   1492 
   1493 /* This is available to tools... always demangle C++ names,
   1494    match anywhere in function, but don't show offsets. */
   1495 Bool VG_(get_fnname) ( Addr a, HChar* buf, Int nbuf )
   1496 {
   1497    return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
   1498                          /*below-main-renaming*/True,
   1499                          a, buf, nbuf,
   1500                          /*match_anywhere_in_fun*/True,
   1501                          /*show offset?*/False,
   1502                          /*text syms only*/True,
   1503                          /*offsetP*/NULL );
   1504 }
   1505 
   1506 /* This is available to tools... always demangle C++ names,
   1507    match anywhere in function, and show offset if nonzero. */
   1508 Bool VG_(get_fnname_w_offset) ( Addr a, HChar* buf, Int nbuf )
   1509 {
   1510    return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
   1511                          /*below-main-renaming*/True,
   1512                          a, buf, nbuf,
   1513                          /*match_anywhere_in_fun*/True,
   1514                          /*show offset?*/True,
   1515                          /*text syms only*/True,
   1516                          /*offsetP*/NULL );
   1517 }
   1518 
   1519 /* This is available to tools... always demangle C++ names,
   1520    only succeed if 'a' matches first instruction of function,
   1521    and don't show offsets. */
   1522 Bool VG_(get_fnname_if_entry) ( Addr a, HChar* buf, Int nbuf )
   1523 {
   1524    return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
   1525                          /*below-main-renaming*/True,
   1526                          a, buf, nbuf,
   1527                          /*match_anywhere_in_fun*/False,
   1528                          /*show offset?*/False,
   1529                          /*text syms only*/True,
   1530                          /*offsetP*/NULL );
   1531 }
   1532 
   1533 /* This is only available to core... don't C++-demangle, don't Z-demangle,
   1534    don't rename below-main, match anywhere in function, and don't show
   1535    offsets. */
   1536 Bool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf )
   1537 {
   1538    return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
   1539                          /*below-main-renaming*/False,
   1540                          a, buf, nbuf,
   1541                          /*match_anywhere_in_fun*/True,
   1542                          /*show offset?*/False,
   1543                          /*text syms only*/True,
   1544                          /*offsetP*/NULL );
   1545 }
   1546 
   1547 /* This is only available to core... don't demangle C++ names, but do
   1548    do Z-demangling and below-main-renaming, match anywhere in function, and
   1549    don't show offsets. */
   1550 Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf )
   1551 {
   1552    return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
   1553                          /*below-main-renaming*/True,
   1554                          a, buf, nbuf,
   1555                          /*match_anywhere_in_fun*/True,
   1556                          /*show offset?*/False,
   1557                          /*text syms only*/True,
   1558                          /*offsetP*/NULL );
   1559 }
   1560 
   1561 /* mips-linux only: find the offset of current address. This is needed for
   1562    stack unwinding for MIPS.
   1563 */
   1564 Bool VG_(get_inst_offset_in_function)( Addr a,
   1565                                        /*OUT*/PtrdiffT* offset )
   1566 {
   1567    HChar fnname[64];
   1568    return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
   1569                          /*below-main-renaming*/False,
   1570                          a, fnname, 64,
   1571                          /*match_anywhere_in_sym*/True,
   1572                          /*show offset?*/True,
   1573                          /*data syms only please*/True,
   1574                          offset );
   1575 }
   1576 
   1577 Vg_FnNameKind VG_(get_fnname_kind) ( HChar* name )
   1578 {
   1579    if (VG_STREQ("main", name)) {
   1580       return Vg_FnNameMain;
   1581 
   1582    } else if (
   1583 #      if defined(VGO_linux)
   1584        VG_STREQ("__libc_start_main",  name) ||  // glibc glibness
   1585        VG_STREQ("generic_start_main", name) ||  // Yellow Dog doggedness
   1586 #      elif defined(VGO_darwin)
   1587        // See readmacho.c for an explanation of this.
   1588        VG_STREQ("start_according_to_valgrind", name) ||  // Darwin, darling
   1589 #      else
   1590 #        error "Unknown OS"
   1591 #      endif
   1592        0) {
   1593       return Vg_FnNameBelowMain;
   1594 
   1595    } else {
   1596       return Vg_FnNameNormal;
   1597    }
   1598 }
   1599 
   1600 Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip )
   1601 {
   1602    // We don't need a big buffer;  all the special names are small.
   1603    #define BUFLEN 50
   1604    HChar buf[50];
   1605 
   1606    // We don't demangle, because it's faster not to, and the special names
   1607    // we're looking for won't be demangled.
   1608    if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) {
   1609       buf[BUFLEN-1] = '\0';      // paranoia
   1610       return VG_(get_fnname_kind)(buf);
   1611    } else {
   1612       return Vg_FnNameNormal;    // Don't know the name, treat it as normal.
   1613    }
   1614 }
   1615 
   1616 /* Looks up data_addr in the collection of data symbols, and if found
   1617    puts its name (or as much as will fit) into dname[0 .. n_dname-1],
   1618    which is guaranteed to be zero terminated.  Also data_addr's offset
   1619    from the symbol start is put into *offset. */
   1620 Bool VG_(get_datasym_and_offset)( Addr data_addr,
   1621                                   /*OUT*/HChar* dname, Int n_dname,
   1622                                   /*OUT*/PtrdiffT* offset )
   1623 {
   1624    Bool ok;
   1625    vg_assert(n_dname > 1);
   1626    ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
   1627                        /*below-main-renaming*/False,
   1628                        data_addr, dname, n_dname,
   1629                        /*match_anywhere_in_sym*/True,
   1630                        /*show offset?*/False,
   1631                        /*data syms only please*/False,
   1632                        offset );
   1633    if (!ok)
   1634       return False;
   1635    dname[n_dname-1] = 0;
   1636    return True;
   1637 }
   1638 
   1639 /* Map a code address to the name of a shared object file or the
   1640    executable.  Returns False if no idea; otherwise True.  Doesn't
   1641    require debug info.  Caller supplies buf and nbuf. */
   1642 Bool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf )
   1643 {
   1644    DebugInfo* di;
   1645    const NSegment *seg;
   1646    HChar* filename;
   1647    vg_assert(nbuf > 0);
   1648    /* Look in the debugInfo_list to find the name.  In most cases we
   1649       expect this to produce a result. */
   1650    for (di = debugInfo_list; di != NULL; di = di->next) {
   1651       if (di->text_present
   1652           && di->text_size > 0
   1653           && di->text_avma <= a
   1654           && a < di->text_avma + di->text_size) {
   1655          VG_(strncpy_safely)(buf, di->fsm.filename, nbuf);
   1656          buf[nbuf-1] = 0;
   1657          return True;
   1658       }
   1659    }
   1660    /* Last-ditch fallback position: if we don't find the address in
   1661       the debugInfo_list, ask the address space manager whether it
   1662       knows the name of the file associated with this mapping.  This
   1663       allows us to print the names of exe/dll files in the stack trace
   1664       when running programs under wine. */
   1665    if ( (seg = VG_(am_find_nsegment(a))) != NULL
   1666         && (filename = VG_(am_get_filename)(seg)) != NULL ) {
   1667       VG_(strncpy_safely)(buf, filename, nbuf);
   1668       return True;
   1669    }
   1670    return False;
   1671 }
   1672 
   1673 /* Map a code address to its DebugInfo.  Returns NULL if not found.  Doesn't
   1674    require debug info. */
   1675 DebugInfo* VG_(find_DebugInfo) ( Addr a )
   1676 {
   1677    static UWord n_search = 0;
   1678    DebugInfo* di;
   1679    n_search++;
   1680    for (di = debugInfo_list; di != NULL; di = di->next) {
   1681       if (di->text_present
   1682           && di->text_size > 0
   1683           && di->text_avma <= a
   1684           && a < di->text_avma + di->text_size) {
   1685          if (0 == (n_search & 0xF))
   1686             move_DebugInfo_one_step_forward( di );
   1687          return di;
   1688       }
   1689    }
   1690    return NULL;
   1691 }
   1692 
   1693 /* Map a code address to a filename.  Returns True if successful.  */
   1694 Bool VG_(get_filename)( Addr a, HChar* filename, Int n_filename )
   1695 {
   1696    DebugInfo* si;
   1697    Word       locno;
   1698    search_all_loctabs ( a, &si, &locno );
   1699    if (si == NULL)
   1700       return False;
   1701    VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
   1702    return True;
   1703 }
   1704 
   1705 /* Map a code address to a line number.  Returns True if successful. */
   1706 Bool VG_(get_linenum)( Addr a, UInt* lineno )
   1707 {
   1708    DebugInfo* si;
   1709    Word       locno;
   1710    search_all_loctabs ( a, &si, &locno );
   1711    if (si == NULL)
   1712       return False;
   1713    *lineno = si->loctab[locno].lineno;
   1714 
   1715    return True;
   1716 }
   1717 
   1718 /* Map a code address to a filename/line number/dir name info.
   1719    See prototype for detailed description of behaviour.
   1720 */
   1721 Bool VG_(get_filename_linenum) ( Addr a,
   1722                                  /*OUT*/HChar* filename, Int n_filename,
   1723                                  /*OUT*/HChar* dirname,  Int n_dirname,
   1724                                  /*OUT*/Bool* dirname_available,
   1725                                  /*OUT*/UInt* lineno )
   1726 {
   1727    DebugInfo* si;
   1728    Word       locno;
   1729 
   1730    vg_assert( (dirname == NULL && dirname_available == NULL)
   1731               ||
   1732               (dirname != NULL && dirname_available != NULL) );
   1733 
   1734    search_all_loctabs ( a, &si, &locno );
   1735    if (si == NULL) {
   1736       if (dirname_available) {
   1737          *dirname_available = False;
   1738          *dirname = 0;
   1739       }
   1740       return False;
   1741    }
   1742 
   1743    VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
   1744    *lineno = si->loctab[locno].lineno;
   1745 
   1746    if (dirname) {
   1747       /* caller wants directory info too .. */
   1748       vg_assert(n_dirname > 0);
   1749       if (si->loctab[locno].dirname) {
   1750          /* .. and we have some */
   1751          *dirname_available = True;
   1752          VG_(strncpy_safely)(dirname, si->loctab[locno].dirname,
   1753                                       n_dirname);
   1754       } else {
   1755          /* .. but we don't have any */
   1756          *dirname_available = False;
   1757          *dirname = 0;
   1758       }
   1759    }
   1760 
   1761    return True;
   1762 }
   1763 
   1764 
   1765 /* Map a function name to its entry point and toc pointer.  Is done by
   1766    sequential search of all symbol tables, so is very slow.  To
   1767    mitigate the worst performance effects, you may specify a soname
   1768    pattern, and only objects matching that pattern are searched.
   1769    Therefore specify "*" to search all the objects.  On TOC-afflicted
   1770    platforms, a symbol is deemed to be found only if it has a nonzero
   1771    TOC pointer.  */
   1772 Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name,
   1773                              Addr* pEnt, Addr* pToc)
   1774 {
   1775    Bool     require_pToc = False;
   1776    Int      i;
   1777    DebugInfo* si;
   1778    Bool     debug = False;
   1779 #  if defined(VG_PLAT_USES_PPCTOC)
   1780    require_pToc = True;
   1781 #  endif
   1782    for (si = debugInfo_list; si; si = si->next) {
   1783       if (debug)
   1784          VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
   1785       if (!VG_(string_match)(sopatt, si->soname)) {
   1786          if (debug)
   1787             VG_(printf)(" ... skip\n");
   1788          continue;
   1789       }
   1790       for (i = 0; i < si->symtab_used; i++) {
   1791          HChar* pri_name = si->symtab[i].pri_name;
   1792          tl_assert(pri_name);
   1793          if (0==VG_(strcmp)(name, pri_name)
   1794              && (require_pToc ? si->symtab[i].tocptr : True)) {
   1795             *pEnt = si->symtab[i].addr;
   1796             *pToc = si->symtab[i].tocptr;
   1797             return True;
   1798          }
   1799          HChar** sec_names = si->symtab[i].sec_names;
   1800          if (sec_names) {
   1801             tl_assert(sec_names[0]);
   1802             while (*sec_names) {
   1803                if (0==VG_(strcmp)(name, *sec_names)
   1804                    && (require_pToc ? si->symtab[i].tocptr : True)) {
   1805                   *pEnt = si->symtab[i].addr;
   1806                   *pToc = si->symtab[i].tocptr;
   1807                   return True;
   1808                }
   1809                sec_names++;
   1810             }
   1811          }
   1812       }
   1813    }
   1814    return False;
   1815 }
   1816 
   1817 
   1818 /* VG_(describe_IP): print into buf info on code address, function
   1819    name and filename. */
   1820 
   1821 /* Copy str into buf starting at n, but not going past buf[n_buf-1]
   1822    and always ensuring that buf is zero-terminated. */
   1823 
   1824 static Int putStr ( Int n, Int n_buf, HChar* buf, const HChar* str )
   1825 {
   1826    vg_assert(n_buf > 0);
   1827    vg_assert(n >= 0 && n < n_buf);
   1828    for (; n < n_buf-1 && *str != 0; n++,str++)
   1829       buf[n] = *str;
   1830    vg_assert(n >= 0 && n < n_buf);
   1831    buf[n] = '\0';
   1832    return n;
   1833 }
   1834 
   1835 /* Same as putStr, but escaping chars for XML output, and
   1836    also not adding more than count chars to n_buf. */
   1837 
   1838 static Int putStrEsc ( Int n, Int n_buf, Int count, HChar* buf, HChar* str )
   1839 {
   1840    HChar alt[2];
   1841    vg_assert(n_buf > 0);
   1842    vg_assert(count >= 0 && count < n_buf);
   1843    vg_assert(n >= 0 && n < n_buf);
   1844    for (; *str != 0; str++) {
   1845       vg_assert(count >= 0);
   1846       if (count <= 0)
   1847          goto done;
   1848       switch (*str) {
   1849          case '&':
   1850             if (count < 5) goto done;
   1851             n = putStr( n, n_buf, buf, "&amp;");
   1852             count -= 5;
   1853             break;
   1854          case '<':
   1855             if (count < 4) goto done;
   1856             n = putStr( n, n_buf, buf, "&lt;");
   1857             count -= 4;
   1858             break;
   1859          case '>':
   1860             if (count < 4) goto done;
   1861             n = putStr( n, n_buf, buf, "&gt;");
   1862             count -= 4;
   1863             break;
   1864          default:
   1865             if (count < 1) goto done;
   1866             alt[0] = *str;
   1867             alt[1] = 0;
   1868             n = putStr( n, n_buf, buf, alt );
   1869             count -= 1;
   1870             break;
   1871       }
   1872    }
   1873   done:
   1874    vg_assert(count >= 0); /* should not go -ve in loop */
   1875    vg_assert(n >= 0 && n < n_buf);
   1876    return n;
   1877 }
   1878 
   1879 HChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf)
   1880 {
   1881 #  define APPEND(_str) \
   1882       n = putStr(n, n_buf, buf, _str)
   1883 #  define APPEND_ESC(_count,_str) \
   1884       n = putStrEsc(n, n_buf, (_count), buf, (_str))
   1885 #  define BUF_LEN    4096
   1886 
   1887    UInt  lineno;
   1888    HChar ibuf[50];
   1889    Int   n = 0;
   1890 
   1891    static HChar buf_fn[BUF_LEN];
   1892    static HChar buf_obj[BUF_LEN];
   1893    static HChar buf_srcloc[BUF_LEN];
   1894    static HChar buf_dirname[BUF_LEN];
   1895    buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0;
   1896 
   1897    Bool  know_dirinfo = False;
   1898    Bool  know_fnname  = VG_(clo_sym_offsets)
   1899                         ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN)
   1900                         : VG_(get_fnname) (eip, buf_fn, BUF_LEN);
   1901    Bool  know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN);
   1902    Bool  know_srcloc  = VG_(get_filename_linenum)(
   1903                            eip,
   1904                            buf_srcloc,  BUF_LEN,
   1905                            buf_dirname, BUF_LEN, &know_dirinfo,
   1906                            &lineno
   1907                         );
   1908    buf_fn     [ sizeof(buf_fn)-1      ]  = 0;
   1909    buf_obj    [ sizeof(buf_obj)-1     ]  = 0;
   1910    buf_srcloc [ sizeof(buf_srcloc)-1  ]  = 0;
   1911    buf_dirname[ sizeof(buf_dirname)-1 ]  = 0;
   1912 
   1913    if (VG_(clo_xml)) {
   1914 
   1915       Bool   human_readable = True;
   1916       const HChar* maybe_newline  = human_readable ? "\n      " : "";
   1917       const HChar* maybe_newline2 = human_readable ? "\n    "   : "";
   1918 
   1919       /* Print in XML format, dumping in as much info as we know.
   1920          Ensure all tags are balanced even if the individual strings
   1921          are too long.  Allocate 1/10 of BUF_LEN to the object name,
   1922          6/10s to the function name, 1/10 to the directory name and
   1923          1/10 to the file name, leaving 1/10 for all the fixed-length
   1924          stuff. */
   1925       APPEND("<frame>");
   1926       VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip);
   1927       APPEND(maybe_newline);
   1928       APPEND(ibuf);
   1929       if (know_objname) {
   1930          APPEND(maybe_newline);
   1931          APPEND("<obj>");
   1932          APPEND_ESC(1*BUF_LEN/10, buf_obj);
   1933          APPEND("</obj>");
   1934       }
   1935       if (know_fnname) {
   1936          APPEND(maybe_newline);
   1937          APPEND("<fn>");
   1938          APPEND_ESC(6*BUF_LEN/10, buf_fn);
   1939          APPEND("</fn>");
   1940       }
   1941       if (know_srcloc) {
   1942          if (know_dirinfo) {
   1943             APPEND(maybe_newline);
   1944             APPEND("<dir>");
   1945             APPEND_ESC(1*BUF_LEN/10, buf_dirname);
   1946             APPEND("</dir>");
   1947          }
   1948          APPEND(maybe_newline);
   1949          APPEND("<file>");
   1950          APPEND_ESC(1*BUF_LEN/10, buf_srcloc);
   1951          APPEND("</file>");
   1952          APPEND(maybe_newline);
   1953          APPEND("<line>");
   1954          VG_(sprintf)(ibuf,"%d",lineno);
   1955          APPEND(ibuf);
   1956          APPEND("</line>");
   1957       }
   1958       APPEND(maybe_newline2);
   1959       APPEND("</frame>");
   1960 
   1961    } else {
   1962 
   1963       /* Print for humans to read */
   1964       //
   1965       // Possible forms:
   1966       //
   1967       //   0x80483BF: really (a.c:20)
   1968       //   0x80483BF: really (in /foo/a.out)
   1969       //   0x80483BF: really (in ???)
   1970       //   0x80483BF: ??? (in /foo/a.out)
   1971       //   0x80483BF: ??? (a.c:20)
   1972       //   0x80483BF: ???
   1973       //
   1974       VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip);
   1975       APPEND(ibuf);
   1976       if (know_fnname) {
   1977          APPEND(buf_fn);
   1978       } else {
   1979          APPEND("???");
   1980       }
   1981       if (know_srcloc) {
   1982          APPEND(" (");
   1983          // Get the directory name, if any, possibly pruned, into dirname.
   1984          HChar* dirname = NULL;
   1985          if (VG_(clo_n_fullpath_after) > 0) {
   1986             Int i;
   1987             dirname = buf_dirname;
   1988             // Remove leading prefixes from the dirname.
   1989             // If user supplied --fullpath-after=foo, this will remove
   1990             // a leading string which matches '.*foo' (not greedy).
   1991             for (i = 0; i < VG_(clo_n_fullpath_after); i++) {
   1992                const HChar* prefix = VG_(clo_fullpath_after)[i];
   1993                HChar* str    = VG_(strstr)(dirname, prefix);
   1994                if (str) {
   1995                   dirname = str + VG_(strlen)(prefix);
   1996                   break;
   1997                }
   1998             }
   1999             /* remove leading "./" */
   2000             if (dirname[0] == '.' && dirname[1] == '/')
   2001                dirname += 2;
   2002          }
   2003          // do we have any interesting directory name to show?  If so
   2004          // add it in.
   2005          if (dirname && dirname[0] != 0) {
   2006             APPEND(dirname);
   2007             APPEND("/");
   2008          }
   2009          APPEND(buf_srcloc);
   2010          APPEND(":");
   2011          VG_(sprintf)(ibuf,"%d",lineno);
   2012          APPEND(ibuf);
   2013          APPEND(")");
   2014       } else if (know_objname) {
   2015          APPEND(" (in ");
   2016          APPEND(buf_obj);
   2017          APPEND(")");
   2018       } else if (know_fnname) {
   2019          // Nb: do this in two steps because "??)" is a trigraph!
   2020          APPEND(" (in ???");
   2021          APPEND(")");
   2022       }
   2023 
   2024    }
   2025    return buf;
   2026 
   2027 #  undef APPEND
   2028 #  undef APPEND_ESC
   2029 #  undef BUF_LEN
   2030 }
   2031 
   2032 
   2033 /*--------------------------------------------------------------*/
   2034 /*---                                                        ---*/
   2035 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING               ---*/
   2036 /*---            DWARF3 .eh_frame INFO                       ---*/
   2037 /*---                                                        ---*/
   2038 /*--------------------------------------------------------------*/
   2039 
   2040 /* Gather up all the constant pieces of info needed to evaluate
   2041    a CfiExpr into one convenient struct. */
   2042 typedef
   2043    struct {
   2044       D3UnwindRegs* uregs;
   2045       Addr          min_accessible;
   2046       Addr          max_accessible;
   2047    }
   2048    CfiExprEvalContext;
   2049 
   2050 /* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
   2051    *ok is set to False on failure, but not to True on success.  The
   2052    caller must set it to True before calling. */
   2053 __attribute__((noinline))
   2054 static
   2055 UWord evalCfiExpr ( XArray* exprs, Int ix,
   2056                     CfiExprEvalContext* eec, Bool* ok )
   2057 {
   2058    UWord w, wL, wR;
   2059    Addr  a;
   2060    CfiExpr* e;
   2061    vg_assert(sizeof(Addr) == sizeof(UWord));
   2062    e = VG_(indexXA)( exprs, ix );
   2063    switch (e->tag) {
   2064       case Cex_Unop:
   2065          w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
   2066          if (!(*ok)) return 0;
   2067          switch (e->Cex.Unop.op) {
   2068             case Cunop_Abs: return (Word) w < 0 ? - w : w;
   2069             case Cunop_Neg: return - (Word) w;
   2070             case Cunop_Not: return ~ w;
   2071             default: goto unhandled;
   2072          }
   2073          /*NOTREACHED*/
   2074       case Cex_Binop:
   2075          wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
   2076          if (!(*ok)) return 0;
   2077          wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
   2078          if (!(*ok)) return 0;
   2079          switch (e->Cex.Binop.op) {
   2080             case Cbinop_Add: return wL + wR;
   2081             case Cbinop_Sub: return wL - wR;
   2082             case Cbinop_And: return wL & wR;
   2083             case Cbinop_Mul: return wL * wR;
   2084             case Cbinop_Shl: return wL << wR;
   2085             case Cbinop_Shr: return wL >> wR;
   2086             case Cbinop_Eq: return wL == wR ? 1 : 0;
   2087             case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
   2088             case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
   2089             case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
   2090             case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
   2091             case Cbinop_Ne: return wL != wR ? 1 : 0;
   2092             default: goto unhandled;
   2093          }
   2094          /*NOTREACHED*/
   2095       case Cex_CfiReg:
   2096          switch (e->Cex.CfiReg.reg) {
   2097 #           if defined(VGA_x86) || defined(VGA_amd64)
   2098             case Creg_IA_IP: return eec->uregs->xip;
   2099             case Creg_IA_SP: return eec->uregs->xsp;
   2100             case Creg_IA_BP: return eec->uregs->xbp;
   2101 #           elif defined(VGA_arm)
   2102             case Creg_ARM_R15: return eec->uregs->r15;
   2103             case Creg_ARM_R14: return eec->uregs->r14;
   2104             case Creg_ARM_R13: return eec->uregs->r13;
   2105             case Creg_ARM_R12: return eec->uregs->r12;
   2106 #           elif defined(VGA_s390x)
   2107             case Creg_IA_IP: return eec->uregs->ia;
   2108             case Creg_IA_SP: return eec->uregs->sp;
   2109             case Creg_IA_BP: return eec->uregs->fp;
   2110             case Creg_S390_R14: return eec->uregs->lr;
   2111 #           elif defined(VGA_mips32) || defined(VGA_mips64)
   2112             case Creg_IA_IP: return eec->uregs->pc;
   2113             case Creg_IA_SP: return eec->uregs->sp;
   2114             case Creg_IA_BP: return eec->uregs->fp;
   2115             case Creg_MIPS_RA: return eec->uregs->ra;
   2116 #           elif defined(VGA_ppc32) || defined(VGA_ppc64)
   2117 #           elif defined(VGP_arm64_linux)
   2118             case Creg_ARM64_X30: return eec->uregs->x30;
   2119 #           else
   2120 #             error "Unsupported arch"
   2121 #           endif
   2122             default: goto unhandled;
   2123          }
   2124          /*NOTREACHED*/
   2125       case Cex_Const:
   2126          return e->Cex.Const.con;
   2127       case Cex_Deref:
   2128          a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
   2129          if (!(*ok)) return 0;
   2130          if (a < eec->min_accessible
   2131              || a > eec->max_accessible - sizeof(UWord) + 1) {
   2132             *ok = False;
   2133             return 0;
   2134          }
   2135          /* let's hope it doesn't trap! */
   2136          return ML_(read_UWord)((void *)a);
   2137       default:
   2138          goto unhandled;
   2139    }
   2140    /*NOTREACHED*/
   2141   unhandled:
   2142    VG_(printf)("\n\nevalCfiExpr: unhandled\n");
   2143    ML_(ppCfiExpr)( exprs, ix );
   2144    VG_(printf)("\n");
   2145    vg_assert(0);
   2146    /*NOTREACHED*/
   2147    return 0;
   2148 }
   2149 
   2150 
   2151 /* Search all the DebugInfos in the entire system, to find the DiCfSI
   2152    that pertains to 'ip'.
   2153 
   2154    If found, set *diP to the DebugInfo in which it resides, and
   2155    *ixP to the index in that DebugInfo's cfsi array.
   2156 
   2157    If not found, set *diP to (DebugInfo*)1 and *ixP to zero.
   2158 */
   2159 __attribute__((noinline))
   2160 static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
   2161                           /*OUT*/Word* ixP,
   2162                           Addr ip )
   2163 {
   2164    DebugInfo* di;
   2165    Word       i = -1;
   2166 
   2167    static UWord n_search = 0;
   2168    static UWord n_steps = 0;
   2169    n_search++;
   2170 
   2171    if (0) VG_(printf)("search for %#lx\n", ip);
   2172 
   2173    for (di = debugInfo_list; di != NULL; di = di->next) {
   2174       Word j;
   2175       n_steps++;
   2176 
   2177       /* Use the per-DebugInfo summary address ranges to skip
   2178          inapplicable DebugInfos quickly. */
   2179       if (di->cfsi_used == 0)
   2180          continue;
   2181       if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
   2182          continue;
   2183 
   2184       /* It might be in this DebugInfo.  Search it. */
   2185       j = ML_(search_one_cfitab)( di, ip );
   2186       vg_assert(j >= -1 && j < (Word)di->cfsi_used);
   2187 
   2188       if (j != -1) {
   2189          i = j;
   2190          break; /* found it */
   2191       }
   2192    }
   2193 
   2194    if (i == -1) {
   2195 
   2196       /* we didn't find it. */
   2197       *diP = (DebugInfo*)1;
   2198       *ixP = 0;
   2199 
   2200    } else {
   2201 
   2202       /* found it. */
   2203       /* ensure that di is 4-aligned (at least), so it can't possibly
   2204          be equal to (DebugInfo*)1. */
   2205       vg_assert(di && VG_IS_4_ALIGNED(di));
   2206       vg_assert(i >= 0 && i < di->cfsi_used);
   2207       *diP = di;
   2208       *ixP = i;
   2209 
   2210       /* Start of performance-enhancing hack: once every 64 (chosen
   2211          hackily after profiling) successful searches, move the found
   2212          DebugInfo one step closer to the start of the list.  This
   2213          makes future searches cheaper.  For starting konqueror on
   2214          amd64, this in fact reduces the total amount of searching
   2215          done by the above find-the-right-DebugInfo loop by more than
   2216          a factor of 20. */
   2217       if ((n_search & 0xF) == 0) {
   2218          /* Move di one step closer to the start of the list. */
   2219          move_DebugInfo_one_step_forward( di );
   2220       }
   2221       /* End of performance-enhancing hack. */
   2222 
   2223       if (0 && ((n_search & 0x7FFFF) == 0))
   2224          VG_(printf)("find_DiCfSI: %lu searches, "
   2225                      "%lu DebugInfos looked at\n",
   2226                      n_search, n_steps);
   2227 
   2228    }
   2229 
   2230 }
   2231 
   2232 
   2233 /* Now follows a mechanism for caching queries to find_DiCfSI, since
   2234    they are extremely frequent on amd64-linux, during stack unwinding.
   2235 
   2236    Each cache entry binds an ip value to a (di, ix) pair.  Possible
   2237    values:
   2238 
   2239    di is non-null, ix >= 0  ==>  cache slot in use, "di->cfsi[ix]"
   2240    di is (DebugInfo*)1      ==>  cache slot in use, no associated di
   2241    di is NULL               ==>  cache slot not in use
   2242 
   2243    Hence simply zeroing out the entire cache invalidates all
   2244    entries.
   2245 
   2246    Why not map ip values directly to DiCfSI*'s?  Because this would
   2247    cause problems if/when the cfsi array is moved due to resizing.
   2248    Instead we cache .cfsi array index value, which should be invariant
   2249    across resizing.  (That said, I don't think the current
   2250    implementation will resize whilst during queries, since the DiCfSI
   2251    records are added all at once, when the debuginfo for an object is
   2252    read, and is not changed ever thereafter. */
   2253 
   2254 // Prime number, giving about 3K cache on 32 bits, 6K cache on 64 bits.
   2255 #define N_CFSI_CACHE 509
   2256 
   2257 typedef
   2258    struct { Addr ip; DebugInfo* di; Word ix; }
   2259    CFSICacheEnt;
   2260 
   2261 static CFSICacheEnt cfsi_cache[N_CFSI_CACHE];
   2262 
   2263 static void cfsi_cache__invalidate ( void ) {
   2264    VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache));
   2265    CF_info_generation++;
   2266 }
   2267 
   2268 UInt VG_(CF_info_generation) (void)
   2269 {
   2270    return CF_info_generation;
   2271 }
   2272 
   2273 static inline CFSICacheEnt* cfsi_cache__find ( Addr ip )
   2274 {
   2275    UWord         hash = ip % N_CFSI_CACHE;
   2276    CFSICacheEnt* ce = &cfsi_cache[hash];
   2277    static UWord  n_q = 0, n_m = 0;
   2278 
   2279    n_q++;
   2280    if (0 && 0 == (n_q & 0x1FFFFF))
   2281       VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
   2282 
   2283    if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
   2284       /* found an entry in the cache .. */
   2285    } else {
   2286       /* not found in cache.  Search and update. */
   2287       n_m++;
   2288       ce->ip = ip;
   2289       find_DiCfSI( &ce->di, &ce->ix, ip );
   2290    }
   2291 
   2292    if (UNLIKELY(ce->di == (DebugInfo*)1)) {
   2293       /* no DiCfSI for this address */
   2294       return NULL;
   2295    } else {
   2296       /* found a DiCfSI for this address */
   2297       return ce;
   2298    }
   2299 }
   2300 
   2301 
   2302 inline
   2303 static Addr compute_cfa ( D3UnwindRegs* uregs,
   2304                           Addr min_accessible, Addr max_accessible,
   2305                           DebugInfo* di, DiCfSI* cfsi )
   2306 {
   2307    CfiExprEvalContext eec;
   2308    Addr               cfa;
   2309    Bool               ok;
   2310 
   2311    /* Compute the CFA. */
   2312    cfa = 0;
   2313    switch (cfsi->cfa_how) {
   2314 #     if defined(VGA_x86) || defined(VGA_amd64)
   2315       case CFIC_IA_SPREL:
   2316          cfa = cfsi->cfa_off + uregs->xsp;
   2317          break;
   2318       case CFIC_IA_BPREL:
   2319          cfa = cfsi->cfa_off + uregs->xbp;
   2320          break;
   2321 #     elif defined(VGA_arm)
   2322       case CFIC_ARM_R13REL:
   2323          cfa = cfsi->cfa_off + uregs->r13;
   2324          break;
   2325       case CFIC_ARM_R12REL:
   2326          cfa = cfsi->cfa_off + uregs->r12;
   2327          break;
   2328       case CFIC_ARM_R11REL:
   2329          cfa = cfsi->cfa_off + uregs->r11;
   2330          break;
   2331       case CFIC_ARM_R7REL:
   2332          cfa = cfsi->cfa_off + uregs->r7;
   2333          break;
   2334 #     elif defined(VGA_s390x)
   2335       case CFIC_IA_SPREL:
   2336          cfa = cfsi->cfa_off + uregs->sp;
   2337          break;
   2338       case CFIR_MEMCFAREL:
   2339       {
   2340          Addr a = uregs->sp + cfsi->cfa_off;
   2341          if (a < min_accessible || a > max_accessible-sizeof(Addr))
   2342             break;
   2343          cfa = ML_(read_Addr)((void *)a);
   2344          break;
   2345       }
   2346       case CFIR_SAME:
   2347          cfa = uregs->fp;
   2348          break;
   2349       case CFIC_IA_BPREL:
   2350          cfa = cfsi->cfa_off + uregs->fp;
   2351          break;
   2352 #     elif defined(VGA_mips32) || defined(VGA_mips64)
   2353       case CFIC_IA_SPREL:
   2354          cfa = cfsi->cfa_off + uregs->sp;
   2355          break;
   2356       case CFIR_SAME:
   2357          cfa = uregs->fp;
   2358          break;
   2359       case CFIC_IA_BPREL:
   2360          cfa = cfsi->cfa_off + uregs->fp;
   2361          break;
   2362 #     elif defined(VGA_ppc32) || defined(VGA_ppc64)
   2363 #     elif defined(VGP_arm64_linux)
   2364       case CFIC_ARM64_SPREL:
   2365          cfa = cfsi->cfa_off + uregs->sp;
   2366          break;
   2367       case CFIC_ARM64_X29REL:
   2368          cfa = cfsi->cfa_off + uregs->x29;
   2369          break;
   2370 #     else
   2371 #       error "Unsupported arch"
   2372 #     endif
   2373       case CFIC_EXPR: /* available on all archs */
   2374          if (0) {
   2375             VG_(printf)("CFIC_EXPR: ");
   2376             ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off);
   2377             VG_(printf)("\n");
   2378          }
   2379          eec.uregs          = uregs;
   2380          eec.min_accessible = min_accessible;
   2381          eec.max_accessible = max_accessible;
   2382          ok = True;
   2383          cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
   2384          if (!ok) return 0;
   2385          break;
   2386       default:
   2387          vg_assert(0);
   2388    }
   2389    return cfa;
   2390 }
   2391 
   2392 
   2393 /* Get the call frame address (CFA) given an IP/SP/FP triple. */
   2394 /* NOTE: This function may rearrange the order of entries in the
   2395    DebugInfo list. */
   2396 Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
   2397                     Addr min_accessible, Addr max_accessible )
   2398 {
   2399    CFSICacheEnt* ce;
   2400    DebugInfo*    di;
   2401    DiCfSI*       cfsi __attribute__((unused));
   2402 
   2403    ce = cfsi_cache__find(ip);
   2404 
   2405    if (UNLIKELY(ce == NULL))
   2406       return 0; /* no info.  Nothing we can do. */
   2407 
   2408    di = ce->di;
   2409    cfsi = &di->cfsi[ ce->ix ];
   2410 
   2411    /* Temporary impedance-matching kludge so that this keeps working
   2412       on x86-linux and amd64-linux. */
   2413 #  if defined(VGA_x86) || defined(VGA_amd64)
   2414    { D3UnwindRegs uregs;
   2415      uregs.xip = ip;
   2416      uregs.xsp = sp;
   2417      uregs.xbp = fp;
   2418      return compute_cfa(&uregs,
   2419                         min_accessible,  max_accessible, di, cfsi);
   2420    }
   2421 #elif defined(VGA_s390x)
   2422    { D3UnwindRegs uregs;
   2423      uregs.ia = ip;
   2424      uregs.sp = sp;
   2425      uregs.fp = fp;
   2426      return compute_cfa(&uregs,
   2427                         min_accessible,  max_accessible, di, cfsi);
   2428    }
   2429 #elif defined(VGA_mips32) || defined(VGA_mips64)
   2430    { D3UnwindRegs uregs;
   2431      uregs.pc = ip;
   2432      uregs.sp = sp;
   2433      uregs.fp = fp;
   2434      return compute_cfa(&uregs,
   2435                         min_accessible,  max_accessible, di, cfsi);
   2436    }
   2437 
   2438 #  else
   2439    return 0; /* indicates failure */
   2440 #  endif
   2441 }
   2442 
   2443 
   2444 /* The main function for DWARF2/3 CFI-based stack unwinding.  Given a
   2445    set of registers in UREGS, modify it to hold the register values
   2446    for the previous frame, if possible.  Returns True if successful.
   2447    If not successful, *UREGS is not changed.
   2448 
   2449    For x86 and amd64, the unwound registers are: {E,R}IP,
   2450    {E,R}SP, {E,R}BP.
   2451 
   2452    For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
   2453 
   2454    For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
   2455 */
   2456 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
   2457                         Addr min_accessible,
   2458                         Addr max_accessible )
   2459 {
   2460    DebugInfo*         di;
   2461    DiCfSI*            cfsi = NULL;
   2462    Addr               cfa, ipHere = 0;
   2463    CFSICacheEnt*      ce;
   2464    CfiExprEvalContext eec __attribute__((unused));
   2465    D3UnwindRegs       uregsPrev;
   2466 
   2467 #  if defined(VGA_x86) || defined(VGA_amd64)
   2468    ipHere = uregsHere->xip;
   2469 #  elif defined(VGA_arm)
   2470    ipHere = uregsHere->r15;
   2471 #  elif defined(VGA_s390x)
   2472    ipHere = uregsHere->ia;
   2473 #  elif defined(VGA_mips32) || defined(VGA_mips64)
   2474    ipHere = uregsHere->pc;
   2475 #  elif defined(VGA_ppc32) || defined(VGA_ppc64)
   2476 #  elif defined(VGP_arm64_linux)
   2477    ipHere = uregsHere->pc;
   2478 #  else
   2479 #    error "Unknown arch"
   2480 #  endif
   2481    ce = cfsi_cache__find(ipHere);
   2482 
   2483    if (UNLIKELY(ce == NULL))
   2484       return False; /* no info.  Nothing we can do. */
   2485 
   2486    di = ce->di;
   2487    cfsi = &di->cfsi[ ce->ix ];
   2488 
   2489    if (0) {
   2490       VG_(printf)("found cfisi: ");
   2491       ML_(ppDiCfSI)(di->cfsi_exprs, cfsi);
   2492    }
   2493 
   2494    VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
   2495 
   2496    /* First compute the CFA. */
   2497    cfa = compute_cfa(uregsHere,
   2498                      min_accessible, max_accessible, di, cfsi);
   2499    if (UNLIKELY(cfa == 0))
   2500       return False;
   2501 
   2502    /* Now we know the CFA, use it to roll back the registers we're
   2503       interested in. */
   2504 
   2505 #  define COMPUTE(_prev, _here, _how, _off)             \
   2506       do {                                              \
   2507          switch (_how) {                                \
   2508             case CFIR_UNKNOWN:                          \
   2509                return False;                            \
   2510             case CFIR_SAME:                             \
   2511                _prev = _here; break;                    \
   2512             case CFIR_MEMCFAREL: {                      \
   2513                Addr a = cfa + (Word)_off;               \
   2514                if (a < min_accessible                   \
   2515                    || a > max_accessible-sizeof(Addr))  \
   2516                   return False;                         \
   2517                _prev = ML_(read_Addr)((void *)a);       \
   2518                break;                                   \
   2519             }                                           \
   2520             case CFIR_CFAREL:                           \
   2521                _prev = cfa + (Word)_off;                \
   2522                break;                                   \
   2523             case CFIR_EXPR:                             \
   2524                if (0)                                   \
   2525                   ML_(ppCfiExpr)(di->cfsi_exprs,_off);  \
   2526                eec.uregs = uregsHere;                   \
   2527                eec.min_accessible = min_accessible;     \
   2528                eec.max_accessible = max_accessible;     \
   2529                Bool ok = True;                          \
   2530                _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
   2531                if (!ok) return False;                   \
   2532                break;                                   \
   2533             default:                                    \
   2534                vg_assert(0);                            \
   2535          }                                              \
   2536       } while (0)
   2537 
   2538 #  if defined(VGA_x86) || defined(VGA_amd64)
   2539    COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi->ra_how, cfsi->ra_off);
   2540    COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi->sp_how, cfsi->sp_off);
   2541    COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi->bp_how, cfsi->bp_off);
   2542 #  elif defined(VGA_arm)
   2543    COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi->ra_how,  cfsi->ra_off);
   2544    COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi->r14_how, cfsi->r14_off);
   2545    COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi->r13_how, cfsi->r13_off);
   2546    COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi->r12_how, cfsi->r12_off);
   2547    COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi->r11_how, cfsi->r11_off);
   2548    COMPUTE(uregsPrev.r7,  uregsHere->r7,  cfsi->r7_how,  cfsi->r7_off);
   2549 #  elif defined(VGA_s390x)
   2550    COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off);
   2551    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
   2552    COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
   2553 #  elif defined(VGA_mips32) || defined(VGA_mips64)
   2554    COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi->ra_how, cfsi->ra_off);
   2555    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
   2556    COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
   2557 #  elif defined(VGA_ppc32) || defined(VGA_ppc64)
   2558 #  elif defined(VGP_arm64_linux)
   2559    COMPUTE(uregsPrev.pc,  uregsHere->pc,  cfsi->ra_how,  cfsi->ra_off);
   2560    COMPUTE(uregsPrev.sp,  uregsHere->sp,  cfsi->sp_how,  cfsi->sp_off);
   2561    COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi->x30_how, cfsi->x30_off);
   2562    COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi->x29_how, cfsi->x29_off);
   2563 #  else
   2564 #    error "Unknown arch"
   2565 #  endif
   2566 
   2567 #  undef COMPUTE
   2568 
   2569    *uregsHere = uregsPrev;
   2570    return True;
   2571 }
   2572 
   2573 
   2574 /*--------------------------------------------------------------*/
   2575 /*---                                                        ---*/
   2576 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING               ---*/
   2577 /*---            MSVC FPO INFO                               ---*/
   2578 /*---                                                        ---*/
   2579 /*--------------------------------------------------------------*/
   2580 
   2581 Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
   2582                          /*MOD*/Addr* spP,
   2583                          /*MOD*/Addr* fpP,
   2584                          Addr min_accessible,
   2585                          Addr max_accessible )
   2586 {
   2587    Word       i;
   2588    DebugInfo* di;
   2589    FPO_DATA*  fpo = NULL;
   2590    Addr       spHere;
   2591 
   2592    static UWord n_search = 0;
   2593    static UWord n_steps = 0;
   2594    n_search++;
   2595 
   2596    if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
   2597 
   2598    for (di = debugInfo_list; di != NULL; di = di->next) {
   2599       n_steps++;
   2600 
   2601       /* Use the per-DebugInfo summary address ranges to skip
   2602          inapplicable DebugInfos quickly. */
   2603       if (di->fpo == NULL)
   2604          continue;
   2605       if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
   2606          continue;
   2607 
   2608       i = ML_(search_one_fpotab)( di, *ipP );
   2609       if (i != -1) {
   2610          Word j;
   2611          if (0) {
   2612             /* debug printing only */
   2613             VG_(printf)("look for %#lx  size %ld i %ld\n",
   2614                         *ipP, di->fpo_size, i);
   2615             for (j = 0; j < di->fpo_size; j++)
   2616                VG_(printf)("[%02ld] %#x %d\n",
   2617                             j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
   2618          }
   2619          vg_assert(i >= 0 && i < di->fpo_size);
   2620          fpo = &di->fpo[i];
   2621          break;
   2622       }
   2623    }
   2624 
   2625    if (fpo == NULL)
   2626       return False;
   2627 
   2628    if (0 && ((n_search & 0x7FFFF) == 0))
   2629       VG_(printf)("VG_(use_FPO_info): %lu searches, "
   2630                   "%lu DebugInfos looked at\n",
   2631                   n_search, n_steps);
   2632 
   2633 
   2634    /* Start of performance-enhancing hack: once every 64 (chosen
   2635       hackily after profiling) successful searches, move the found
   2636       DebugInfo one step closer to the start of the list.  This makes
   2637       future searches cheaper.  For starting konqueror on amd64, this
   2638       in fact reduces the total amount of searching done by the above
   2639       find-the-right-DebugInfo loop by more than a factor of 20. */
   2640    if ((n_search & 0x3F) == 0) {
   2641       /* Move si one step closer to the start of the list. */
   2642       //move_DebugInfo_one_step_forward( di );
   2643    }
   2644    /* End of performance-enhancing hack. */
   2645 
   2646    if (0) {
   2647       VG_(printf)("found fpo: ");
   2648       //ML_(ppFPO)(fpo);
   2649    }
   2650 
   2651    /*
   2652    Stack layout is:
   2653    %esp->
   2654       4*.cbRegs  {%edi, %esi, %ebp, %ebx}
   2655       4*.cdwLocals
   2656       return_pc
   2657       4*.cdwParams
   2658    prior_%esp->
   2659 
   2660    Typical code looks like:
   2661       sub $4*.cdwLocals,%esp
   2662          Alternative to above for >=4KB (and sometimes for smaller):
   2663             mov $size,%eax
   2664             call __chkstk  # WinNT performs page-by-page probe!
   2665                __chkstk is much like alloc(), except that on return
   2666                %eax= 5+ &CALL.  Thus it could be used as part of
   2667                Position Independent Code to locate the Global Offset Table.
   2668       push %ebx
   2669       push %ebp
   2670       push %esi
   2671          Other once-only instructions often scheduled >here<.
   2672       push %edi
   2673 
   2674    If the pc is within the first .cbProlog bytes of the function,
   2675    then you must disassemble to see how many registers have been pushed,
   2676    because instructions in the prolog may be scheduled for performance.
   2677    The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
   2678    registers not pushed when .cbRegs < 4.  This seems somewhat strange
   2679    because %ebp is the register whose usage you want to minimize,
   2680    yet it is in the first half of the PUSH list.
   2681 
   2682    I don't know what happens when the compiler constructs an outgoing CALL.
   2683    %esp could move if outgoing parameters are PUSHed, and this affects
   2684    traceback for errors during the PUSHes. */
   2685 
   2686    spHere = *spP;
   2687 
   2688    *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
   2689    *spP =                         spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
   2690                                                           + fpo->cdwParams);
   2691    *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
   2692    return True;
   2693 }
   2694 
   2695 
   2696 /*--------------------------------------------------------------*/
   2697 /*---                                                        ---*/
   2698 /*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES      ---*/
   2699 /*---            FROM DWARF3 DEBUG INFO                      ---*/
   2700 /*---                                                        ---*/
   2701 /*--------------------------------------------------------------*/
   2702 
   2703 /* Try to make p2XA(dst, fmt, args..) turn into
   2704    VG_(xaprintf)(dst, fmt, args) without having to resort to
   2705    vararg macros.  As usual with everything to do with varargs, it's
   2706    an ugly hack.
   2707 
   2708    //#define p2XA(dstxa, format, args...)
   2709    //   VG_(xaprintf)(dstxa, format, ##args)
   2710 */
   2711 #define  p2XA  VG_(xaprintf)
   2712 
   2713 /* Add a zero-terminating byte to DST, which must be an XArray* of
   2714    HChar. */
   2715 static void zterm_XA ( XArray* dst )
   2716 {
   2717    HChar zero = 0;
   2718    (void) VG_(addBytesToXA)( dst, &zero, 1 );
   2719 }
   2720 
   2721 
   2722 /* Evaluate the location expression/list for var, to see whether or
   2723    not data_addr falls within the variable.  If so also return the
   2724    offset of data_addr from the start of the variable.  Note that
   2725    regs, which supplies ip,sp,fp values, will be NULL for global
   2726    variables, and non-NULL for local variables. */
   2727 static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
   2728                                      XArray* /* TyEnt */ tyents,
   2729                                      DiVariable*   var,
   2730                                      RegSummary*   regs,
   2731                                      Addr          data_addr,
   2732                                      const DebugInfo* di )
   2733 {
   2734    MaybeULong mul;
   2735    SizeT      var_szB;
   2736    GXResult   res;
   2737    Bool       show = False;
   2738 
   2739    vg_assert(var->name);
   2740    vg_assert(var->gexpr);
   2741 
   2742    /* Figure out how big the variable is. */
   2743    mul = ML_(sizeOfType)(tyents, var->typeR);
   2744    /* If this var has a type whose size is unknown, zero, or
   2745       impossibly large, it should never have been added.  ML_(addVar)
   2746       should have rejected it. */
   2747    vg_assert(mul.b == True);
   2748    vg_assert(mul.ul > 0);
   2749    if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
   2750    /* After this point, we assume we can truncate mul.ul to a host word
   2751       safely (without loss of info). */
   2752 
   2753    var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
   2754 
   2755    if (show) {
   2756       VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
   2757                   data_addr, var->name );
   2758       ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
   2759       VG_(printf)("\n");
   2760    }
   2761 
   2762    /* ignore zero-sized vars; they can never match anything. */
   2763    if (var_szB == 0) {
   2764       if (show)
   2765          VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
   2766       return False;
   2767    }
   2768 
   2769    res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
   2770 
   2771    if (show) {
   2772       VG_(printf)("VVVV: -> ");
   2773       ML_(pp_GXResult)( res );
   2774       VG_(printf)("\n");
   2775    }
   2776 
   2777    if (res.kind == GXR_Addr
   2778        && res.word <= data_addr
   2779        && data_addr < res.word + var_szB) {
   2780       *offset = data_addr - res.word;
   2781       return True;
   2782    } else {
   2783       return False;
   2784    }
   2785 }
   2786 
   2787 
   2788 /* Format the acquired information into DN(AME)1 and DN(AME)2, which
   2789    are XArray*s of HChar, that have been initialised by the caller.
   2790    Resulting strings will be zero terminated.  Information is
   2791    formatted in an understandable way.  Not so easy.  If frameNo is
   2792    -1, this is assumed to be a global variable; else a local
   2793    variable. */
   2794 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
   2795                              /*MOD*/XArray* /* of HChar */ dn2,
   2796                              Addr     data_addr,
   2797                              DiVariable* var,
   2798                              PtrdiffT var_offset,
   2799                              PtrdiffT residual_offset,
   2800                              XArray* /*UChar*/ described,
   2801                              Int      frameNo,
   2802                              ThreadId tid )
   2803 {
   2804    Bool   have_descr, have_srcloc;
   2805    Bool   xml       = VG_(clo_xml);
   2806    const HChar* vo_plural = var_offset == 1 ? "" : "s";
   2807    const HChar* ro_plural = residual_offset == 1 ? "" : "s";
   2808    const HChar* basetag   = "auxwhat"; /* a constant */
   2809    HChar tagL[32], tagR[32], xagL[32], xagR[32];
   2810 
   2811    if (frameNo < -1) {
   2812       vg_assert(0); /* Not allowed */
   2813    }
   2814    else if (frameNo == -1) {
   2815       vg_assert(tid == VG_INVALID_THREADID);
   2816    }
   2817    else /* (frameNo >= 0) */ {
   2818       vg_assert(tid != VG_INVALID_THREADID);
   2819    }
   2820 
   2821    vg_assert(dn1 && dn2);
   2822    vg_assert(described);
   2823    vg_assert(var && var->name);
   2824    have_descr = VG_(sizeXA)(described) > 0
   2825                 && *(UChar*)VG_(indexXA)(described,0) != '\0';
   2826    have_srcloc = var->fileName && var->lineNo > 0;
   2827 
   2828    tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
   2829    if (xml) {
   2830       VG_(sprintf)(tagL, "<%s>",   basetag); // <auxwhat>
   2831       VG_(sprintf)(tagR, "</%s>",  basetag); // </auxwhat>
   2832       VG_(sprintf)(xagL, "<x%s>",  basetag); // <xauxwhat>
   2833       VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
   2834    }
   2835 
   2836 #  define TAGL(_xa) p2XA(_xa, "%s", tagL)
   2837 #  define TAGR(_xa) p2XA(_xa, "%s", tagR)
   2838 #  define XAGL(_xa) p2XA(_xa, "%s", xagL)
   2839 #  define XAGR(_xa) p2XA(_xa, "%s", xagR)
   2840 #  define TXTL(_xa) p2XA(_xa, "%s", "<text>")
   2841 #  define TXTR(_xa) p2XA(_xa, "%s", "</text>")
   2842 
   2843    /* ------ local cases ------ */
   2844 
   2845    if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
   2846       /* no srcloc, no description:
   2847          Location 0x7fefff6cf is 543 bytes inside local var "a",
   2848          in frame #1 of thread 1
   2849       */
   2850       if (xml) {
   2851          TAGL( dn1 );
   2852          p2XA( dn1,
   2853                "Location 0x%lx is %lu byte%s inside local var \"%pS\",",
   2854                data_addr, var_offset, vo_plural, var->name );
   2855          TAGR( dn1 );
   2856          TAGL( dn2 );
   2857          p2XA( dn2,
   2858                "in frame #%d of thread %d", frameNo, (Int)tid );
   2859          TAGR( dn2 );
   2860       } else {
   2861          p2XA( dn1,
   2862                "Location 0x%lx is %lu byte%s inside local var \"%s\",",
   2863                data_addr, var_offset, vo_plural, var->name );
   2864          p2XA( dn2,
   2865                "in frame #%d of thread %d", frameNo, (Int)tid );
   2866       }
   2867    }
   2868    else
   2869    if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
   2870       /* no description:
   2871          Location 0x7fefff6cf is 543 bytes inside local var "a"
   2872          declared at dsyms7.c:17, in frame #1 of thread 1
   2873       */
   2874       if (xml) {
   2875          TAGL( dn1 );
   2876          p2XA( dn1,
   2877                "Location 0x%lx is %lu byte%s inside local var \"%pS\"",
   2878                data_addr, var_offset, vo_plural, var->name );
   2879          TAGR( dn1 );
   2880          XAGL( dn2 );
   2881          TXTL( dn2 );
   2882          p2XA( dn2,
   2883                "declared at %pS:%d, in frame #%d of thread %d",
   2884                var->fileName, var->lineNo, frameNo, (Int)tid );
   2885          TXTR( dn2 );
   2886          // FIXME: also do <dir>
   2887          p2XA( dn2,
   2888                " <file>%pS</file> <line>%d</line> ",
   2889                var->fileName, var->lineNo );
   2890          XAGR( dn2 );
   2891       } else {
   2892          p2XA( dn1,
   2893                "Location 0x%lx is %lu byte%s inside local var \"%s\"",
   2894                data_addr, var_offset, vo_plural, var->name );
   2895          p2XA( dn2,
   2896                "declared at %s:%d, in frame #%d of thread %d",
   2897                var->fileName, var->lineNo, frameNo, (Int)tid );
   2898       }
   2899    }
   2900    else
   2901    if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
   2902       /* no srcloc:
   2903          Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
   2904          in frame #1 of thread 1
   2905       */
   2906       if (xml) {
   2907          TAGL( dn1 );
   2908          p2XA( dn1,
   2909                "Location 0x%lx is %lu byte%s inside %pS%pS",
   2910                data_addr, residual_offset, ro_plural, var->name,
   2911                (HChar*)(VG_(indexXA)(described,0)) );
   2912          TAGR( dn1 );
   2913          TAGL( dn2 );
   2914          p2XA( dn2,
   2915                "in frame #%d of thread %d", frameNo, (Int)tid );
   2916          TAGR( dn2 );
   2917       } else {
   2918          p2XA( dn1,
   2919                "Location 0x%lx is %lu byte%s inside %s%s",
   2920                data_addr, residual_offset, ro_plural, var->name,
   2921                (HChar*)(VG_(indexXA)(described,0)) );
   2922          p2XA( dn2,
   2923                "in frame #%d of thread %d", frameNo, (Int)tid );
   2924       }
   2925    }
   2926    else
   2927    if ( frameNo >= 0 && have_srcloc && have_descr ) {
   2928       /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
   2929          declared at dsyms7.c:17, in frame #1 of thread 1 */
   2930       if (xml) {
   2931          TAGL( dn1 );
   2932          p2XA( dn1,
   2933                "Location 0x%lx is %lu byte%s inside %pS%pS,",
   2934                data_addr, residual_offset, ro_plural, var->name,
   2935                (HChar*)(VG_(indexXA)(described,0)) );
   2936          TAGR( dn1 );
   2937          XAGL( dn2 );
   2938          TXTL( dn2 );
   2939          p2XA( dn2,
   2940                "declared at %pS:%d, in frame #%d of thread %d",
   2941                var->fileName, var->lineNo, frameNo, (Int)tid );
   2942          TXTR( dn2 );
   2943          // FIXME: also do <dir>
   2944          p2XA( dn2,
   2945                " <file>%pS</file> <line>%d</line> ",
   2946                var->fileName, var->lineNo );
   2947          XAGR( dn2 );
   2948       } else {
   2949          p2XA( dn1,
   2950                "Location 0x%lx is %lu byte%s inside %s%s,",
   2951                data_addr, residual_offset, ro_plural, var->name,
   2952                (HChar*)(VG_(indexXA)(described,0)) );
   2953          p2XA( dn2,
   2954                "declared at %s:%d, in frame #%d of thread %d",
   2955                var->fileName, var->lineNo, frameNo, (Int)tid );
   2956       }
   2957    }
   2958    else
   2959    /* ------ global cases ------ */
   2960    if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
   2961       /* no srcloc, no description:
   2962          Location 0x7fefff6cf is 543 bytes inside global var "a"
   2963       */
   2964       if (xml) {
   2965          TAGL( dn1 );
   2966          p2XA( dn1,
   2967                "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
   2968                data_addr, var_offset, vo_plural, var->name );
   2969          TAGR( dn1 );
   2970       } else {
   2971          p2XA( dn1,
   2972                "Location 0x%lx is %lu byte%s inside global var \"%s\"",
   2973                data_addr, var_offset, vo_plural, var->name );
   2974       }
   2975    }
   2976    else
   2977    if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
   2978       /* no description:
   2979          Location 0x7fefff6cf is 543 bytes inside global var "a"
   2980          declared at dsyms7.c:17
   2981       */
   2982       if (xml) {
   2983          TAGL( dn1 );
   2984          p2XA( dn1,
   2985                "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
   2986                data_addr, var_offset, vo_plural, var->name );
   2987          TAGR( dn1 );
   2988          XAGL( dn2 );
   2989          TXTL( dn2 );
   2990          p2XA( dn2,
   2991                "declared at %pS:%d",
   2992                var->fileName, var->lineNo);
   2993          TXTR( dn2 );
   2994          // FIXME: also do <dir>
   2995          p2XA( dn2,
   2996                " <file>%pS</file> <line>%d</line> ",
   2997                var->fileName, var->lineNo );
   2998          XAGR( dn2 );
   2999       } else {
   3000          p2XA( dn1,
   3001                "Location 0x%lx is %lu byte%s inside global var \"%s\"",
   3002                data_addr, var_offset, vo_plural, var->name );
   3003          p2XA( dn2,
   3004                "declared at %s:%d",
   3005                var->fileName, var->lineNo);
   3006       }
   3007    }
   3008    else
   3009    if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
   3010       /* no srcloc:
   3011          Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
   3012          a global variable
   3013       */
   3014       if (xml) {
   3015          TAGL( dn1 );
   3016          p2XA( dn1,
   3017                "Location 0x%lx is %lu byte%s inside %pS%pS,",
   3018                data_addr, residual_offset, ro_plural, var->name,
   3019                (HChar*)(VG_(indexXA)(described,0)) );
   3020          TAGR( dn1 );
   3021          TAGL( dn2 );
   3022          p2XA( dn2,
   3023                "a global variable");
   3024          TAGR( dn2 );
   3025       } else {
   3026          p2XA( dn1,
   3027                "Location 0x%lx is %lu byte%s inside %s%s,",
   3028                data_addr, residual_offset, ro_plural, var->name,
   3029                (char*)(VG_(indexXA)(described,0)) );
   3030          p2XA( dn2,
   3031                "a global variable");
   3032       }
   3033    }
   3034    else
   3035    if ( frameNo >= -1 && have_srcloc && have_descr ) {
   3036       /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
   3037          a global variable declared at dsyms7.c:17 */
   3038       if (xml) {
   3039          TAGL( dn1 );
   3040          p2XA( dn1,
   3041                "Location 0x%lx is %lu byte%s inside %pS%pS,",
   3042                data_addr, residual_offset, ro_plural, var->name,
   3043                (HChar*)(VG_(indexXA)(described,0)) );
   3044          TAGR( dn1 );
   3045          XAGL( dn2 );
   3046          TXTL( dn2 );
   3047          p2XA( dn2,
   3048                "a global variable declared at %pS:%d",
   3049                var->fileName, var->lineNo);
   3050          TXTR( dn2 );
   3051          // FIXME: also do <dir>
   3052          p2XA( dn2,
   3053                " <file>%pS</file> <line>%d</line> ",
   3054                var->fileName, var->lineNo );
   3055          XAGR( dn2 );
   3056       } else {
   3057          p2XA( dn1,
   3058                "Location 0x%lx is %lu byte%s inside %s%s,",
   3059                data_addr, residual_offset, ro_plural, var->name,
   3060                (HChar*)(VG_(indexXA)(described,0)) );
   3061          p2XA( dn2,
   3062                "a global variable declared at %s:%d",
   3063                var->fileName, var->lineNo);
   3064       }
   3065    }
   3066    else
   3067       vg_assert(0);
   3068 
   3069    /* Zero terminate both strings */
   3070    zterm_XA( dn1 );
   3071    zterm_XA( dn2 );
   3072 
   3073 #  undef TAGL
   3074 #  undef TAGR
   3075 #  undef XAGL
   3076 #  undef XAGR
   3077 #  undef TXTL
   3078 #  undef TXTR
   3079 }
   3080 
   3081 
   3082 /* Determine if data_addr is a local variable in the frame
   3083    characterised by (ip,sp,fp), and if so write its description at the
   3084    ends of DNAME{1,2}, which are XArray*s of HChar, that have been
   3085    initialised by the caller, zero terminate both, and return True.
   3086    If it's not a local variable in said frame, return False. */
   3087 static
   3088 Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
   3089                               /*MOD*/XArray* /* of HChar */ dname2,
   3090                               Addr data_addr,
   3091                               Addr ip, Addr sp, Addr fp,
   3092                               /* shown to user: */
   3093                               ThreadId tid, Int frameNo )
   3094 {
   3095    Word       i;
   3096    DebugInfo* di;
   3097    RegSummary regs;
   3098    Bool debug = False;
   3099 
   3100    static UInt n_search = 0;
   3101    static UInt n_steps = 0;
   3102    n_search++;
   3103    if (debug)
   3104       VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
   3105    /* first, find the DebugInfo that pertains to 'ip'. */
   3106    for (di = debugInfo_list; di; di = di->next) {
   3107       n_steps++;
   3108       /* text segment missing? unlikely, but handle it .. */
   3109       if (!di->text_present || di->text_size == 0)
   3110          continue;
   3111       /* Ok.  So does this text mapping bracket the ip? */
   3112       if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
   3113          break;
   3114    }
   3115 
   3116    /* Didn't find it.  Strange -- means ip is a code address outside
   3117       of any mapped text segment.  Unlikely but not impossible -- app
   3118       could be generating code to run. */
   3119    if (!di)
   3120       return False;
   3121 
   3122    if (0 && ((n_search & 0x1) == 0))
   3123       VG_(printf)("consider_vars_in_frame: %u searches, "
   3124                   "%u DebugInfos looked at\n",
   3125                   n_search, n_steps);
   3126    /* Start of performance-enhancing hack: once every ??? (chosen
   3127       hackily after profiling) successful searches, move the found
   3128       DebugInfo one step closer to the start of the list.  This makes
   3129       future searches cheaper. */
   3130    if ((n_search & 0xFFFF) == 0) {
   3131       /* Move si one step closer to the start of the list. */
   3132       move_DebugInfo_one_step_forward( di );
   3133    }
   3134    /* End of performance-enhancing hack. */
   3135 
   3136    /* any var info at all? */
   3137    if (!di->varinfo)
   3138       return False;
   3139 
   3140    /* Work through the scopes from most deeply nested outwards,
   3141       looking for code address ranges that bracket 'ip'.  The
   3142       variables on each such address range found are in scope right
   3143       now.  Don't descend to level zero as that is the global
   3144       scope. */
   3145    regs.ip = ip;
   3146    regs.sp = sp;
   3147    regs.fp = fp;
   3148 
   3149    /* "for each scope, working outwards ..." */
   3150    for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
   3151       XArray*      vars;
   3152       Word         j;
   3153       DiAddrRange* arange;
   3154       OSet*        this_scope
   3155          = *(OSet**)VG_(indexXA)( di->varinfo, i );
   3156       if (debug)
   3157          VG_(printf)("QQQQ:   considering scope %ld\n", (Word)i);
   3158       if (!this_scope)
   3159          continue;
   3160       /* Find the set of variables in this scope that
   3161          bracket the program counter. */
   3162       arange = VG_(OSetGen_LookupWithCmp)(
   3163                   this_scope, &ip,
   3164                   ML_(cmp_for_DiAddrRange_range)
   3165                );
   3166       if (!arange)
   3167          continue;
   3168       /* stay sane */
   3169       vg_assert(arange->aMin <= arange->aMax);
   3170       /* It must bracket the ip we asked for, else
   3171          ML_(cmp_for_DiAddrRange_range) is somehow broken. */
   3172       vg_assert(arange->aMin <= ip && ip <= arange->aMax);
   3173       /* It must have an attached XArray of DiVariables. */
   3174       vars = arange->vars;
   3175       vg_assert(vars);
   3176       /* But it mustn't cover the entire address range.  We only
   3177          expect that to happen for the global scope (level 0), which
   3178          we're not looking at here.  Except, it may cover the entire
   3179          address range, but in that case the vars array must be
   3180          empty. */
   3181       vg_assert(! (arange->aMin == (Addr)0
   3182                    && arange->aMax == ~(Addr)0
   3183                    && VG_(sizeXA)(vars) > 0) );
   3184       for (j = 0; j < VG_(sizeXA)( vars ); j++) {
   3185          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
   3186          PtrdiffT    offset;
   3187          if (debug)
   3188             VG_(printf)("QQQQ:    var:name=%s %#lx-%#lx %#lx\n",
   3189                         var->name,arange->aMin,arange->aMax,ip);
   3190          if (data_address_is_in_var( &offset, di->admin_tyents,
   3191                                      var, &regs,
   3192                                      data_addr, di )) {
   3193             PtrdiffT residual_offset = 0;
   3194             XArray* described = ML_(describe_type)( &residual_offset,
   3195                                                     di->admin_tyents,
   3196                                                     var->typeR, offset );
   3197             format_message( dname1, dname2,
   3198                             data_addr, var, offset, residual_offset,
   3199                             described, frameNo, tid );
   3200             VG_(deleteXA)( described );
   3201             return True;
   3202          }
   3203       }
   3204    }
   3205 
   3206    return False;
   3207 }
   3208 
   3209 /* Try to form some description of DATA_ADDR by looking at the DWARF3
   3210    debug info we have.  This considers all global variables, and 8
   3211    frames in the stacks of all threads.  Result is written at the ends
   3212    of DNAME{1,2}V, which are XArray*s of HChar, that have been
   3213    initialised by the caller, and True is returned.  If no description
   3214    is created, False is returned.  Regardless of the return value,
   3215    DNAME{1,2}V are guaranteed to be zero terminated after the call.
   3216 
   3217    Note that after the call, DNAME{1,2} may have more than one
   3218    trailing zero, so callers should establish the useful text length
   3219    using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
   3220    XArray itself.
   3221 */
   3222 Bool VG_(get_data_description)(
   3223         /*MOD*/ void* /* really, XArray* of HChar */ dname1v,
   3224         /*MOD*/ void* /* really, XArray* of HChar */ dname2v,
   3225         Addr data_addr
   3226      )
   3227 {
   3228 #  define N_FRAMES 8
   3229    Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
   3230    UInt n_frames;
   3231 
   3232    Addr       stack_min, stack_max;
   3233    ThreadId   tid;
   3234    Bool       found;
   3235    DebugInfo* di;
   3236    Word       j;
   3237 
   3238    XArray*    dname1 = (XArray*)dname1v;
   3239    XArray*    dname2 = (XArray*)dname2v;
   3240 
   3241    if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
   3242    /* First, see if data_addr is (or is part of) a global variable.
   3243       Loop over the DebugInfos we have.  Check data_addr against the
   3244       outermost scope of all of them, as that should be a global
   3245       scope. */
   3246    for (di = debugInfo_list; di != NULL; di = di->next) {
   3247       OSet*        global_scope;
   3248       Word         gs_size;
   3249       Addr         zero;
   3250       DiAddrRange* global_arange;
   3251       Word         i;
   3252       XArray*      vars;
   3253 
   3254       /* text segment missing? unlikely, but handle it .. */
   3255       if (!di->text_present || di->text_size == 0)
   3256          continue;
   3257       /* any var info at all? */
   3258       if (!di->varinfo)
   3259          continue;
   3260       /* perhaps this object didn't contribute any vars at all? */
   3261       if (VG_(sizeXA)( di->varinfo ) == 0)
   3262          continue;
   3263       global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
   3264       vg_assert(global_scope);
   3265       gs_size = VG_(OSetGen_Size)( global_scope );
   3266       /* The global scope might be completely empty if this
   3267          compilation unit declared locals but nothing global. */
   3268       if (gs_size == 0)
   3269           continue;
   3270       /* But if it isn't empty, then it must contain exactly one
   3271          element, which covers the entire address range. */
   3272       vg_assert(gs_size == 1);
   3273       /* Fish out the global scope and check it is as expected. */
   3274       zero = 0;
   3275       global_arange
   3276          = VG_(OSetGen_Lookup)( global_scope, &zero );
   3277       /* The global range from (Addr)0 to ~(Addr)0 must exist */
   3278       vg_assert(global_arange);
   3279       vg_assert(global_arange->aMin == (Addr)0
   3280                 && global_arange->aMax == ~(Addr)0);
   3281       /* Any vars in this range? */
   3282       if (!global_arange->vars)
   3283          continue;
   3284       /* Ok, there are some vars in the global scope of this
   3285          DebugInfo.  Wade through them and see if the data addresses
   3286          of any of them bracket data_addr. */
   3287       vars = global_arange->vars;
   3288       for (i = 0; i < VG_(sizeXA)( vars ); i++) {
   3289          PtrdiffT offset;
   3290          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
   3291          vg_assert(var->name);
   3292          /* Note we use a NULL RegSummary* here.  It can't make any
   3293             sense for a global variable to have a location expression
   3294             which depends on a SP/FP/IP value.  So don't supply any.
   3295             This means, if the evaluation of the location
   3296             expression/list requires a register, we have to let it
   3297             fail. */
   3298          if (data_address_is_in_var( &offset, di->admin_tyents, var,
   3299                                      NULL/* RegSummary* */,
   3300                                      data_addr, di )) {
   3301             PtrdiffT residual_offset = 0;
   3302             XArray* described = ML_(describe_type)( &residual_offset,
   3303                                                     di->admin_tyents,
   3304                                                     var->typeR, offset );
   3305             format_message( dname1, dname2,
   3306                             data_addr, var, offset, residual_offset,
   3307                             described, -1/*frameNo*/,
   3308                             VG_INVALID_THREADID );
   3309             VG_(deleteXA)( described );
   3310             zterm_XA( dname1 );
   3311             zterm_XA( dname2 );
   3312             return True;
   3313          }
   3314       }
   3315    }
   3316 
   3317    /* Ok, well it's not a global variable.  So now let's snoop around
   3318       in the stacks of all the threads.  First try to figure out which
   3319       thread's stack data_addr is in. */
   3320 
   3321    /* Perhaps it's on a thread's stack? */
   3322    found = False;
   3323    VG_(thread_stack_reset_iter)(&tid);
   3324    while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
   3325       if (stack_min >= stack_max)
   3326          continue; /* ignore obviously stupid cases */
   3327       if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
   3328           && data_addr <= stack_max) {
   3329          found = True;
   3330          break;
   3331       }
   3332    }
   3333    if (!found) {
   3334       zterm_XA( dname1 );
   3335       zterm_XA( dname2 );
   3336       return False;
   3337    }
   3338 
   3339    /* We conclude data_addr is in thread tid's stack.  Unwind the
   3340       stack to get a bunch of (ip,sp,fp) triples describing the
   3341       frames, and for each frame, consider the local variables. */
   3342    n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
   3343                                    sps, fps, 0/*first_ip_delta*/ );
   3344 
   3345    vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
   3346    for (j = 0; j < n_frames; j++) {
   3347       if (consider_vars_in_frame( dname1, dname2,
   3348                                   data_addr,
   3349                                   ips[j],
   3350                                   sps[j], fps[j], tid, j )) {
   3351          zterm_XA( dname1 );
   3352          zterm_XA( dname2 );
   3353          return True;
   3354       }
   3355       /* Now, it appears that gcc sometimes appears to produce
   3356          location lists whose ranges don't actually cover the call
   3357          instruction, even though the address of the variable in
   3358          question is passed as a parameter in the call.  AFAICS this
   3359          is simply a bug in gcc - how can the variable be claimed not
   3360          exist in memory (on the stack) for the duration of a call in
   3361          which its address is passed?  But anyway, in the particular
   3362          case I investigated (memcheck/tests/varinfo6.c, call to croak
   3363          on line 2999, local var budget declared at line 3115
   3364          appearing not to exist across the call to mainSort on line
   3365          3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
   3366          amd64), the variable's location list does claim it exists
   3367          starting at the first byte of the first instruction after the
   3368          call instruction.  So, call consider_vars_in_frame a second
   3369          time, but this time add 1 to the IP.  GDB handles this
   3370          example with no difficulty, which leads me to believe that
   3371          either (1) I misunderstood something, or (2) GDB has an
   3372          equivalent kludge. */
   3373       if (j > 0 /* this is a non-innermost frame */
   3374           && consider_vars_in_frame( dname1, dname2,
   3375                                      data_addr,
   3376                                      ips[j] + 1,
   3377                                      sps[j], fps[j], tid, j )) {
   3378          zterm_XA( dname1 );
   3379          zterm_XA( dname2 );
   3380          return True;
   3381       }
   3382    }
   3383 
   3384    /* We didn't find anything useful. */
   3385    zterm_XA( dname1 );
   3386    zterm_XA( dname2 );
   3387    return False;
   3388 #  undef N_FRAMES
   3389 }
   3390 
   3391 
   3392 //////////////////////////////////////////////////////////////////
   3393 //                                                              //
   3394 // Support for other kinds of queries to the Dwarf3 var info    //
   3395 //                                                              //
   3396 //////////////////////////////////////////////////////////////////
   3397 
   3398 /* Figure out if the variable 'var' has a location that is linearly
   3399    dependent on a stack pointer value, or a frame pointer value, and
   3400    if it is, add a description of it to 'blocks'.  Otherwise ignore
   3401    it.  If 'arrays_only' is True, also ignore it unless it has an
   3402    array type. */
   3403 
   3404 static
   3405 void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
   3406                     XArray* /* TyEnt */ tyents,
   3407                     Addr ip, const DebugInfo* di, DiVariable* var,
   3408                     Bool arrays_only )
   3409 {
   3410    GXResult   res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
   3411    RegSummary regs;
   3412    MaybeULong mul;
   3413    Bool       isVec;
   3414    TyEnt*     ty;
   3415 
   3416    Bool debug = False;
   3417    if (0&&debug)
   3418       VG_(printf)("adeps: var %s\n", var->name );
   3419 
   3420    /* Figure out how big the variable is. */
   3421    mul = ML_(sizeOfType)(tyents, var->typeR);
   3422    /* If this var has a type whose size is unknown, zero, or
   3423       impossibly large, it should never have been added.  ML_(addVar)
   3424       should have rejected it. */
   3425    vg_assert(mul.b == True);
   3426    vg_assert(mul.ul > 0);
   3427    if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
   3428    /* After this point, we assume we can truncate mul.ul to a host word
   3429       safely (without loss of info). */
   3430 
   3431    /* skip if non-array and we're only interested in arrays */
   3432    ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
   3433    vg_assert(ty);
   3434    vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
   3435    if (ty->tag == Te_UNKNOWN)
   3436       return; /* perhaps we should complain in this case? */
   3437    isVec = ty->tag == Te_TyArray;
   3438    if (arrays_only && !isVec)
   3439       return;
   3440 
   3441    if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
   3442            VG_(printf)("  %s\n", var->name);}
   3443 
   3444    /* Do some test evaluations of the variable's location expression,
   3445       in order to guess whether it is sp-relative, fp-relative, or
   3446       none.  A crude hack, which can be interpreted roughly as finding
   3447       the first derivative of the location expression w.r.t. the
   3448       supplied frame and stack pointer values. */
   3449    regs.fp   = 0;
   3450    regs.ip   = ip;
   3451    regs.sp   = 6 * 1024;
   3452    res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
   3453 
   3454    regs.fp   = 0;
   3455    regs.ip   = ip;
   3456    regs.sp   = 7 * 1024;
   3457    res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
   3458 
   3459    regs.fp   = 6 * 1024;
   3460    regs.ip   = ip;
   3461    regs.sp   = 0;
   3462    res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
   3463 
   3464    regs.fp   = 7 * 1024;
   3465    regs.ip   = ip;
   3466    regs.sp   = 0;
   3467    res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
   3468 
   3469    vg_assert(res_sp_6k.kind == res_sp_7k.kind);
   3470    vg_assert(res_sp_6k.kind == res_fp_6k.kind);
   3471    vg_assert(res_sp_6k.kind == res_fp_7k.kind);
   3472 
   3473    if (res_sp_6k.kind == GXR_Addr) {
   3474       StackBlock block;
   3475       GXResult res;
   3476       UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
   3477       UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
   3478       tl_assert(sp_delta == 0 || sp_delta == 1024);
   3479       tl_assert(fp_delta == 0 || fp_delta == 1024);
   3480 
   3481       if (sp_delta == 0 && fp_delta == 0) {
   3482          /* depends neither on sp nor fp, so it can't be a stack
   3483             local.  Ignore it. */
   3484       }
   3485       else
   3486       if (sp_delta == 1024 && fp_delta == 0) {
   3487          regs.sp = regs.fp = 0;
   3488          regs.ip = ip;
   3489          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
   3490          tl_assert(res.kind == GXR_Addr);
   3491          if (debug)
   3492          VG_(printf)("   %5ld .. %5ld (sp) %s\n",
   3493                      res.word, res.word + ((UWord)mul.ul) - 1, var->name);
   3494          block.base  = res.word;
   3495          block.szB   = (SizeT)mul.ul;
   3496          block.spRel = True;
   3497          block.isVec = isVec;
   3498          VG_(memset)( &block.name[0], 0, sizeof(block.name) );
   3499          if (var->name)
   3500             VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
   3501          block.name[ sizeof(block.name)-1 ] = 0;
   3502          VG_(addToXA)( blocks, &block );
   3503       }
   3504       else
   3505       if (sp_delta == 0 && fp_delta == 1024) {
   3506          regs.sp = regs.fp = 0;
   3507          regs.ip = ip;
   3508          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
   3509          tl_assert(res.kind == GXR_Addr);
   3510          if (debug)
   3511          VG_(printf)("   %5ld .. %5ld (FP) %s\n",
   3512                      res.word, res.word + ((UWord)mul.ul) - 1, var->name);
   3513          block.base  = res.word;
   3514          block.szB   = (SizeT)mul.ul;
   3515          block.spRel = False;
   3516          block.isVec = isVec;
   3517          VG_(memset)( &block.name[0], 0, sizeof(block.name) );
   3518          if (var->name)
   3519             VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
   3520          block.name[ sizeof(block.name)-1 ] = 0;
   3521          VG_(addToXA)( blocks, &block );
   3522       }
   3523       else {
   3524          vg_assert(0);
   3525       }
   3526    }
   3527 }
   3528 
   3529 
   3530 /* Get an XArray of StackBlock which describe the stack (auto) blocks
   3531    for this ip.  The caller is expected to free the XArray at some
   3532    point.  If 'arrays_only' is True, only array-typed blocks are
   3533    returned; otherwise blocks of all types are returned. */
   3534 
   3535 void* /* really, XArray* of StackBlock */
   3536       VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
   3537 {
   3538    /* This is a derivation of consider_vars_in_frame() above. */
   3539    Word       i;
   3540    DebugInfo* di;
   3541    Bool debug = False;
   3542 
   3543    XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
   3544                              ML_(dinfo_free),
   3545                              sizeof(StackBlock) );
   3546 
   3547    static UInt n_search = 0;
   3548    static UInt n_steps = 0;
   3549    n_search++;
   3550    if (debug)
   3551       VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
   3552    /* first, find the DebugInfo that pertains to 'ip'. */
   3553    for (di = debugInfo_list; di; di = di->next) {
   3554       n_steps++;
   3555       /* text segment missing? unlikely, but handle it .. */
   3556       if (!di->text_present || di->text_size == 0)
   3557          continue;
   3558       /* Ok.  So does this text mapping bracket the ip? */
   3559       if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
   3560          break;
   3561    }
   3562 
   3563    /* Didn't find it.  Strange -- means ip is a code address outside
   3564       of any mapped text segment.  Unlikely but not impossible -- app
   3565       could be generating code to run. */
   3566    if (!di)
   3567       return res; /* currently empty */
   3568 
   3569    if (0 && ((n_search & 0x1) == 0))
   3570       VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
   3571                   "%u DebugInfos looked at\n",
   3572                   n_search, n_steps);
   3573    /* Start of performance-enhancing hack: once every ??? (chosen
   3574       hackily after profiling) successful searches, move the found
   3575       DebugInfo one step closer to the start of the list.  This makes
   3576       future searches cheaper. */
   3577    if ((n_search & 0xFFFF) == 0) {
   3578       /* Move si one step closer to the start of the list. */
   3579       move_DebugInfo_one_step_forward( di );
   3580    }
   3581    /* End of performance-enhancing hack. */
   3582 
   3583    /* any var info at all? */
   3584    if (!di->varinfo)
   3585       return res; /* currently empty */
   3586 
   3587    /* Work through the scopes from most deeply nested outwards,
   3588       looking for code address ranges that bracket 'ip'.  The
   3589       variables on each such address range found are in scope right
   3590       now.  Don't descend to level zero as that is the global
   3591       scope. */
   3592 
   3593    /* "for each scope, working outwards ..." */
   3594    for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
   3595       XArray*      vars;
   3596       Word         j;
   3597       DiAddrRange* arange;
   3598       OSet*        this_scope
   3599          = *(OSet**)VG_(indexXA)( di->varinfo, i );
   3600       if (debug)
   3601          VG_(printf)("QQQQ:   considering scope %ld\n", (Word)i);
   3602       if (!this_scope)
   3603          continue;
   3604       /* Find the set of variables in this scope that
   3605          bracket the program counter. */
   3606       arange = VG_(OSetGen_LookupWithCmp)(
   3607                   this_scope, &ip,
   3608                   ML_(cmp_for_DiAddrRange_range)
   3609                );
   3610       if (!arange)
   3611          continue;
   3612       /* stay sane */
   3613       vg_assert(arange->aMin <= arange->aMax);
   3614       /* It must bracket the ip we asked for, else
   3615          ML_(cmp_for_DiAddrRange_range) is somehow broken. */
   3616       vg_assert(arange->aMin <= ip && ip <= arange->aMax);
   3617       /* It must have an attached XArray of DiVariables. */
   3618       vars = arange->vars;
   3619       vg_assert(vars);
   3620       /* But it mustn't cover the entire address range.  We only
   3621          expect that to happen for the global scope (level 0), which
   3622          we're not looking at here.  Except, it may cover the entire
   3623          address range, but in that case the vars array must be
   3624          empty. */
   3625       vg_assert(! (arange->aMin == (Addr)0
   3626                    && arange->aMax == ~(Addr)0
   3627                    && VG_(sizeXA)(vars) > 0) );
   3628       for (j = 0; j < VG_(sizeXA)( vars ); j++) {
   3629          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
   3630          if (debug)
   3631             VG_(printf)("QQQQ:    var:name=%s %#lx-%#lx %#lx\n",
   3632                         var->name,arange->aMin,arange->aMax,ip);
   3633          analyse_deps( res, di->admin_tyents, ip,
   3634                        di, var, arrays_only );
   3635       }
   3636    }
   3637 
   3638    return res;
   3639 }
   3640 
   3641 
   3642 /* Get an array of GlobalBlock which describe the global blocks owned
   3643    by the shared object characterised by the given di_handle.  Asserts
   3644    if the handle is invalid.  The caller is responsible for freeing
   3645    the array at some point.  If 'arrays_only' is True, only
   3646    array-typed blocks are returned; otherwise blocks of all types are
   3647    returned. */
   3648 
   3649 void* /* really, XArray* of GlobalBlock */
   3650       VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle,
   3651                                                 Bool  arrays_only )
   3652 {
   3653    /* This is a derivation of consider_vars_in_frame() above. */
   3654 
   3655    DebugInfo* di;
   3656    XArray* gvars; /* XArray* of GlobalBlock */
   3657    Word nScopes, scopeIx;
   3658 
   3659    /* The first thing to do is find the DebugInfo that
   3660       pertains to 'di_handle'. */
   3661    tl_assert(di_handle > 0);
   3662    for (di = debugInfo_list; di; di = di->next) {
   3663       if (di->handle == di_handle)
   3664          break;
   3665    }
   3666 
   3667    /* If this fails, we were unable to find any DebugInfo with the
   3668       given handle.  This is considered an error on the part of the
   3669       caller. */
   3670    tl_assert(di != NULL);
   3671 
   3672    /* we'll put the collected variables in here. */
   3673    gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
   3674                        ML_(dinfo_free), sizeof(GlobalBlock) );
   3675    tl_assert(gvars);
   3676 
   3677    /* any var info at all? */
   3678    if (!di->varinfo)
   3679       return gvars;
   3680 
   3681    /* we'll iterate over all the variables we can find, even if
   3682       it seems senseless to visit stack-allocated variables */
   3683    /* Iterate over all scopes */
   3684    nScopes = VG_(sizeXA)( di->varinfo );
   3685    for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
   3686 
   3687       /* Iterate over each (code) address range at the current scope */
   3688       DiAddrRange* range;
   3689       OSet* /* of DiAddrInfo */ scope
   3690          = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
   3691       tl_assert(scope);
   3692       VG_(OSetGen_ResetIter)(scope);
   3693       while ( (range = VG_(OSetGen_Next)(scope)) ) {
   3694 
   3695          /* Iterate over each variable in the current address range */
   3696          Word nVars, varIx;
   3697          tl_assert(range->vars);
   3698          nVars = VG_(sizeXA)( range->vars );
   3699          for (varIx = 0; varIx < nVars; varIx++) {
   3700 
   3701             Bool        isVec;
   3702             GXResult    res;
   3703             MaybeULong  mul;
   3704             GlobalBlock gb;
   3705             TyEnt*      ty;
   3706             DiVariable* var = VG_(indexXA)( range->vars, varIx );
   3707             tl_assert(var->name);
   3708             if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
   3709 
   3710             /* Now figure out if this variable has a constant address
   3711                (that is, independent of FP, SP, phase of moon, etc),
   3712                and if so, what the address is.  Any variable with a
   3713                constant address is deemed to be a global so we collect
   3714                it. */
   3715             if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
   3716                      VG_(printf)("\n"); }
   3717             res = ML_(evaluate_trivial_GX)( var->gexpr, di );
   3718 
   3719             /* Not a constant address => not interesting */
   3720             if (res.kind != GXR_Addr) {
   3721                if (0) VG_(printf)("FAIL\n");
   3722                continue;
   3723             }
   3724 
   3725             /* Ok, it's a constant address.  See if we want to collect
   3726                it. */
   3727             if (0) VG_(printf)("%#lx\n", res.word);
   3728 
   3729             /* Figure out how big the variable is. */
   3730             mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
   3731 
   3732             /* If this var has a type whose size is unknown, zero, or
   3733                impossibly large, it should never have been added.
   3734                ML_(addVar) should have rejected it. */
   3735             vg_assert(mul.b == True);
   3736             vg_assert(mul.ul > 0);
   3737             if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
   3738             /* After this point, we assume we can truncate mul.ul to a
   3739                host word safely (without loss of info). */
   3740 
   3741             /* skip if non-array and we're only interested in
   3742                arrays */
   3743             ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
   3744                                               var->typeR );
   3745             vg_assert(ty);
   3746             vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
   3747             if (ty->tag == Te_UNKNOWN)
   3748                continue; /* perhaps we should complain in this case? */
   3749 
   3750             isVec = ty->tag == Te_TyArray;
   3751             if (arrays_only && !isVec) continue;
   3752 
   3753             /* Ok, so collect it! */
   3754             tl_assert(var->name);
   3755             tl_assert(di->soname);
   3756             if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
   3757                                 var->fileName?(HChar*)var->fileName
   3758                                              :"??",var->lineNo);
   3759             VG_(memset)(&gb, 0, sizeof(gb));
   3760             gb.addr  = res.word;
   3761             gb.szB   = (SizeT)mul.ul;
   3762             gb.isVec = isVec;
   3763             VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
   3764             VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
   3765             tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
   3766             tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
   3767 
   3768             VG_(addToXA)( gvars, &gb );
   3769 
   3770          } /* for (varIx = 0; varIx < nVars; varIx++) */
   3771 
   3772       } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
   3773 
   3774    } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
   3775 
   3776    return gvars;
   3777 }
   3778 
   3779 
   3780 /*------------------------------------------------------------*/
   3781 /*--- DebugInfo accessor functions                         ---*/
   3782 /*------------------------------------------------------------*/
   3783 
   3784 const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
   3785 {
   3786    if (di == NULL)
   3787       return debugInfo_list;
   3788    return di->next;
   3789 }
   3790 
   3791 Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
   3792 {
   3793    return di->text_present ? di->text_avma : 0;
   3794 }
   3795 
   3796 SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
   3797 {
   3798    return di->text_present ? di->text_size : 0;
   3799 }
   3800 
   3801 Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di)
   3802 {
   3803    return di->bss_present ? di->bss_avma : 0;
   3804 }
   3805 
   3806 SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di)
   3807 {
   3808    return di->bss_present ? di->bss_size : 0;
   3809 }
   3810 
   3811 Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
   3812 {
   3813    return di->plt_present ? di->plt_avma : 0;
   3814 }
   3815 
   3816 SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
   3817 {
   3818    return di->plt_present ? di->plt_size : 0;
   3819 }
   3820 
   3821 Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
   3822 {
   3823    return di->gotplt_present ? di->gotplt_avma : 0;
   3824 }
   3825 
   3826 SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
   3827 {
   3828    return di->gotplt_present ? di->gotplt_size : 0;
   3829 }
   3830 
   3831 Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di)
   3832 {
   3833    return di->got_present ? di->got_avma : 0;
   3834 }
   3835 
   3836 SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di)
   3837 {
   3838    return di->got_present ? di->got_size : 0;
   3839 }
   3840 
   3841 const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
   3842 {
   3843    return di->soname;
   3844 }
   3845 
   3846 const HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
   3847 {
   3848    return di->fsm.filename;
   3849 }
   3850 
   3851 PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
   3852 {
   3853    return di->text_present ? di->text_bias : 0;
   3854 }
   3855 
   3856 Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
   3857 {
   3858    return si->symtab_used;
   3859 }
   3860 
   3861 void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
   3862                                         Int idx,
   3863                                   /*OUT*/Addr*    avma,
   3864                                   /*OUT*/Addr*    tocptr,
   3865                                   /*OUT*/UInt*    size,
   3866                                   /*OUT*/HChar**  pri_name,
   3867                                   /*OUT*/HChar*** sec_names,
   3868                                   /*OUT*/Bool*    isText,
   3869                                   /*OUT*/Bool*    isIFunc )
   3870 {
   3871    vg_assert(idx >= 0 && idx < si->symtab_used);
   3872    if (avma)      *avma      = si->symtab[idx].addr;
   3873    if (tocptr)    *tocptr    = si->symtab[idx].tocptr;
   3874    if (size)      *size      = si->symtab[idx].size;
   3875    if (pri_name)  *pri_name  = si->symtab[idx].pri_name;
   3876    if (sec_names) *sec_names = (HChar **)si->symtab[idx].sec_names; // FIXME
   3877    if (isText)    *isText    = si->symtab[idx].isText;
   3878    if (isIFunc)   *isIFunc   = si->symtab[idx].isIFunc;
   3879 }
   3880 
   3881 
   3882 /*------------------------------------------------------------*/
   3883 /*--- SectKind query functions                             ---*/
   3884 /*------------------------------------------------------------*/
   3885 
   3886 /* Convert a VgSectKind to a string, which must be copied if you want
   3887    to change it. */
   3888 const HChar* VG_(pp_SectKind)( VgSectKind kind )
   3889 {
   3890    switch (kind) {
   3891       case Vg_SectUnknown: return "Unknown";
   3892       case Vg_SectText:    return "Text";
   3893       case Vg_SectData:    return "Data";
   3894       case Vg_SectBSS:     return "BSS";
   3895       case Vg_SectGOT:     return "GOT";
   3896       case Vg_SectPLT:     return "PLT";
   3897       case Vg_SectOPD:     return "OPD";
   3898       case Vg_SectGOTPLT:  return "GOTPLT";
   3899       default:             vg_assert(0);
   3900    }
   3901 }
   3902 
   3903 /* Given an address 'a', make a guess of which section of which object
   3904    it comes from.  If name is non-NULL, then the last n_name-1
   3905    characters of the object's name is put in name[0 .. n_name-2], and
   3906    name[n_name-1] is set to zero (guaranteed zero terminated). */
   3907 
   3908 VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/HChar* name, SizeT n_name,
   3909                                      Addr a)
   3910 {
   3911    DebugInfo* di;
   3912    VgSectKind res = Vg_SectUnknown;
   3913 
   3914    for (di = debugInfo_list; di != NULL; di = di->next) {
   3915 
   3916       if (0)
   3917          VG_(printf)(
   3918             "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld "
   3919             "data=%#lx,%ld bss=%#lx,%ld\n",
   3920             a, di, di->fsm.filename,
   3921             di->got_avma,  di->got_size,
   3922             di->plt_avma,  di->plt_size,
   3923             di->data_avma, di->data_size,
   3924             di->bss_avma,  di->bss_size);
   3925 
   3926       if (di->text_present
   3927           && di->text_size > 0
   3928           && a >= di->text_avma && a < di->text_avma + di->text_size) {
   3929          res = Vg_SectText;
   3930          break;
   3931       }
   3932       if (di->data_present
   3933           && di->data_size > 0
   3934           && a >= di->data_avma && a < di->data_avma + di->data_size) {
   3935          res = Vg_SectData;
   3936          break;
   3937       }
   3938       if (di->sdata_present
   3939           && di->sdata_size > 0
   3940           && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
   3941          res = Vg_SectData;
   3942          break;
   3943       }
   3944       if (di->bss_present
   3945           && di->bss_size > 0
   3946           && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
   3947          res = Vg_SectBSS;
   3948          break;
   3949       }
   3950       if (di->sbss_present
   3951           && di->sbss_size > 0
   3952           && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
   3953          res = Vg_SectBSS;
   3954          break;
   3955       }
   3956       if (di->plt_present
   3957           && di->plt_size > 0
   3958           && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
   3959          res = Vg_SectPLT;
   3960          break;
   3961       }
   3962       if (di->got_present
   3963           && di->got_size > 0
   3964           && a >= di->got_avma && a < di->got_avma + di->got_size) {
   3965          res = Vg_SectGOT;
   3966          break;
   3967       }
   3968       if (di->gotplt_present
   3969           && di->gotplt_size > 0
   3970           && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
   3971          res = Vg_SectGOTPLT;
   3972          break;
   3973       }
   3974       if (di->opd_present
   3975           && di->opd_size > 0
   3976           && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
   3977          res = Vg_SectOPD;
   3978          break;
   3979       }
   3980       /* we could also check for .eh_frame, if anyone really cares */
   3981    }
   3982 
   3983    vg_assert( (di == NULL && res == Vg_SectUnknown)
   3984               || (di != NULL && res != Vg_SectUnknown) );
   3985 
   3986    if (name) {
   3987 
   3988       vg_assert(n_name >= 8);
   3989 
   3990       if (di && di->fsm.filename) {
   3991          Int i, j;
   3992          Int fnlen = VG_(strlen)(di->fsm.filename);
   3993          Int start_at = 1 + fnlen - n_name;
   3994          if (start_at < 0) start_at = 0;
   3995          vg_assert(start_at < fnlen);
   3996          i = start_at; j = 0;
   3997          while (True) {
   3998             vg_assert(j >= 0 && j < n_name);
   3999             vg_assert(i >= 0 && i <= fnlen);
   4000             name[j] = di->fsm.filename[i];
   4001             if (di->fsm.filename[i] == 0) break;
   4002             i++; j++;
   4003          }
   4004          vg_assert(i == fnlen);
   4005       } else {
   4006          VG_(snprintf)(name, n_name, "%s", "???");
   4007       }
   4008 
   4009       name[n_name-1] = 0;
   4010    }
   4011 
   4012    return res;
   4013 
   4014 }
   4015 
   4016 /*--------------------------------------------------------------------*/
   4017 /*--- end                                                          ---*/
   4018 /*--------------------------------------------------------------------*/
   4019