Home | History | Annotate | Download | only in m_debuginfo
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Format-neutral storage of and querying of info acquired from ---*/
      4 /*--- ELF/XCOFF stabs/dwarf1/dwarf2/dwarf3 debug info.             ---*/
      5 /*---                                                    storage.c ---*/
      6 /*--------------------------------------------------------------------*/
      7 
      8 /*
      9    This file is part of Valgrind, a dynamic binary instrumentation
     10    framework.
     11 
     12    Copyright (C) 2000-2011 Julian Seward
     13       jseward (at) acm.org
     14 
     15    This program is free software; you can redistribute it and/or
     16    modify it under the terms of the GNU General Public License as
     17    published by the Free Software Foundation; either version 2 of the
     18    License, or (at your option) any later version.
     19 
     20    This program is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received a copy of the GNU General Public License
     26    along with this program; if not, write to the Free Software
     27    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     28    02111-1307, USA.
     29 
     30    The GNU General Public License is contained in the file COPYING.
     31 */
     32 
     33 /* This file manages the data structures built by the debuginfo
     34    system.  These are: the top level SegInfo list.  For each SegInfo,
     35    there are tables for for address-to-symbol mappings,
     36    address-to-src-file/line mappings, and address-to-CFI-info
     37    mappings.
     38 */
     39 
     40 #include "pub_core_basics.h"
     41 #include "pub_core_options.h"      /* VG_(clo_verbosity) */
     42 #include "pub_core_debuginfo.h"
     43 #include "pub_core_libcassert.h"
     44 #include "pub_core_libcbase.h"
     45 #include "pub_core_libcprint.h"
     46 #include "pub_core_xarray.h"
     47 #include "pub_core_oset.h"
     48 
     49 #include "priv_misc.h"         /* dinfo_zalloc/free/strdup */
     50 #include "priv_d3basics.h"     /* ML_(pp_GX) */
     51 #include "priv_tytypes.h"
     52 #include "priv_storage.h"      /* self */
     53 
     54 
     55 /*------------------------------------------------------------*/
     56 /*--- Misc (printing, errors)                              ---*/
     57 /*------------------------------------------------------------*/
     58 
     59 /* Show a non-fatal debug info reading error.  Use vg_panic if
     60    terminal.  'serious' errors are shown regardless of the
     61    verbosity setting. */
     62 void ML_(symerr) ( struct _DebugInfo* di, Bool serious, HChar* msg )
     63 {
     64    /* XML mode hides everything :-( */
     65    if (VG_(clo_xml))
     66       return;
     67 
     68    if (serious) {
     69 
     70       VG_(message)(Vg_DebugMsg, "WARNING: Serious error when "
     71                                 "reading debug info\n");
     72       if (True || VG_(clo_verbosity) < 2) {
     73          /* Need to show what the file name is, at verbosity levels 2
     74             or below, since that won't already have been shown */
     75          VG_(message)(Vg_DebugMsg,
     76                       "When reading debug info from %s:\n",
     77                       (di && di->fsm.filename) ? di->fsm.filename
     78                                                : (UChar*)"???");
     79       }
     80       VG_(message)(Vg_DebugMsg, "%s\n", msg);
     81 
     82    } else { /* !serious */
     83 
     84       if (VG_(clo_verbosity) >= 2)
     85          VG_(message)(Vg_DebugMsg, "%s\n", msg);
     86 
     87    }
     88 }
     89 
     90 
     91 /* Print a symbol. */
     92 void ML_(ppSym) ( Int idx, DiSym* sym )
     93 {
     94    UChar** sec_names = sym->sec_names;
     95    vg_assert(sym->pri_name);
     96    if (sec_names)
     97       vg_assert(sec_names);
     98    VG_(printf)( "%5d:  %c%c %#8lx .. %#8lx (%d)      %s%s",
     99                 idx,
    100                 sym->isText ? 'T' : '-',
    101                 sym->isIFunc ? 'I' : '-',
    102                 sym->addr,
    103                 sym->addr + sym->size - 1, sym->size,
    104                 sym->pri_name, sec_names ? " " : "" );
    105    if (sec_names) {
    106       while (*sec_names) {
    107          VG_(printf)("%s%s", *sec_names, *(sec_names+1) ? " " : "");
    108          sec_names++;
    109       }
    110    }
    111    VG_(printf)("\n");
    112 }
    113 
    114 /* Print a call-frame-info summary. */
    115 void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si )
    116 {
    117 #  define SHOW_HOW(_how, _off)                   \
    118       do {                                       \
    119          if (_how == CFIR_UNKNOWN) {             \
    120             VG_(printf)("Unknown");              \
    121          } else                                  \
    122          if (_how == CFIR_SAME) {                \
    123             VG_(printf)("Same");                 \
    124          } else                                  \
    125          if (_how == CFIR_CFAREL) {              \
    126             VG_(printf)("cfa+%d", _off);         \
    127          } else                                  \
    128          if (_how == CFIR_MEMCFAREL) {           \
    129             VG_(printf)("*(cfa+%d)", _off);      \
    130          } else                                  \
    131          if (_how == CFIR_EXPR) {                \
    132             VG_(printf)("{");                    \
    133             ML_(ppCfiExpr)(exprs, _off);         \
    134             VG_(printf)("}");                    \
    135          } else {                                \
    136             vg_assert(0+0);                      \
    137          }                                       \
    138       } while (0)
    139 
    140    VG_(printf)("[%#lx .. %#lx]: ", si->base,
    141                                si->base + (UWord)si->len - 1);
    142    switch (si->cfa_how) {
    143       case CFIC_IA_SPREL:
    144          VG_(printf)("let cfa=oldSP+%d", si->cfa_off);
    145          break;
    146       case CFIC_IA_BPREL:
    147          VG_(printf)("let cfa=oldBP+%d", si->cfa_off);
    148          break;
    149       case CFIC_ARM_R13REL:
    150          VG_(printf)("let cfa=oldR13+%d", si->cfa_off);
    151          break;
    152       case CFIC_ARM_R12REL:
    153          VG_(printf)("let cfa=oldR12+%d", si->cfa_off);
    154          break;
    155       case CFIC_ARM_R11REL:
    156          VG_(printf)("let cfa=oldR11+%d", si->cfa_off);
    157          break;
    158       case CFIR_SAME:
    159          VG_(printf)("let cfa=Same");
    160          break;
    161       case CFIC_ARM_R7REL:
    162          VG_(printf)("let cfa=oldR7+%d", si->cfa_off);
    163          break;
    164       case CFIC_EXPR:
    165          VG_(printf)("let cfa={");
    166          ML_(ppCfiExpr)(exprs, si->cfa_off);
    167          VG_(printf)("}");
    168          break;
    169       default:
    170          vg_assert(0);
    171    }
    172 
    173    VG_(printf)(" in RA=");
    174    SHOW_HOW(si->ra_how, si->ra_off);
    175 #  if defined(VGA_x86) || defined(VGA_amd64)
    176    VG_(printf)(" SP=");
    177    SHOW_HOW(si->sp_how, si->sp_off);
    178    VG_(printf)(" BP=");
    179    SHOW_HOW(si->bp_how, si->bp_off);
    180 #  elif defined(VGA_arm)
    181    VG_(printf)(" R14=");
    182    SHOW_HOW(si->r14_how, si->r14_off);
    183    VG_(printf)(" R13=");
    184    SHOW_HOW(si->r13_how, si->r13_off);
    185    VG_(printf)(" R12=");
    186    SHOW_HOW(si->r12_how, si->r12_off);
    187    VG_(printf)(" R11=");
    188    SHOW_HOW(si->r11_how, si->r11_off);
    189    VG_(printf)(" R7=");
    190    SHOW_HOW(si->r7_how, si->r7_off);
    191 #  elif defined(VGA_ppc32) || defined(VGA_ppc64)
    192 #  elif defined(VGA_s390x)
    193    VG_(printf)(" SP=");
    194    SHOW_HOW(si->sp_how, si->sp_off);
    195    VG_(printf)(" FP=");
    196    SHOW_HOW(si->fp_how, si->fp_off);
    197 #  else
    198 #    error "Unknown arch"
    199 #  endif
    200    VG_(printf)("\n");
    201 #  undef SHOW_HOW
    202 }
    203 
    204 
    205 /*------------------------------------------------------------*/
    206 /*--- Adding stuff                                         ---*/
    207 /*------------------------------------------------------------*/
    208 
    209 /* Add a str to the string table, including terminating zero, and
    210    return pointer to the string in vg_strtab.  Unless it's been seen
    211    recently, in which case we find the old pointer and return that.
    212    This avoids the most egregious duplications.
    213 
    214    JSGF: changed from returning an index to a pointer, and changed to
    215    a chunking memory allocator rather than reallocating, so the
    216    pointers are stable.
    217 */
    218 UChar* ML_(addStr) ( struct _DebugInfo* di, UChar* str, Int len )
    219 {
    220    struct strchunk *chunk;
    221    Int    space_needed;
    222    UChar* p;
    223 
    224    if (len == -1) {
    225       len = VG_(strlen)(str);
    226    } else {
    227       vg_assert(len >= 0);
    228    }
    229 
    230    space_needed = 1 + len;
    231 
    232    // Allocate a new strtab chunk if necessary
    233    if (di->strchunks == NULL ||
    234        (di->strchunks->strtab_used
    235         + space_needed) > SEGINFO_STRCHUNKSIZE) {
    236       chunk = ML_(dinfo_zalloc)("di.storage.addStr.1", sizeof(*chunk));
    237       chunk->strtab_used = 0;
    238       chunk->next = di->strchunks;
    239       di->strchunks = chunk;
    240    }
    241    chunk = di->strchunks;
    242 
    243    p = &chunk->strtab[chunk->strtab_used];
    244    VG_(memcpy)(p, str, len);
    245    chunk->strtab[chunk->strtab_used+len] = '\0';
    246    chunk->strtab_used += space_needed;
    247 
    248    return p;
    249 }
    250 
    251 
    252 /* Add a symbol to the symbol table, by copying *sym.  'sym' may only
    253    have one name, so there's no complexities to do with deep vs
    254    shallow copying of the sec_name array.  This is checked.
    255 */
    256 void ML_(addSym) ( struct _DebugInfo* di, DiSym* sym )
    257 {
    258    UInt   new_sz, i;
    259    DiSym* new_tab;
    260 
    261    vg_assert(sym->pri_name != NULL);
    262    vg_assert(sym->sec_names == NULL);
    263 
    264    /* Ignore zero-sized syms. */
    265    if (sym->size == 0) return;
    266 
    267    if (di->symtab_used == di->symtab_size) {
    268       new_sz = 2 * di->symtab_size;
    269       if (new_sz == 0) new_sz = 500;
    270       new_tab = ML_(dinfo_zalloc)( "di.storage.addSym.1",
    271                                    new_sz * sizeof(DiSym) );
    272       if (di->symtab != NULL) {
    273          for (i = 0; i < di->symtab_used; i++)
    274             new_tab[i] = di->symtab[i];
    275          ML_(dinfo_free)(di->symtab);
    276       }
    277       di->symtab = new_tab;
    278       di->symtab_size = new_sz;
    279    }
    280 
    281    di->symtab[di->symtab_used++] = *sym;
    282    vg_assert(di->symtab_used <= di->symtab_size);
    283 }
    284 
    285 
    286 /* Add a location to the location table.
    287 */
    288 static void addLoc ( struct _DebugInfo* di, DiLoc* loc )
    289 {
    290    UInt   new_sz, i;
    291    DiLoc* new_tab;
    292 
    293    /* Zero-sized locs should have been ignored earlier */
    294    vg_assert(loc->size > 0);
    295 
    296    if (di->loctab_used == di->loctab_size) {
    297       new_sz = 2 * di->loctab_size;
    298       if (new_sz == 0) new_sz = 500;
    299       new_tab = ML_(dinfo_zalloc)( "di.storage.addLoc.1",
    300                                    new_sz * sizeof(DiLoc) );
    301       if (di->loctab != NULL) {
    302          for (i = 0; i < di->loctab_used; i++)
    303             new_tab[i] = di->loctab[i];
    304          ML_(dinfo_free)(di->loctab);
    305       }
    306       di->loctab = new_tab;
    307       di->loctab_size = new_sz;
    308    }
    309 
    310    di->loctab[di->loctab_used] = *loc;
    311    di->loctab_used++;
    312    vg_assert(di->loctab_used <= di->loctab_size);
    313 }
    314 
    315 
    316 /* Resize the LocTab (line number table) to save memory, by removing
    317    (and, potentially, allowing m_mallocfree to unmap) any unused space
    318    at the end of the table.
    319 */
    320 static void shrinkLocTab ( struct _DebugInfo* di )
    321 {
    322    DiLoc* new_tab;
    323    UWord new_sz = di->loctab_used;
    324    if (new_sz == di->loctab_size) return;
    325    vg_assert(new_sz < di->loctab_size);
    326 
    327    new_tab = ML_(dinfo_zalloc)( "di.storage.shrinkLocTab",
    328                                 new_sz * sizeof(DiLoc) );
    329    VG_(memcpy)(new_tab, di->loctab, new_sz * sizeof(DiLoc));
    330 
    331    ML_(dinfo_free)(di->loctab);
    332    di->loctab = new_tab;
    333    di->loctab_size = new_sz;
    334 }
    335 
    336 
    337 /* Top-level place to call to add a source-location mapping entry.
    338 */
    339 void ML_(addLineInfo) ( struct _DebugInfo* di,
    340                         UChar*   filename,
    341                         UChar*   dirname, /* NULL == directory is unknown */
    342                         Addr     this,
    343                         Addr     next,
    344                         Int      lineno,
    345                         Int      entry /* only needed for debug printing */
    346      )
    347 {
    348    static const Bool debug = False;
    349    DiLoc loc;
    350    Int size = next - this;
    351 
    352    /* Ignore zero-sized locs */
    353    if (this == next) return;
    354 
    355    if (debug)
    356       VG_(printf)( "  src %s %s line %d %#lx-%#lx\n",
    357                    dirname ? dirname : (UChar*)"(unknown)",
    358                    filename, lineno, this, next );
    359 
    360    /* Maximum sanity checking.  Some versions of GNU as do a shabby
    361     * job with stabs entries; if anything looks suspicious, revert to
    362     * a size of 1.  This should catch the instruction of interest
    363     * (since if using asm-level debug info, one instruction will
    364     * correspond to one line, unlike with C-level debug info where
    365     * multiple instructions can map to the one line), but avoid
    366     * catching any other instructions bogusly. */
    367    if (this > next) {
    368        if (VG_(clo_verbosity) > 2) {
    369            VG_(message)(Vg_DebugMsg,
    370                         "warning: line info addresses out of order "
    371                         "at entry %d: 0x%lx 0x%lx\n", entry, this, next);
    372        }
    373        size = 1;
    374    }
    375 
    376    if (size > MAX_LOC_SIZE) {
    377        if (0)
    378        VG_(message)(Vg_DebugMsg,
    379                     "warning: line info address range too large "
    380                     "at entry %d: %d\n", entry, size);
    381        size = 1;
    382    }
    383 
    384    /* Rule out ones which are completely outside the r-x mapped area.
    385       See "Comment_Regarding_Text_Range_Checks" elsewhere in this file
    386       for background and rationale. */
    387    vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map);
    388    if (next-1 < di->fsm.rx_map_avma
    389        || this >= di->fsm.rx_map_avma + di->fsm.rx_map_size ) {
    390        if (0)
    391           VG_(message)(Vg_DebugMsg,
    392                        "warning: ignoring line info entry falling "
    393                        "outside current DebugInfo: %#lx %#lx %#lx %#lx\n",
    394                        di->text_avma,
    395                        di->text_avma + di->text_size,
    396                        this, next-1);
    397        return;
    398    }
    399 
    400    vg_assert(lineno >= 0);
    401    if (lineno > MAX_LINENO) {
    402       static Bool complained = False;
    403       if (!complained) {
    404          complained = True;
    405          VG_(message)(Vg_UserMsg,
    406                       "warning: ignoring line info entry with "
    407                       "huge line number (%d)\n", lineno);
    408          VG_(message)(Vg_UserMsg,
    409                       "         Can't handle line numbers "
    410                       "greater than %d, sorry\n", MAX_LINENO);
    411          VG_(message)(Vg_UserMsg,
    412                       "(Nb: this message is only shown once)\n");
    413       }
    414       return;
    415    }
    416 
    417    loc.addr      = this;
    418    loc.size      = (UShort)size;
    419    loc.lineno    = lineno;
    420    loc.filename  = filename;
    421    loc.dirname   = dirname;
    422 
    423    if (0) VG_(message)(Vg_DebugMsg,
    424 		       "addLoc: addr %#lx, size %d, line %d, file %s\n",
    425 		       this,size,lineno,filename);
    426 
    427    addLoc ( di, &loc );
    428 }
    429 
    430 
    431 /* Top-level place to call to add a CFI summary record.  The supplied
    432    DiCfSI is copied. */
    433 void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi_orig )
    434 {
    435    static const Bool debug = False;
    436    UInt    new_sz, i;
    437    DiCfSI* new_tab;
    438    SSizeT  delta;
    439 
    440    /* copy the original, so we can mess with it */
    441    DiCfSI cfsi = *cfsi_orig;
    442 
    443    if (debug) {
    444       VG_(printf)("adding DiCfSI: ");
    445       ML_(ppDiCfSI)(di->cfsi_exprs, &cfsi);
    446    }
    447 
    448    /* sanity */
    449    vg_assert(cfsi.len > 0);
    450    /* If this fails, the implication is you have a single procedure
    451       with more than 5 million bytes of code.  Which is pretty
    452       unlikely.  Either that, or the debuginfo reader is somehow
    453       broken.  5 million is of course arbitrary; but it's big enough
    454       to be bigger than the size of any plausible piece of code that
    455       would fall within a single procedure. */
    456    vg_assert(cfsi.len < 5000000);
    457 
    458    vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map);
    459    /* If we have an empty r-x mapping (is that possible?) then the
    460       DiCfSI can't possibly fall inside it.  In which case skip. */
    461    if (di->fsm.rx_map_size == 0)
    462       return;
    463 
    464    /* Rule out ones which are completely outside the r-x mapped area.
    465       See "Comment_Regarding_Text_Range_Checks" elsewhere in this file
    466       for background and rationale. */
    467    if (cfsi.base + cfsi.len - 1 < di->fsm.rx_map_avma
    468        || cfsi.base >= di->fsm.rx_map_avma + di->fsm.rx_map_size) {
    469       static Int complaints = 10;
    470       if (VG_(clo_trace_cfi) || complaints > 0) {
    471          complaints--;
    472          if (VG_(clo_verbosity) > 1) {
    473             VG_(message)(
    474                Vg_DebugMsg,
    475                "warning: DiCfSI %#lx .. %#lx outside segment %#lx .. %#lx\n",
    476                cfsi.base,
    477                cfsi.base + cfsi.len - 1,
    478                di->text_avma,
    479                di->text_avma + di->text_size - 1
    480             );
    481          }
    482          if (VG_(clo_trace_cfi))
    483             ML_(ppDiCfSI)(di->cfsi_exprs, &cfsi);
    484       }
    485       return;
    486    }
    487 
    488    /* Now we know the range is at least partially inside the r-x
    489       mapped area.  That implies that at least one of the ends of the
    490       range falls inside the area.  If necessary, clip it so it is
    491       completely within the area.  If we don't do this,
    492       check_CFSI_related_invariants() in debuginfo.c (invariant #2)
    493       will fail.  See
    494       "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
    495       priv_storage.h for background. */
    496    if (cfsi.base < di->fsm.rx_map_avma) {
    497       /* Lower end is outside the mapped area.  Hence upper end must
    498          be inside it. */
    499       if (0) VG_(printf)("XXX truncate lower\n");
    500       vg_assert(cfsi.base + cfsi.len - 1 >= di->fsm.rx_map_avma);
    501       delta = (SSizeT)(di->fsm.rx_map_avma - cfsi.base);
    502       vg_assert(delta > 0);
    503       vg_assert(delta < (SSizeT)cfsi.len);
    504       cfsi.base += delta;
    505       cfsi.len -= delta;
    506    }
    507    else
    508    if (cfsi.base + cfsi.len - 1 > di->fsm.rx_map_avma
    509                                   + di->fsm.rx_map_size - 1) {
    510       /* Upper end is outside the mapped area.  Hence lower end must be
    511          inside it. */
    512       if (0) VG_(printf)("XXX truncate upper\n");
    513       vg_assert(cfsi.base <= di->fsm.rx_map_avma + di->fsm.rx_map_size - 1);
    514       delta = (SSizeT)( (cfsi.base + cfsi.len - 1)
    515                         - (di->fsm.rx_map_avma + di->fsm.rx_map_size - 1) );
    516       vg_assert(delta > 0); vg_assert(delta < (SSizeT)cfsi.len);
    517       cfsi.len -= delta;
    518    }
    519 
    520    /* Final checks */
    521 
    522    /* Because: either cfsi was entirely inside the range, in which
    523       case we asserted that len > 0 at the start, OR it fell partially
    524       inside the range, in which case we reduced it by some size
    525       (delta) which is < its original size. */
    526    vg_assert(cfsi.len > 0);
    527 
    528    /* Similar logic applies for the next two assertions. */
    529    vg_assert(cfsi.base >= di->fsm.rx_map_avma);
    530    vg_assert(cfsi.base + cfsi.len - 1
    531              <= di->fsm.rx_map_avma + di->fsm.rx_map_size - 1);
    532 
    533    if (di->cfsi_used == di->cfsi_size) {
    534       new_sz = 2 * di->cfsi_size;
    535       if (new_sz == 0) new_sz = 20;
    536       new_tab = ML_(dinfo_zalloc)( "di.storage.addDiCfSI.1",
    537                                    new_sz * sizeof(DiCfSI) );
    538       if (di->cfsi != NULL) {
    539          for (i = 0; i < di->cfsi_used; i++)
    540             new_tab[i] = di->cfsi[i];
    541          ML_(dinfo_free)(di->cfsi);
    542       }
    543       di->cfsi = new_tab;
    544       di->cfsi_size = new_sz;
    545    }
    546 
    547    di->cfsi[di->cfsi_used] = cfsi;
    548    di->cfsi_used++;
    549    vg_assert(di->cfsi_used <= di->cfsi_size);
    550 }
    551 
    552 
    553 Int ML_(CfiExpr_Undef)( XArray* dst )
    554 {
    555    CfiExpr e;
    556    VG_(memset)( &e, 0, sizeof(e) );
    557    e.tag = Cex_Undef;
    558    return (Int)VG_(addToXA)( dst, &e );
    559 }
    560 Int ML_(CfiExpr_Deref)( XArray* dst, Int ixAddr )
    561 {
    562    CfiExpr e;
    563    VG_(memset)( &e, 0, sizeof(e) );
    564    e.tag = Cex_Deref;
    565    e.Cex.Deref.ixAddr = ixAddr;
    566    return (Int)VG_(addToXA)( dst, &e );
    567 }
    568 Int ML_(CfiExpr_Const)( XArray* dst, UWord con )
    569 {
    570    CfiExpr e;
    571    VG_(memset)( &e, 0, sizeof(e) );
    572    e.tag = Cex_Const;
    573    e.Cex.Const.con = con;
    574    return (Int)VG_(addToXA)( dst, &e );
    575 }
    576 Int ML_(CfiExpr_Binop)( XArray* dst, CfiOp op, Int ixL, Int ixR )
    577 {
    578    CfiExpr e;
    579    VG_(memset)( &e, 0, sizeof(e) );
    580    e.tag = Cex_Binop;
    581    e.Cex.Binop.op  = op;
    582    e.Cex.Binop.ixL = ixL;
    583    e.Cex.Binop.ixR = ixR;
    584    return (Int)VG_(addToXA)( dst, &e );
    585 }
    586 Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg )
    587 {
    588    CfiExpr e;
    589    VG_(memset)( &e, 0, sizeof(e) );
    590    e.tag = Cex_CfiReg;
    591    e.Cex.CfiReg.reg = reg;
    592    return (Int)VG_(addToXA)( dst, &e );
    593 }
    594 Int ML_(CfiExpr_DwReg)( XArray* dst, Int reg )
    595 {
    596    CfiExpr e;
    597    VG_(memset)( &e, 0, sizeof(e) );
    598    e.tag = Cex_DwReg;
    599    e.Cex.DwReg.reg = reg;
    600    return (Int)VG_(addToXA)( dst, &e );
    601 }
    602 
    603 static void ppCfiOp ( CfiOp op )
    604 {
    605    switch (op) {
    606       case Cop_Add: VG_(printf)("+"); break;
    607       case Cop_Sub: VG_(printf)("-"); break;
    608       case Cop_And: VG_(printf)("&"); break;
    609       case Cop_Mul: VG_(printf)("*"); break;
    610       case Cop_Shl: VG_(printf)("<<"); break;
    611       case Cop_Shr: VG_(printf)(">>"); break;
    612       case Cop_Eq: VG_(printf)("=="); break;
    613       case Cop_Ge: VG_(printf)(">="); break;
    614       case Cop_Gt: VG_(printf)(">"); break;
    615       case Cop_Le: VG_(printf)("<="); break;
    616       case Cop_Lt: VG_(printf)("<"); break;
    617       case Cop_Ne: VG_(printf)("!="); break;
    618       default:      vg_assert(0);
    619    }
    620 }
    621 
    622 static void ppCfiReg ( CfiReg reg )
    623 {
    624    switch (reg) {
    625       case Creg_IA_SP:   VG_(printf)("xSP"); break;
    626       case Creg_IA_BP:   VG_(printf)("xBP"); break;
    627       case Creg_IA_IP:   VG_(printf)("xIP"); break;
    628       case Creg_ARM_R13: VG_(printf)("R13"); break;
    629       case Creg_ARM_R12: VG_(printf)("R12"); break;
    630       case Creg_ARM_R15: VG_(printf)("R15"); break;
    631       case Creg_ARM_R14: VG_(printf)("R14"); break;
    632       default: vg_assert(0);
    633    }
    634 }
    635 
    636 void ML_(ppCfiExpr)( XArray* src, Int ix )
    637 {
    638    /* VG_(indexXA) checks for invalid src/ix values, so we can
    639       use it indiscriminately. */
    640    CfiExpr* e = (CfiExpr*) VG_(indexXA)( src, ix );
    641    switch (e->tag) {
    642       case Cex_Undef:
    643          VG_(printf)("Undef");
    644          break;
    645       case Cex_Deref:
    646          VG_(printf)("*(");
    647          ML_(ppCfiExpr)(src, e->Cex.Deref.ixAddr);
    648          VG_(printf)(")");
    649          break;
    650       case Cex_Const:
    651          VG_(printf)("0x%lx", e->Cex.Const.con);
    652          break;
    653       case Cex_Binop:
    654          VG_(printf)("(");
    655          ML_(ppCfiExpr)(src, e->Cex.Binop.ixL);
    656          VG_(printf)(")");
    657          ppCfiOp(e->Cex.Binop.op);
    658          VG_(printf)("(");
    659          ML_(ppCfiExpr)(src, e->Cex.Binop.ixR);
    660          VG_(printf)(")");
    661          break;
    662       case Cex_CfiReg:
    663          ppCfiReg(e->Cex.CfiReg.reg);
    664          break;
    665       case Cex_DwReg:
    666          VG_(printf)("dwr%d", e->Cex.DwReg.reg);
    667          break;
    668       default:
    669          VG_(core_panic)("ML_(ppCfiExpr)");
    670          /*NOTREACHED*/
    671          break;
    672    }
    673 }
    674 
    675 
    676 Word ML_(cmp_for_DiAddrRange_range) ( const void* keyV,
    677                                       const void* elemV ) {
    678    const Addr* key = (const Addr*)keyV;
    679    const DiAddrRange* elem = (const DiAddrRange*)elemV;
    680    if (0)
    681       VG_(printf)("cmp_for_DiAddrRange_range: %#lx vs %#lx\n",
    682                   *key, elem->aMin);
    683    if ((*key) < elem->aMin) return -1;
    684    if ((*key) > elem->aMax) return 1;
    685    return 0;
    686 }
    687 
    688 static
    689 void show_scope ( OSet* /* of DiAddrRange */ scope, HChar* who )
    690 {
    691    DiAddrRange* range;
    692    VG_(printf)("Scope \"%s\" = {\n", who);
    693    VG_(OSetGen_ResetIter)( scope );
    694    while (True) {
    695       range = VG_(OSetGen_Next)( scope );
    696       if (!range) break;
    697       VG_(printf)("   %#lx .. %#lx: %lu vars\n", range->aMin, range->aMax,
    698                   range->vars ? VG_(sizeXA)(range->vars) : 0);
    699    }
    700    VG_(printf)("}\n");
    701 }
    702 
    703 /* Add the variable 'var' to 'scope' for the address range [aMin,aMax]
    704    (inclusive of aMin and aMax).  Split existing ranges as required if
    705    aMin or aMax or both don't match existing range boundaries, and add
    706    'var' to all required ranges.  Take great care to preserve the
    707    invariant that the ranges in 'scope' cover the entire address range
    708    exactly once, with no overlaps and no holes. */
    709 static void add_var_to_arange (
    710                /*MOD*/OSet* /* of DiAddrRange */ scope,
    711                Addr aMin,
    712                Addr aMax,
    713                DiVariable* var
    714             )
    715 {
    716    DiAddrRange *first, *last, *range;
    717    /* These xx variables are for assertion checking only; they don't
    718       contribute anything to the actual work of this function. */
    719    DiAddrRange *xxRangep, *xxFirst, *xxLast;
    720    UWord       xxIters;
    721 
    722    vg_assert(aMin <= aMax);
    723 
    724    if (0) VG_(printf)("add_var_to_arange: %#lx .. %#lx\n", aMin, aMax);
    725    if (0) show_scope( scope, "add_var_to_arange(1)" );
    726 
    727    /* See if the lower end of the range (aMin) falls exactly on an
    728       existing range boundary.  If not, find the range it does fall
    729       into, and split it (copying the variables in the process), so
    730       that aMin does exactly fall on a range boundary. */
    731    first = VG_(OSetGen_Lookup)( scope, &aMin );
    732    /* It must be present, since the presented OSet must cover
    733       the entire address range. */
    734    vg_assert(first);
    735    vg_assert(first->aMin <= first->aMax);
    736    vg_assert(first->aMin <= aMin && aMin <= first->aMax);
    737 
    738    /* Fast track common case, which is that the range specified for
    739       the variable exactly coincides with one already-existing
    740       range. */
    741    if (first->aMin == aMin && first->aMax == aMax) {
    742       vg_assert(first->vars);
    743       VG_(addToXA)( first->vars, var );
    744       return;
    745    }
    746 
    747    /* We have to get into splitting ranges, which is complex
    748       and slow. */
    749    if (first->aMin < aMin) {
    750       DiAddrRange* nyu;
    751       /* Ok.  We'll have to split 'first'. */
    752       /* truncate the upper end of 'first' */
    753       Addr tmp = first->aMax;
    754       first->aMax = aMin-1;
    755       vg_assert(first->aMin <= first->aMax);
    756       /* create a new range */
    757       nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) );
    758       vg_assert(nyu);
    759       nyu->aMin = aMin;
    760       nyu->aMax = tmp;
    761       vg_assert(nyu->aMin <= nyu->aMax);
    762       /* copy vars into it */
    763       vg_assert(first->vars);
    764       nyu->vars = VG_(cloneXA)( "di.storage.avta.1", first->vars );
    765       vg_assert(nyu->vars);
    766       VG_(OSetGen_Insert)( scope, nyu );
    767       first = nyu;
    768    }
    769 
    770    vg_assert(first->aMin == aMin);
    771 
    772    /* Now do exactly the same for the upper end (aMax): if it doesn't
    773       fall on a boundary, cause it to do so by splitting the range it
    774       does currently fall into. */
    775    last = VG_(OSetGen_Lookup)( scope, &aMax );
    776    vg_assert(last->aMin <= last->aMax);
    777    vg_assert(last->aMin <= aMax && aMax <= last->aMax);
    778 
    779    if (aMax < last->aMax) {
    780       DiAddrRange* nyu;
    781       /* We have to split 'last'. */
    782       /* truncate the lower end of 'last' */
    783       Addr tmp = last->aMin;
    784       last->aMin = aMax+1;
    785       vg_assert(last->aMin <= last->aMax);
    786       /* create a new range */
    787       nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) );
    788       vg_assert(nyu);
    789       nyu->aMin = tmp;
    790       nyu->aMax = aMax;
    791       vg_assert(nyu->aMin <= nyu->aMax);
    792       /* copy vars into it */
    793       vg_assert(last->vars);
    794       nyu->vars = VG_(cloneXA)( "di.storage.avta.2", last->vars );
    795       vg_assert(nyu->vars);
    796       VG_(OSetGen_Insert)( scope, nyu );
    797       last = nyu;
    798    }
    799 
    800    vg_assert(aMax == last->aMax);
    801 
    802    xxFirst = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMin);
    803    xxLast  = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMax);
    804    vg_assert(xxFirst);
    805    vg_assert(xxLast);
    806    vg_assert(xxFirst->aMin == aMin);
    807    vg_assert(xxLast->aMax == aMax);
    808    if (xxFirst != xxLast)
    809       vg_assert(xxFirst->aMax < xxLast->aMin);
    810 
    811    /* Great.  Now we merely need to iterate over the segments from
    812       'first' to 'last' inclusive, and add 'var' to the variable set
    813       of each of them. */
    814    if (0) {
    815       static UWord ctr = 0;
    816       ctr++;
    817       VG_(printf)("ctr = %lu\n", ctr);
    818       if (ctr >= 33263) show_scope( scope, "add_var_to_arange(2)" );
    819    }
    820 
    821    xxIters = 0;
    822    range = xxRangep = NULL;
    823    VG_(OSetGen_ResetIterAt)( scope, &aMin );
    824    while (True) {
    825       xxRangep = range;
    826       range    = VG_(OSetGen_Next)( scope );
    827       if (!range) break;
    828       if (range->aMin > aMax) break;
    829       xxIters++;
    830       if (0) VG_(printf)("have range %#lx %#lx\n",
    831                          range->aMin, range->aMax);
    832 
    833       /* Sanity checks */
    834       if (!xxRangep) {
    835          /* This is the first in the range */
    836          vg_assert(range->aMin == aMin);
    837       } else {
    838          vg_assert(xxRangep->aMax + 1 == range->aMin);
    839       }
    840 
    841       vg_assert(range->vars);
    842       VG_(addToXA)( range->vars, var );
    843    }
    844    /* Done.  We should have seen at least one range. */
    845    vg_assert(xxIters >= 1);
    846    if (xxIters == 1) vg_assert(xxFirst == xxLast);
    847    if (xxFirst == xxLast) vg_assert(xxIters == 1);
    848    vg_assert(xxRangep);
    849    vg_assert(xxRangep->aMax == aMax);
    850    vg_assert(xxRangep == xxLast);
    851 }
    852 
    853 
    854 /* Top-level place to call to add a variable description (as extracted
    855    from a DWARF3 .debug_info section. */
    856 void ML_(addVar)( struct _DebugInfo* di,
    857                   Int    level,
    858                   Addr   aMin,
    859                   Addr   aMax,
    860                   UChar* name, /* in di's .strchunks */
    861                   UWord  typeR, /* a cuOff */
    862                   GExpr* gexpr,
    863                   GExpr* fbGX,
    864                   UChar* fileName, /* where decl'd - may be NULL.
    865                                       in di's .strchunks */
    866                   Int    lineNo, /* where decl'd - may be zero */
    867                   Bool   show )
    868 {
    869    OSet* /* of DiAddrRange */ scope;
    870    DiVariable var;
    871    Bool       all;
    872    TyEnt*     ent;
    873    MaybeULong mul;
    874    HChar*     badness;
    875 
    876    tl_assert(di && di->admin_tyents);
    877 
    878    if (0) {
    879       VG_(printf)("  ML_(addVar): level %d  %#lx-%#lx  %s :: ",
    880                   level, aMin, aMax, name );
    881       ML_(pp_TyEnt_C_ishly)( di->admin_tyents, typeR );
    882       VG_(printf)("\n  Var=");
    883       ML_(pp_GX)(gexpr);
    884       VG_(printf)("\n");
    885       if (fbGX) {
    886          VG_(printf)("  FrB=");
    887          ML_(pp_GX)( fbGX );
    888          VG_(printf)("\n");
    889       } else {
    890          VG_(printf)("  FrB=none\n");
    891       }
    892       VG_(printf)("\n");
    893    }
    894 
    895    vg_assert(level >= 0);
    896    vg_assert(aMin <= aMax);
    897    vg_assert(name);
    898    vg_assert(gexpr);
    899 
    900    ent = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, typeR);
    901    tl_assert(ent);
    902    vg_assert(ML_(TyEnt__is_type)(ent));
    903 
    904    /* "Comment_Regarding_Text_Range_Checks" (is referred to elsewhere)
    905       ----------------------------------------------------------------
    906       Ignore any variables whose aMin .. aMax (that is, range of text
    907       addresses for which they actually exist) falls outside the text
    908       segment.  Is this indicative of a bug in the reader?  Maybe.
    909       (LATER): instead of restricting strictly to the .text segment,
    910       be a bit more relaxed, and accept any variable whose text range
    911       falls inside the r-x mapped area.  This is useful because .text
    912       is not always the only instruction-carrying segment: others are:
    913       .init .plt __libc_freeres_fn and .fini.  This implicitly assumes
    914       that those extra sections have the same bias as .text, but that
    915       seems a reasonable assumption to me. */
    916    /* This is assured us by top level steering logic in debuginfo.c,
    917       and it is re-checked at the start of
    918       ML_(read_elf_debug_info). */
    919    vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map);
    920    if (level > 0
    921        && (aMax < di->fsm.rx_map_avma
    922            || aMin >= di->fsm.rx_map_avma + di->fsm.rx_map_size)) {
    923       if (VG_(clo_verbosity) >= 0) {
    924          VG_(message)(Vg_DebugMsg,
    925             "warning: addVar: in range %#lx .. %#lx outside "
    926             "segment %#lx .. %#lx (%s)\n",
    927             aMin, aMax,
    928             di->text_avma, di->text_avma + di->text_size -1,
    929             name
    930          );
    931       }
    932       return;
    933    }
    934 
    935    /* If the type's size is zero (which can mean unknown size), ignore
    936       it.  We will never be able to actually relate a data address to
    937       a data object with zero size, so there's no point in storing
    938       info on it.  On 32-bit platforms, also reject types whose size
    939       is 2^32 bytes or large.  (It's amazing what junk shows up ..) */
    940    mul = ML_(sizeOfType)(di->admin_tyents, typeR);
    941 
    942    badness = NULL;
    943    if (mul.b != True)
    944       badness = "unknown size";
    945    else if (mul.ul == 0)
    946       badness = "zero size   ";
    947    else if (sizeof(void*) == 4 && mul.ul >= (1ULL<<32))
    948       badness = "implausibly large";
    949 
    950    if (badness) {
    951       static Int complaints = 10;
    952       if (VG_(clo_verbosity) >= 2 && complaints > 0) {
    953          VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)\n",
    954                                    badness, name );
    955          complaints--;
    956       }
    957       return;
    958    }
    959 
    960    if (!di->varinfo) {
    961       di->varinfo = VG_(newXA)( ML_(dinfo_zalloc),
    962                                 "di.storage.addVar.1",
    963                                 ML_(dinfo_free),
    964                                 sizeof(OSet*) );
    965    }
    966 
    967    vg_assert(level < 256); /* arbitrary; stay sane */
    968    /* Expand the top level array enough to map this level */
    969    while ( VG_(sizeXA)(di->varinfo) <= level ) {
    970       DiAddrRange* nyu;
    971       scope = VG_(OSetGen_Create)( offsetof(DiAddrRange,aMin),
    972                                    ML_(cmp_for_DiAddrRange_range),
    973                                    ML_(dinfo_zalloc), "di.storage.addVar.2",
    974                                    ML_(dinfo_free) );
    975       vg_assert(scope);
    976       if (0) VG_(printf)("create: scope = %p, adding at %ld\n",
    977                          scope, VG_(sizeXA)(di->varinfo));
    978       VG_(addToXA)( di->varinfo, &scope );
    979       /* Add a single range covering the entire address space.  At
    980          level 0 we require this doesn't get split.  At levels above 0
    981          we require that any additions to it cause it to get split.
    982          All of these invariants get checked both add_var_to_arange
    983          and after reading is complete, in canonicaliseVarInfo. */
    984       nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) );
    985       vg_assert(nyu);
    986       nyu->aMin = (Addr)0;
    987       nyu->aMax = ~(Addr)0;
    988       nyu->vars = VG_(newXA)( ML_(dinfo_zalloc), "di.storage.addVar.3",
    989                               ML_(dinfo_free),
    990                               sizeof(DiVariable) );
    991       vg_assert(nyu->vars);
    992       VG_(OSetGen_Insert)( scope, nyu );
    993    }
    994 
    995    vg_assert( VG_(sizeXA)(di->varinfo) > level );
    996    scope = *(OSet**)VG_(indexXA)( di->varinfo, level );
    997    vg_assert(scope);
    998 
    999    var.name     = name;
   1000    var.typeR    = typeR;
   1001    var.gexpr    = gexpr;
   1002    var.fbGX     = fbGX;
   1003    var.fileName = fileName;
   1004    var.lineNo   = lineNo;
   1005 
   1006    all = aMin == (Addr)0 && aMax == ~(Addr)0;
   1007    vg_assert(level == 0 ? all : !all);
   1008 
   1009    add_var_to_arange( /*MOD*/scope, aMin, aMax, &var );
   1010 }
   1011 
   1012 
   1013 /* This really just checks the constructed data structure, as there is
   1014    no canonicalisation to do. */
   1015 static void canonicaliseVarInfo ( struct _DebugInfo* di )
   1016 {
   1017    Word i, nInThisScope;
   1018 
   1019    if (!di->varinfo)
   1020       return;
   1021 
   1022    for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
   1023 
   1024       DiAddrRange *range, *rangep;
   1025       OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
   1026       if (!scope) continue;
   1027 
   1028       /* Deal with the global-scope case. */
   1029       if (i == 0) {
   1030          Addr zero = 0;
   1031          vg_assert(VG_(OSetGen_Size)( scope ) == 1);
   1032          range = VG_(OSetGen_Lookup)( scope, &zero );
   1033          vg_assert(range);
   1034          vg_assert(range->aMin == (Addr)0);
   1035          vg_assert(range->aMax == ~(Addr)0);
   1036          continue;
   1037       }
   1038 
   1039       /* All the rest of this is for the local-scope case. */
   1040       /* iterate over all entries in 'scope' */
   1041       nInThisScope = 0;
   1042       rangep = NULL;
   1043       VG_(OSetGen_ResetIter)(scope);
   1044       while (True) {
   1045          range = VG_(OSetGen_Next)(scope);
   1046          if (!range) {
   1047            /* We just saw the last one.  There must have been at
   1048               least one entry in the range. */
   1049            vg_assert(rangep);
   1050            vg_assert(rangep->aMax == ~(Addr)0);
   1051            break;
   1052          }
   1053 
   1054          vg_assert(range->aMin <= range->aMax);
   1055          vg_assert(range->vars);
   1056 
   1057          if (!rangep) {
   1058            /* This is the first entry in the range. */
   1059            vg_assert(range->aMin == 0);
   1060          } else {
   1061            vg_assert(rangep->aMax + 1 == range->aMin);
   1062          }
   1063 
   1064          rangep = range;
   1065          nInThisScope++;
   1066       } /* iterating over ranges in a given scope */
   1067 
   1068       /* If there's only one entry in this (local) scope, it must
   1069          cover the entire address space (obviously), but it must not
   1070          contain any vars. */
   1071 
   1072       vg_assert(nInThisScope > 0);
   1073       if (nInThisScope == 1) {
   1074          Addr zero = 0;
   1075          vg_assert(VG_(OSetGen_Size)( scope ) == 1);
   1076          range = VG_(OSetGen_Lookup)( scope, &zero );
   1077          vg_assert(range);
   1078          vg_assert(range->aMin == (Addr)0);
   1079          vg_assert(range->aMax == ~(Addr)0);
   1080          vg_assert(range->vars);
   1081          vg_assert(VG_(sizeXA)(range->vars) == 0);
   1082       }
   1083 
   1084    } /* iterate over scopes */
   1085 }
   1086 
   1087 
   1088 /*------------------------------------------------------------*/
   1089 /*--- Canonicalisers                                       ---*/
   1090 /*------------------------------------------------------------*/
   1091 
   1092 /* Sort the symtab by starting address, and emit warnings if any
   1093    symbols have overlapping address ranges.  We use that old chestnut,
   1094    shellsort.  Mash the table around so as to establish the property
   1095    that addresses are in order and the ranges to not overlap.  This
   1096    facilitates using binary search to map addresses to symbols when we
   1097    come to query the table.
   1098 */
   1099 static Int compare_DiSym ( void* va, void* vb )
   1100 {
   1101    DiSym* a = (DiSym*)va;
   1102    DiSym* b = (DiSym*)vb;
   1103    if (a->addr < b->addr) return -1;
   1104    if (a->addr > b->addr) return  1;
   1105    return 0;
   1106 }
   1107 
   1108 
   1109 /* An address is associated with more than one name.  Which do we
   1110    prefer as the "display" name (that we show the user in stack
   1111    traces)?  In order:
   1112 
   1113    - Prefer "PMPI_<foo>" over "MPI_<foo>".
   1114 
   1115    - Else, prefer a non-empty name over an empty one.
   1116 
   1117    - Else, prefer a non-whitespace name over an all-whitespace name.
   1118 
   1119    - Else, prefer the shorter symbol name.  If the symbol contains a
   1120      version symbol ('@' on Linux, other platforms may differ), which means it
   1121      is versioned, then the length up to the version symbol is used for length
   1122      comparison purposes (so "foo (at) GLIBC_2.4.2" is considered shorter than
   1123      "foobar").
   1124 
   1125    - Else, if two symbols have the same length, prefer a versioned symbol over
   1126      a non-versioned symbol.
   1127 
   1128    - Else, use alphabetical ordering.
   1129 
   1130    - Otherwise, they must be the same;  use the name with the lower address.
   1131 
   1132    Very occasionally this goes wrong (eg. 'memcmp' and 'bcmp' are
   1133    aliases in glibc, we choose the 'bcmp' symbol because it's shorter,
   1134    so we can misdescribe memcmp() as bcmp()).  This is hard to avoid.
   1135    It's mentioned in the FAQ file.
   1136 
   1137    Returned value is True if a_name is preferred, False if b_name is
   1138    preferred.
   1139  */
   1140 static
   1141 Bool preferName ( struct _DebugInfo* di,
   1142                   UChar* a_name, UChar* b_name,
   1143                   Addr sym_avma/*exposition only*/ )
   1144 {
   1145    Word cmp;
   1146    Word vlena, vlenb;		/* length without version */
   1147    const UChar *vpa, *vpb;
   1148 
   1149    Bool preferA = False;
   1150    Bool preferB = False;
   1151 
   1152    vg_assert(a_name);
   1153    vg_assert(b_name);
   1154    vg_assert(a_name != b_name);
   1155 
   1156    vlena = VG_(strlen)(a_name);
   1157    vlenb = VG_(strlen)(b_name);
   1158 
   1159 #  if defined(VGO_linux)
   1160 #    define VERSION_CHAR '@'
   1161 #  elif defined(VGO_darwin)
   1162 #    define VERSION_CHAR '$'
   1163 #  else
   1164 #    error Unknown OS
   1165 #  endif
   1166 
   1167    vpa = VG_(strchr)(a_name, VERSION_CHAR);
   1168    vpb = VG_(strchr)(b_name, VERSION_CHAR);
   1169 
   1170 #  undef VERSION_CHAR
   1171 
   1172    if (vpa)
   1173       vlena = vpa - a_name;
   1174    if (vpb)
   1175       vlenb = vpb - b_name;
   1176 
   1177    /* MPI hack: prefer PMPI_Foo over MPI_Foo */
   1178    if (0==VG_(strncmp)(a_name, "MPI_", 4)
   1179        && 0==VG_(strncmp)(b_name, "PMPI_", 5)
   1180        && 0==VG_(strcmp)(a_name, 1+b_name)) {
   1181       preferB = True; goto out;
   1182    }
   1183    if (0==VG_(strncmp)(b_name, "MPI_", 4)
   1184        && 0==VG_(strncmp)(a_name, "PMPI_", 5)
   1185        && 0==VG_(strcmp)(b_name, 1+a_name)) {
   1186       preferA = True; goto out;
   1187    }
   1188 
   1189    /* Prefer non-empty name. */
   1190    if (vlena  &&  !vlenb) {
   1191       preferA = True; goto out;
   1192    }
   1193    if (vlenb  &&  !vlena) {
   1194       preferB = True; goto out;
   1195    }
   1196 
   1197    /* Prefer non-whitespace name. */
   1198    {
   1199       Bool blankA = True;
   1200       Bool blankB = True;
   1201       Char *s;
   1202       s = a_name;
   1203       while (*s) {
   1204          if (!VG_(isspace)(*s++)) {
   1205             blankA = False;
   1206             break;
   1207          }
   1208       }
   1209       s = b_name;
   1210       while (*s) {
   1211          if (!VG_(isspace)(*s++)) {
   1212             blankB = False;
   1213             break;
   1214          }
   1215       }
   1216 
   1217       if (!blankA  &&  blankB) {
   1218          preferA = True; goto out;
   1219       }
   1220       if (!blankB  &&  blankA) {
   1221          preferB = True; goto out;
   1222       }
   1223    }
   1224 
   1225    /* Select the shortest unversioned name */
   1226    if (vlena < vlenb) {
   1227       preferA = True; goto out;
   1228    }
   1229    if (vlenb < vlena) {
   1230       preferB = True; goto out;
   1231    }
   1232 
   1233    /* Equal lengths; select the versioned name */
   1234    if (vpa && !vpb) {
   1235       preferA = True; goto out;
   1236    }
   1237    if (vpb && !vpa) {
   1238       preferB = True; goto out;
   1239    }
   1240 
   1241    /* Either both versioned or neither is versioned; select them
   1242       alphabetically */
   1243    cmp = VG_(strcmp)(a_name, b_name);
   1244    if (cmp < 0) {
   1245       preferA = True; goto out;
   1246    }
   1247    if (cmp > 0) {
   1248       preferB = True; goto out;
   1249    }
   1250 
   1251    /* If we get here, they are the same name. */
   1252 
   1253    /* In this case we could choose either (arbitrarily), but might as
   1254       well choose the one with the lowest DiSym* address, so as to try
   1255       and make the comparison mechanism more stable (a la sorting
   1256       parlance).  Also, skip the diagnostic printing in this case. */
   1257    return a_name <= b_name  ? True  : False;
   1258 
   1259    /*NOTREACHED*/
   1260    vg_assert(0);
   1261   out:
   1262    if (preferA && !preferB) {
   1263       TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n",
   1264                    sym_avma, a_name, b_name );
   1265       return True;
   1266    }
   1267    if (preferB && !preferA) {
   1268       TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n",
   1269                    sym_avma, b_name, a_name );
   1270       return False;
   1271    }
   1272    /*NOTREACHED*/
   1273    vg_assert(0);
   1274 }
   1275 
   1276 
   1277 /* Add the names in FROM to the names in TO. */
   1278 static
   1279 void add_DiSym_names_to_from ( DebugInfo* di, DiSym* to, DiSym* from )
   1280 {
   1281    vg_assert(to->pri_name);
   1282    vg_assert(from->pri_name);
   1283    /* Figure out how many names there will be in the new combined
   1284       secondary vector. */
   1285    UChar** to_sec   = to->sec_names;
   1286    UChar** from_sec = from->sec_names;
   1287    Word n_new_sec = 1;
   1288    if (from_sec) {
   1289       while (*from_sec) {
   1290          n_new_sec++;
   1291          from_sec++;
   1292       }
   1293    }
   1294    if (to_sec) {
   1295       while (*to_sec) {
   1296          n_new_sec++;
   1297          to_sec++;
   1298       }
   1299    }
   1300    if (0)
   1301       TRACE_SYMTAB("merge: -> %ld\n", n_new_sec);
   1302    /* Create the new sec and copy stuff into it, putting the new
   1303       entries at the end. */
   1304    UChar** new_sec = ML_(dinfo_zalloc)( "di.storage.aDntf.1",
   1305                                         (n_new_sec+1) * sizeof(UChar*) );
   1306    from_sec = from->sec_names;
   1307    to_sec   = to->sec_names;
   1308    Word i = 0;
   1309    if (to_sec) {
   1310       while (*to_sec) {
   1311          new_sec[i++] = *to_sec;
   1312          to_sec++;
   1313       }
   1314    }
   1315    new_sec[i++] = from->pri_name;
   1316    if (from_sec) {
   1317       while (*from_sec) {
   1318          new_sec[i++] = *from_sec;
   1319          from_sec++;
   1320       }
   1321    }
   1322    vg_assert(i == n_new_sec);
   1323    vg_assert(new_sec[i] == NULL);
   1324    /* If we're replacing an existing secondary vector, free it. */
   1325    if (to->sec_names) {
   1326       ML_(dinfo_free)(to->sec_names);
   1327    }
   1328    to->sec_names = new_sec;
   1329 }
   1330 
   1331 
   1332 static void canonicaliseSymtab ( struct _DebugInfo* di )
   1333 {
   1334    Word  i, j, n_truncated;
   1335    Addr  sta1, sta2, end1, end2, toc1, toc2;
   1336    UChar *pri1, *pri2, **sec1, **sec2;
   1337    Bool  ist1, ist2, isf1, isf2;
   1338 
   1339 #  define SWAP(ty,aa,bb) \
   1340       do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0)
   1341 
   1342    if (di->symtab_used == 0)
   1343       return;
   1344 
   1345    /* Check initial invariants */
   1346    for (i = 0; i < di->symtab_used; i++) {
   1347       DiSym* sym = &di->symtab[i];
   1348       vg_assert(sym->pri_name);
   1349       vg_assert(!sym->sec_names);
   1350    }
   1351 
   1352    /* Sort by address. */
   1353    VG_(ssort)(di->symtab, di->symtab_used,
   1354                           sizeof(*di->symtab), compare_DiSym);
   1355 
   1356   cleanup_more:
   1357 
   1358    /* If two symbols have identical address ranges, and agree on
   1359       .isText and .isIFunc, merge them into a single entry, but
   1360       preserve both names, so we end up knowing all the names for that
   1361       particular address range. */
   1362    while (1) {
   1363       Word r, w, n_merged;
   1364       n_merged = 0;
   1365       w = 0;
   1366       /* A pass merging entries together */
   1367       for (r = 1; r < di->symtab_used; r++) {
   1368          vg_assert(w < r);
   1369          if (   di->symtab[w].addr      == di->symtab[r].addr
   1370              && di->symtab[w].size      == di->symtab[r].size
   1371              && !!di->symtab[w].isText  == !!di->symtab[r].isText
   1372              && !!di->symtab[w].isIFunc == !!di->symtab[r].isIFunc) {
   1373             /* merge the two into one */
   1374             n_merged++;
   1375             add_DiSym_names_to_from(di, &di->symtab[w], &di->symtab[r]);
   1376             /* and use ::pri_names to indicate this slot is no longer in use */
   1377             di->symtab[r].pri_name = NULL;
   1378             if (di->symtab[r].sec_names) {
   1379                ML_(dinfo_free)(di->symtab[r].sec_names);
   1380                di->symtab[r].sec_names = NULL;
   1381             }
   1382             /* Completely zap the entry -- paranoia to make it more
   1383                likely we'll notice if we inadvertantly use it
   1384                again. */
   1385             VG_(memset)(&di->symtab[r], 0, sizeof(DiSym));
   1386          } else {
   1387             w = r;
   1388          }
   1389       }
   1390       TRACE_SYMTAB( "canonicaliseSymtab: %ld symbols merged\n", n_merged);
   1391       if (n_merged == 0)
   1392          break;
   1393       /* Now a pass to squeeze out any unused ones */
   1394       w = 0;
   1395       for (r = 0; r < di->symtab_used; r++) {
   1396          vg_assert(w <= r);
   1397          if (di->symtab[r].pri_name == NULL)
   1398             continue;
   1399          if (w < r) {
   1400             di->symtab[w] = di->symtab[r];
   1401          }
   1402          w++;
   1403       }
   1404       vg_assert(w + n_merged == di->symtab_used);
   1405       di->symtab_used = w;
   1406    }
   1407 
   1408    /* Detect and "fix" overlapping address ranges. */
   1409    n_truncated = 0;
   1410 
   1411    for (i = 0; i < ((Word)di->symtab_used) -1; i++) {
   1412 
   1413       vg_assert(di->symtab[i].addr <= di->symtab[i+1].addr);
   1414 
   1415       /* Check for common (no overlap) case. */
   1416       if (di->symtab[i].addr + di->symtab[i].size
   1417           <= di->symtab[i+1].addr)
   1418          continue;
   1419 
   1420       /* There's an overlap.  Truncate one or the other. */
   1421       if (di->trace_symtab) {
   1422          VG_(printf)("overlapping address ranges in symbol table\n\t");
   1423          ML_(ppSym)( i, &di->symtab[i] );
   1424          VG_(printf)("\t");
   1425          ML_(ppSym)( i+1, &di->symtab[i+1] );
   1426          VG_(printf)("\n");
   1427       }
   1428 
   1429       /* Truncate one or the other. */
   1430       sta1 = di->symtab[i].addr;
   1431       end1 = sta1 + di->symtab[i].size - 1;
   1432       toc1 = di->symtab[i].tocptr;
   1433       pri1 = di->symtab[i].pri_name;
   1434       sec1 = di->symtab[i].sec_names;
   1435       ist1 = di->symtab[i].isText;
   1436       isf1 = di->symtab[i].isIFunc;
   1437 
   1438       sta2 = di->symtab[i+1].addr;
   1439       end2 = sta2 + di->symtab[i+1].size - 1;
   1440       toc2 = di->symtab[i+1].tocptr;
   1441       pri2 = di->symtab[i+1].pri_name;
   1442       sec2 = di->symtab[i+1].sec_names;
   1443       ist2 = di->symtab[i+1].isText;
   1444       isf2 = di->symtab[i+1].isIFunc;
   1445 
   1446       if (sta1 < sta2) {
   1447          end1 = sta2 - 1;
   1448       } else {
   1449          vg_assert(sta1 == sta2);
   1450          if (end1 > end2) {
   1451             sta1 = end2 + 1;
   1452             SWAP(Addr,sta1,sta2); SWAP(Addr,end1,end2); SWAP(Addr,toc1,toc2);
   1453             SWAP(UChar*,pri1,pri2); SWAP(UChar**,sec1,sec2);
   1454             SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2);
   1455          } else
   1456          if (end1 < end2) {
   1457             sta2 = end1 + 1;
   1458          } else {
   1459 	   /* end1 == end2.  Identical addr ranges.  We'll eventually wind
   1460               up back at cleanup_more, which will take care of it. */
   1461 	 }
   1462       }
   1463       di->symtab[i].addr      = sta1;
   1464       di->symtab[i].size      = end1 - sta1 + 1;
   1465       di->symtab[i].tocptr    = toc1;
   1466       di->symtab[i].pri_name  = pri1;
   1467       di->symtab[i].sec_names = sec1;
   1468       di->symtab[i].isText    = ist1;
   1469       di->symtab[i].isIFunc   = isf1;
   1470 
   1471       di->symtab[i+1].addr      = sta2;
   1472       di->symtab[i+1].size      = end2 - sta2 + 1;
   1473       di->symtab[i+1].tocptr    = toc2;
   1474       di->symtab[i+1].pri_name  = pri2;
   1475       di->symtab[i+1].sec_names = sec2;
   1476       di->symtab[i+1].isText    = ist2;
   1477       di->symtab[i+1].isIFunc   = isf2;
   1478 
   1479       vg_assert(sta1 <= sta2);
   1480       vg_assert(di->symtab[i].size > 0);
   1481       vg_assert(di->symtab[i+1].size > 0);
   1482       /* It may be that the i+1 entry now needs to be moved further
   1483          along to maintain the address order requirement. */
   1484       j = i+1;
   1485       while (j < ((Word)di->symtab_used)-1
   1486              && di->symtab[j].addr > di->symtab[j+1].addr) {
   1487          SWAP(DiSym,di->symtab[j],di->symtab[j+1]);
   1488          j++;
   1489       }
   1490       n_truncated++;
   1491    }
   1492 
   1493    if (n_truncated > 0) goto cleanup_more;
   1494 
   1495    /* Ensure relevant postconditions hold. */
   1496    for (i = 0; i < ((Word)di->symtab_used)-1; i++) {
   1497       /* No zero-sized symbols. */
   1498       vg_assert(di->symtab[i].size > 0);
   1499       /* In order. */
   1500       vg_assert(di->symtab[i].addr < di->symtab[i+1].addr);
   1501       /* No overlaps. */
   1502       vg_assert(di->symtab[i].addr + di->symtab[i].size - 1
   1503                 < di->symtab[i+1].addr);
   1504       /* Names are sane(ish) */
   1505       vg_assert(di->symtab[i].pri_name);
   1506       if (di->symtab[i].sec_names) {
   1507          vg_assert(di->symtab[i].sec_names[0]);
   1508       }
   1509    }
   1510 
   1511    /* For each symbol that has more than one name, use preferName to
   1512       select the primary name.  This is a complete kludge in that
   1513       doing it properly requires making a total ordering on the
   1514       candidate names, whilst what we have to work with is an ad-hoc
   1515       binary relation (preferName) that certainly doesn't have the
   1516       relevant transitivity etc properties that are needed to induce a
   1517       legitimate total order.  Doesn't matter though if it doesn't
   1518       always work right since this is only used to generate names to
   1519       show the user. */
   1520    for (i = 0; i < ((Word)di->symtab_used)-1; i++) {
   1521       DiSym*  sym = &di->symtab[i];
   1522       UChar** sec = sym->sec_names;
   1523       if (!sec)
   1524          continue;
   1525       /* Slow but simple.  Copy all the cands into a temp array,
   1526          choose the primary name, and copy them all back again. */
   1527       Word n_tmp = 1;
   1528       while (*sec) { n_tmp++; sec++; }
   1529       j = 0;
   1530       UChar** tmp = ML_(dinfo_zalloc)( "di.storage.cS.1",
   1531                                        (n_tmp+1) * sizeof(UChar*) );
   1532       tmp[j++] = sym->pri_name;
   1533       sec = sym->sec_names;
   1534       while (*sec) { tmp[j++] = *sec; sec++; }
   1535       vg_assert(j == n_tmp);
   1536       vg_assert(tmp[n_tmp] == NULL); /* because of zalloc */
   1537       /* Choose the most favoured. */
   1538       Word best = 0;
   1539       for (j = 1; j < n_tmp; j++) {
   1540          if (preferName(di, tmp[best], tmp[j], di->symtab[i].addr)) {
   1541             /* best is unchanged */
   1542          } else {
   1543             best = j;
   1544          }
   1545       }
   1546       vg_assert(best >= 0 && best < n_tmp);
   1547       /* Copy back */
   1548       sym->pri_name = tmp[best];
   1549       UChar** cursor = sym->sec_names;
   1550       for (j = 0; j < n_tmp; j++) {
   1551          if (j == best)
   1552             continue;
   1553          *cursor = tmp[j];
   1554          cursor++;
   1555       }
   1556       vg_assert(*cursor == NULL);
   1557       ML_(dinfo_free)( tmp );
   1558    }
   1559 
   1560 #  undef SWAP
   1561 }
   1562 
   1563 
   1564 /* Sort the location table by starting address.  Mash the table around
   1565    so as to establish the property that addresses are in order and the
   1566    ranges do not overlap.  This facilitates using binary search to map
   1567    addresses to locations when we come to query the table.
   1568 */
   1569 static Int compare_DiLoc ( void* va, void* vb )
   1570 {
   1571    DiLoc* a = (DiLoc*)va;
   1572    DiLoc* b = (DiLoc*)vb;
   1573    if (a->addr < b->addr) return -1;
   1574    if (a->addr > b->addr) return  1;
   1575    return 0;
   1576 }
   1577 
   1578 static void canonicaliseLoctab ( struct _DebugInfo* di )
   1579 {
   1580    Word i, j;
   1581 
   1582 #  define SWAP(ty,aa,bb) \
   1583       do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0);
   1584 
   1585    if (di->loctab_used == 0)
   1586       return;
   1587 
   1588    /* Sort by start address. */
   1589    VG_(ssort)(di->loctab, di->loctab_used,
   1590                           sizeof(*di->loctab), compare_DiLoc);
   1591 
   1592    /* If two adjacent entries overlap, truncate the first. */
   1593    for (i = 0; i < ((Word)di->loctab_used)-1; i++) {
   1594       vg_assert(di->loctab[i].size < 10000);
   1595       if (di->loctab[i].addr + di->loctab[i].size > di->loctab[i+1].addr) {
   1596          /* Do this in signed int32 because the actual .size fields
   1597             are only 12 bits. */
   1598          Int new_size = di->loctab[i+1].addr - di->loctab[i].addr;
   1599          if (new_size < 0) {
   1600             di->loctab[i].size = 0;
   1601          } else
   1602          if (new_size > MAX_LOC_SIZE) {
   1603            di->loctab[i].size = MAX_LOC_SIZE;
   1604          } else {
   1605            di->loctab[i].size = (UShort)new_size;
   1606          }
   1607       }
   1608    }
   1609 
   1610    /* Zap any zero-sized entries resulting from the truncation
   1611       process. */
   1612    j = 0;
   1613    for (i = 0; i < (Word)di->loctab_used; i++) {
   1614       if (di->loctab[i].size > 0) {
   1615          if (j != i)
   1616             di->loctab[j] = di->loctab[i];
   1617          j++;
   1618       }
   1619    }
   1620    di->loctab_used = j;
   1621 
   1622    /* Ensure relevant postconditions hold. */
   1623    for (i = 0; i < ((Word)di->loctab_used)-1; i++) {
   1624       /*
   1625       VG_(printf)("%d   (%d) %d 0x%x\n",
   1626                    i, di->loctab[i+1].confident,
   1627                    di->loctab[i+1].size, di->loctab[i+1].addr );
   1628       */
   1629       /* No zero-sized symbols. */
   1630       vg_assert(di->loctab[i].size > 0);
   1631       /* In order. */
   1632       vg_assert(di->loctab[i].addr < di->loctab[i+1].addr);
   1633       /* No overlaps. */
   1634       vg_assert(di->loctab[i].addr + di->loctab[i].size - 1
   1635                 < di->loctab[i+1].addr);
   1636    }
   1637 #  undef SWAP
   1638 
   1639    /* Free up unused space at the end of the table. */
   1640    shrinkLocTab(di);
   1641 }
   1642 
   1643 
   1644 /* Sort the call-frame-info table by starting address.  Mash the table
   1645    around so as to establish the property that addresses are in order
   1646    and the ranges do not overlap.  This facilitates using binary
   1647    search to map addresses to locations when we come to query the
   1648    table.
   1649 
   1650    Also, set cfisi_minaddr and cfisi_maxaddr to be the min and max of
   1651    any of the address ranges contained in cfisi[0 .. cfisi_used-1], so
   1652    as to facilitate rapidly skipping this SegInfo when looking for an
   1653    address which falls outside that range.
   1654 */
   1655 static Int compare_DiCfSI ( void* va, void* vb )
   1656 {
   1657    DiCfSI* a = (DiCfSI*)va;
   1658    DiCfSI* b = (DiCfSI*)vb;
   1659    if (a->base < b->base) return -1;
   1660    if (a->base > b->base) return  1;
   1661    return 0;
   1662 }
   1663 
   1664 void ML_(canonicaliseCFI) ( struct _DebugInfo* di )
   1665 {
   1666    Word  i, j;
   1667    const Addr minAvma = 0;
   1668    const Addr maxAvma = ~minAvma;
   1669 
   1670    /* Note: take care in here.  di->cfsi can be NULL, in which
   1671       case _used and _size fields will be zero. */
   1672    if (di->cfsi == NULL) {
   1673       vg_assert(di->cfsi_used == 0);
   1674       vg_assert(di->cfsi_size == 0);
   1675    }
   1676 
   1677    /* Set cfsi_minavma and cfsi_maxavma to summarise the entire
   1678       address range contained in cfsi[0 .. cfsi_used-1]. */
   1679    di->cfsi_minavma = maxAvma;
   1680    di->cfsi_maxavma = minAvma;
   1681    for (i = 0; i < (Word)di->cfsi_used; i++) {
   1682       Addr here_min = di->cfsi[i].base;
   1683       Addr here_max = di->cfsi[i].base + di->cfsi[i].len - 1;
   1684       if (here_min < di->cfsi_minavma)
   1685          di->cfsi_minavma = here_min;
   1686       if (here_max > di->cfsi_maxavma)
   1687          di->cfsi_maxavma = here_max;
   1688    }
   1689 
   1690    if (di->trace_cfi)
   1691       VG_(printf)("canonicaliseCfiSI: %ld entries, %#lx .. %#lx\n",
   1692                   di->cfsi_used,
   1693 	          di->cfsi_minavma, di->cfsi_maxavma);
   1694 
   1695    /* Sort the cfsi array by base address. */
   1696    VG_(ssort)(di->cfsi, di->cfsi_used, sizeof(*di->cfsi), compare_DiCfSI);
   1697 
   1698    /* If two adjacent entries overlap, truncate the first. */
   1699    for (i = 0; i < (Word)di->cfsi_used-1; i++) {
   1700       if (di->cfsi[i].base + di->cfsi[i].len > di->cfsi[i+1].base) {
   1701          Word new_len = di->cfsi[i+1].base - di->cfsi[i].base;
   1702          /* how could it be otherwise?  The entries are sorted by the
   1703             .base field. */
   1704          vg_assert(new_len >= 0);
   1705 	 vg_assert(new_len <= di->cfsi[i].len);
   1706          di->cfsi[i].len = new_len;
   1707       }
   1708    }
   1709 
   1710    /* Zap any zero-sized entries resulting from the truncation
   1711       process. */
   1712    j = 0;
   1713    for (i = 0; i < (Word)di->cfsi_used; i++) {
   1714       if (di->cfsi[i].len > 0) {
   1715          if (j != i)
   1716             di->cfsi[j] = di->cfsi[i];
   1717          j++;
   1718       }
   1719    }
   1720    /* VG_(printf)("XXXXXXXXXXXXX %d %d\n", di->cfsi_used, j); */
   1721    di->cfsi_used = j;
   1722 
   1723    /* Ensure relevant postconditions hold. */
   1724    for (i = 0; i < (Word)di->cfsi_used; i++) {
   1725       /* No zero-length ranges. */
   1726       vg_assert(di->cfsi[i].len > 0);
   1727       /* Makes sense w.r.t. summary address range */
   1728       vg_assert(di->cfsi[i].base >= di->cfsi_minavma);
   1729       vg_assert(di->cfsi[i].base + di->cfsi[i].len - 1
   1730                 <= di->cfsi_maxavma);
   1731 
   1732       if (i < di->cfsi_used - 1) {
   1733          /*
   1734          if (!(di->cfsi[i].base < di->cfsi[i+1].base)) {
   1735             VG_(printf)("\nOOO cfsis:\n");
   1736             ML_(ppCfiSI)(&di->cfsi[i]);
   1737             ML_(ppCfiSI)(&di->cfsi[i+1]);
   1738          }
   1739          */
   1740          /* In order. */
   1741          vg_assert(di->cfsi[i].base < di->cfsi[i+1].base);
   1742          /* No overlaps. */
   1743          vg_assert(di->cfsi[i].base + di->cfsi[i].len - 1
   1744                    < di->cfsi[i+1].base);
   1745       }
   1746    }
   1747 
   1748 }
   1749 
   1750 
   1751 /* Canonicalise the tables held by 'di', in preparation for use.  Call
   1752    this after finishing adding entries to these tables. */
   1753 void ML_(canonicaliseTables) ( struct _DebugInfo* di )
   1754 {
   1755    canonicaliseSymtab ( di );
   1756    canonicaliseLoctab ( di );
   1757    ML_(canonicaliseCFI) ( di );
   1758    canonicaliseVarInfo ( di );
   1759 }
   1760 
   1761 
   1762 /*------------------------------------------------------------*/
   1763 /*--- Searching the tables                                 ---*/
   1764 /*------------------------------------------------------------*/
   1765 
   1766 /* Find a symbol-table index containing the specified pointer, or -1
   1767    if not found.  Binary search.  */
   1768 
   1769 Word ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr,
   1770                               Bool match_anywhere_in_sym,
   1771                               Bool findText )
   1772 {
   1773    Addr a_mid_lo, a_mid_hi;
   1774    Word mid, size,
   1775         lo = 0,
   1776         hi = di->symtab_used-1;
   1777    while (True) {
   1778       /* current unsearched space is from lo to hi, inclusive. */
   1779       if (lo > hi) return -1; /* not found */
   1780       mid      = (lo + hi) / 2;
   1781       a_mid_lo = di->symtab[mid].addr;
   1782       size = ( match_anywhere_in_sym
   1783              ? di->symtab[mid].size
   1784              : 1);
   1785       a_mid_hi = ((Addr)di->symtab[mid].addr) + size - 1;
   1786 
   1787       if (ptr < a_mid_lo) { hi = mid-1; continue; }
   1788       if (ptr > a_mid_hi) { lo = mid+1; continue; }
   1789       vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
   1790       /* Found a symbol with the correct address range.  But is it
   1791          of the right kind (text vs data) ? */
   1792       if (  findText   &&   di->symtab[mid].isText  ) return mid;
   1793       if ( (!findText) && (!di->symtab[mid].isText) ) return mid;
   1794       return -1;
   1795    }
   1796 }
   1797 
   1798 
   1799 /* Find a location-table index containing the specified pointer, or -1
   1800    if not found.  Binary search.  */
   1801 
   1802 Word ML_(search_one_loctab) ( struct _DebugInfo* di, Addr ptr )
   1803 {
   1804    Addr a_mid_lo, a_mid_hi;
   1805    Word mid,
   1806         lo = 0,
   1807         hi = di->loctab_used-1;
   1808    while (True) {
   1809       /* current unsearched space is from lo to hi, inclusive. */
   1810       if (lo > hi) return -1; /* not found */
   1811       mid      = (lo + hi) / 2;
   1812       a_mid_lo = di->loctab[mid].addr;
   1813       a_mid_hi = ((Addr)di->loctab[mid].addr) + di->loctab[mid].size - 1;
   1814 
   1815       if (ptr < a_mid_lo) { hi = mid-1; continue; }
   1816       if (ptr > a_mid_hi) { lo = mid+1; continue; }
   1817       vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
   1818       return mid;
   1819    }
   1820 }
   1821 
   1822 
   1823 /* Find a CFI-table index containing the specified pointer, or -1
   1824    if not found.  Binary search.  */
   1825 
   1826 Word ML_(search_one_cfitab) ( struct _DebugInfo* di, Addr ptr )
   1827 {
   1828    Addr a_mid_lo, a_mid_hi;
   1829    Word mid, size,
   1830         lo = 0,
   1831         hi = di->cfsi_used-1;
   1832    while (True) {
   1833       /* current unsearched space is from lo to hi, inclusive. */
   1834       if (lo > hi) return -1; /* not found */
   1835       mid      = (lo + hi) / 2;
   1836       a_mid_lo = di->cfsi[mid].base;
   1837       size     = di->cfsi[mid].len;
   1838       a_mid_hi = a_mid_lo + size - 1;
   1839       vg_assert(a_mid_hi >= a_mid_lo);
   1840       if (ptr < a_mid_lo) { hi = mid-1; continue; }
   1841       if (ptr > a_mid_hi) { lo = mid+1; continue; }
   1842       vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
   1843       return mid;
   1844    }
   1845 }
   1846 
   1847 
   1848 /* Find a FPO-table index containing the specified pointer, or -1
   1849    if not found.  Binary search.  */
   1850 
   1851 Word ML_(search_one_fpotab) ( struct _DebugInfo* di, Addr ptr )
   1852 {
   1853    Addr const addr = ptr - di->fsm.rx_map_avma;
   1854    Addr a_mid_lo, a_mid_hi;
   1855    Word mid, size,
   1856         lo = 0,
   1857         hi = di->fpo_size-1;
   1858    while (True) {
   1859       /* current unsearched space is from lo to hi, inclusive. */
   1860       if (lo > hi) return -1; /* not found */
   1861       mid      = (lo + hi) / 2;
   1862       a_mid_lo = di->fpo[mid].ulOffStart;
   1863       size     = di->fpo[mid].cbProcSize;
   1864       a_mid_hi = a_mid_lo + size - 1;
   1865       vg_assert(a_mid_hi >= a_mid_lo);
   1866       if (addr < a_mid_lo) { hi = mid-1; continue; }
   1867       if (addr > a_mid_hi) { lo = mid+1; continue; }
   1868       vg_assert(addr >= a_mid_lo && addr <= a_mid_hi);
   1869       return mid;
   1870    }
   1871 }
   1872 
   1873 /*--------------------------------------------------------------------*/
   1874 /*--- end                                                          ---*/
   1875 /*--------------------------------------------------------------------*/
   1876