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-2015 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 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_debuglog.h"
     44 #include "pub_core_libcassert.h"
     45 #include "pub_core_libcbase.h"
     46 #include "pub_core_libcprint.h"
     47 #include "pub_core_xarray.h"
     48 #include "pub_core_oset.h"
     49 #include "pub_core_deduppoolalloc.h"
     50 
     51 #include "priv_misc.h"         /* dinfo_zalloc/free/strdup */
     52 #include "priv_image.h"
     53 #include "priv_d3basics.h"     /* ML_(pp_GX) */
     54 #include "priv_tytypes.h"
     55 #include "priv_storage.h"      /* self */
     56 
     57 
     58 /*------------------------------------------------------------*/
     59 /*--- Misc (printing, errors)                              ---*/
     60 /*------------------------------------------------------------*/
     61 
     62 /* Show a non-fatal debug info reading error.  Use VG_(core_panic) for
     63    fatal errors.  'serious' errors are shown regardless of the
     64    verbosity setting. */
     65 void ML_(symerr) ( const DebugInfo* di, Bool serious, const HChar* msg )
     66 {
     67    /* XML mode hides everything :-( */
     68    if (VG_(clo_xml))
     69       return;
     70 
     71    if (serious) {
     72 
     73       VG_(message)(Vg_DebugMsg, "WARNING: Serious error when "
     74                                 "reading debug info\n");
     75       if (True || VG_(clo_verbosity) < 2) {
     76          /* Need to show what the file name is, at verbosity levels 2
     77             or below, since that won't already have been shown */
     78          VG_(message)(Vg_DebugMsg,
     79                       "When reading debug info from %s:\n",
     80                       (di && di->fsm.filename) ? di->fsm.filename
     81                                                : "???");
     82       }
     83       VG_(message)(Vg_DebugMsg, "%s\n", msg);
     84 
     85    } else { /* !serious */
     86 
     87       if (VG_(clo_verbosity) >= 2)
     88          VG_(message)(Vg_DebugMsg, "%s\n", msg);
     89 
     90    }
     91 }
     92 
     93 
     94 /* Print a symbol. */
     95 void ML_(ppSym) ( Int idx, const DiSym* sym )
     96 {
     97    const HChar** sec_names = sym->sec_names;
     98    vg_assert(sym->pri_name);
     99    if (sec_names)
    100       vg_assert(sec_names);
    101    VG_(printf)( "%5d:  %c%c %#8lx .. %#8lx (%u)      %s%s",
    102                 idx,
    103                 sym->isText ? 'T' : '-',
    104                 sym->isIFunc ? 'I' : '-',
    105                 sym->avmas.main,
    106                 sym->avmas.main + sym->size - 1, sym->size,
    107                 sym->pri_name, sec_names ? " " : "" );
    108    if (sec_names) {
    109       while (*sec_names) {
    110          VG_(printf)("%s%s", *sec_names, *(sec_names+1) ? " " : "");
    111          sec_names++;
    112       }
    113    }
    114    VG_(printf)("\n");
    115 }
    116 
    117 /* Print a call-frame-info summary. */
    118 void ML_(ppDiCfSI) ( const XArray* /* of CfiExpr */ exprs,
    119                      Addr base, UInt len,
    120                      const DiCfSI_m* si_m )
    121 {
    122 #  define SHOW_HOW(_how, _off)                   \
    123       do {                                       \
    124          if (_how == CFIR_UNKNOWN) {             \
    125             VG_(printf)("Unknown");              \
    126          } else                                  \
    127          if (_how == CFIR_SAME) {                \
    128             VG_(printf)("Same");                 \
    129          } else                                  \
    130          if (_how == CFIR_CFAREL) {              \
    131             VG_(printf)("cfa+%d", _off);         \
    132          } else                                  \
    133          if (_how == CFIR_MEMCFAREL) {           \
    134             VG_(printf)("*(cfa+%d)", _off);      \
    135          } else                                  \
    136          if (_how == CFIR_EXPR) {                \
    137             VG_(printf)("{");                    \
    138             ML_(ppCfiExpr)(exprs, _off);         \
    139             VG_(printf)("}");                    \
    140          } else {                                \
    141             vg_assert(0+0);                      \
    142          }                                       \
    143       } while (0)
    144 
    145    if (base != 0 || len != 0)
    146       VG_(printf)("[%#lx .. %#lx]: ", base, base + len - 1);
    147    else
    148       VG_(printf)("[]: ");
    149 
    150    switch (si_m->cfa_how) {
    151       case CFIC_IA_SPREL:
    152          VG_(printf)("let cfa=oldSP+%d", si_m->cfa_off);
    153          break;
    154       case CFIC_IA_BPREL:
    155          VG_(printf)("let cfa=oldBP+%d", si_m->cfa_off);
    156          break;
    157       case CFIC_ARM_R13REL:
    158          VG_(printf)("let cfa=oldR13+%d", si_m->cfa_off);
    159          break;
    160       case CFIC_ARM_R12REL:
    161          VG_(printf)("let cfa=oldR12+%d", si_m->cfa_off);
    162          break;
    163       case CFIC_ARM_R11REL:
    164          VG_(printf)("let cfa=oldR11+%d", si_m->cfa_off);
    165          break;
    166       case CFIR_SAME:
    167          VG_(printf)("let cfa=Same");
    168          break;
    169       case CFIC_ARM_R7REL:
    170          VG_(printf)("let cfa=oldR7+%d", si_m->cfa_off);
    171          break;
    172       case CFIC_ARM64_SPREL:
    173          VG_(printf)("let cfa=oldSP+%d", si_m->cfa_off);
    174          break;
    175       case CFIC_ARM64_X29REL:
    176          VG_(printf)("let cfa=oldX29+%d", si_m->cfa_off);
    177          break;
    178       case CFIC_EXPR:
    179          VG_(printf)("let cfa={");
    180          ML_(ppCfiExpr)(exprs, si_m->cfa_off);
    181          VG_(printf)("}");
    182          break;
    183       default:
    184          vg_assert(0);
    185    }
    186 
    187    VG_(printf)(" in RA=");
    188    SHOW_HOW(si_m->ra_how, si_m->ra_off);
    189 #  if defined(VGA_x86) || defined(VGA_amd64)
    190    VG_(printf)(" SP=");
    191    SHOW_HOW(si_m->sp_how, si_m->sp_off);
    192    VG_(printf)(" BP=");
    193    SHOW_HOW(si_m->bp_how, si_m->bp_off);
    194 #  elif defined(VGA_arm)
    195    VG_(printf)(" R14=");
    196    SHOW_HOW(si_m->r14_how, si_m->r14_off);
    197    VG_(printf)(" R13=");
    198    SHOW_HOW(si_m->r13_how, si_m->r13_off);
    199    VG_(printf)(" R12=");
    200    SHOW_HOW(si_m->r12_how, si_m->r12_off);
    201    VG_(printf)(" R11=");
    202    SHOW_HOW(si_m->r11_how, si_m->r11_off);
    203    VG_(printf)(" R7=");
    204    SHOW_HOW(si_m->r7_how, si_m->r7_off);
    205 #  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
    206 #  elif defined(VGA_s390x) || defined(VGA_mips32) || defined(VGA_mips64)
    207    VG_(printf)(" SP=");
    208    SHOW_HOW(si_m->sp_how, si_m->sp_off);
    209    VG_(printf)(" FP=");
    210    SHOW_HOW(si_m->fp_how, si_m->fp_off);
    211 #  elif defined(VGA_arm64)
    212    VG_(printf)(" SP=");
    213    SHOW_HOW(si_m->sp_how, si_m->sp_off);
    214    VG_(printf)(" X30=");
    215    SHOW_HOW(si_m->x30_how, si_m->x30_off);
    216    VG_(printf)(" X29=");
    217    SHOW_HOW(si_m->x29_how, si_m->x29_off);
    218 #  elif defined(VGA_tilegx)
    219    VG_(printf)(" SP=");
    220    SHOW_HOW(si_m->sp_how, si_m->sp_off);
    221    VG_(printf)(" FP=");
    222    SHOW_HOW(si_m->fp_how, si_m->fp_off);
    223 #  else
    224 #    error "Unknown arch"
    225 #  endif
    226    VG_(printf)("\n");
    227 #  undef SHOW_HOW
    228 }
    229 
    230 
    231 /*------------------------------------------------------------*/
    232 /*--- Adding stuff                                         ---*/
    233 /*------------------------------------------------------------*/
    234 
    235 /* Add a str to the string table, including terminating zero, and
    236    return pointer to the string in vg_strtab.  Unless it's been seen
    237    recently, in which case we find the old pointer and return that.
    238    This avoids the most egregious duplications.
    239 
    240    JSGF: changed from returning an index to a pointer, and changed to
    241    a chunking memory allocator rather than reallocating, so the
    242    pointers are stable.
    243 */
    244 const HChar* ML_(addStr) ( DebugInfo* di, const HChar* str, Int len )
    245 {
    246    if (len == -1) {
    247       len = VG_(strlen)(str);
    248    } else {
    249       vg_assert(len >= 0);
    250    }
    251    if (UNLIKELY(di->strpool == NULL))
    252       di->strpool = VG_(newDedupPA)(SEGINFO_STRPOOLSIZE,
    253                                     1,
    254                                     ML_(dinfo_zalloc),
    255                                     "di.storage.addStr.1",
    256                                     ML_(dinfo_free));
    257    return VG_(allocEltDedupPA) (di->strpool, len+1, str);
    258 }
    259 
    260 UInt ML_(addFnDn) (struct _DebugInfo* di,
    261                    const HChar* filename,
    262                    const HChar* dirname)
    263 {
    264    FnDn fndn;
    265    UInt fndn_ix;
    266 
    267    if (UNLIKELY(di->fndnpool == NULL))
    268       di->fndnpool = VG_(newDedupPA)(500,
    269                                      vg_alignof(FnDn),
    270                                      ML_(dinfo_zalloc),
    271                                      "di.storage.addFnDn.1",
    272                                      ML_(dinfo_free));
    273    fndn.filename = ML_(addStr)(di, filename, -1);
    274    fndn.dirname = dirname ? ML_(addStr)(di, dirname, -1) : NULL;
    275    fndn_ix = VG_(allocFixedEltDedupPA) (di->fndnpool, sizeof(FnDn), &fndn);
    276    return fndn_ix;
    277 }
    278 
    279 const HChar* ML_(fndn_ix2filename) (const DebugInfo* di,
    280                                     UInt fndn_ix)
    281 {
    282    FnDn *fndn;
    283    if (fndn_ix == 0)
    284       return "???";
    285    else {
    286       fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix);
    287       return fndn->filename;
    288    }
    289 }
    290 
    291 const HChar* ML_(fndn_ix2dirname) (const DebugInfo* di,
    292                                    UInt fndn_ix)
    293 {
    294    FnDn *fndn;
    295    if (fndn_ix == 0)
    296       return "";
    297    else {
    298       fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix);
    299       if (fndn->dirname)
    300          return fndn->dirname;
    301       else
    302          return "";
    303    }
    304 }
    305 
    306 /* Add a string to the string table of a DebugInfo, by copying the
    307    string from the given DiCursor.  Measures the length of the string
    308    itself. */
    309 const HChar* ML_(addStrFromCursor)( DebugInfo* di, DiCursor c )
    310 {
    311    /* This is a less-than-stellar implementation, but it should
    312       work. */
    313    vg_assert(ML_(cur_is_valid)(c));
    314    HChar* str = ML_(cur_read_strdup)(c, "di.addStrFromCursor.1");
    315    const HChar* res = ML_(addStr)(di, str, -1);
    316    ML_(dinfo_free)(str);
    317    return res;
    318 }
    319 
    320 
    321 /* Add a symbol to the symbol table, by copying *sym.  'sym' may only
    322    have one name, so there's no complexities to do with deep vs
    323    shallow copying of the sec_name array.  This is checked.
    324 */
    325 void ML_(addSym) ( struct _DebugInfo* di, DiSym* sym )
    326 {
    327    UInt   new_sz, i;
    328    DiSym* new_tab;
    329 
    330    vg_assert(sym->pri_name != NULL);
    331    vg_assert(sym->sec_names == NULL);
    332 
    333    /* Ignore zero-sized syms. */
    334    if (sym->size == 0) return;
    335 
    336    if (di->symtab_used == di->symtab_size) {
    337       new_sz = 2 * di->symtab_size;
    338       if (new_sz == 0) new_sz = 500;
    339       new_tab = ML_(dinfo_zalloc)( "di.storage.addSym.1",
    340                                    new_sz * sizeof(DiSym) );
    341       if (di->symtab != NULL) {
    342          for (i = 0; i < di->symtab_used; i++)
    343             new_tab[i] = di->symtab[i];
    344          ML_(dinfo_free)(di->symtab);
    345       }
    346       di->symtab = new_tab;
    347       di->symtab_size = new_sz;
    348    }
    349 
    350    di->symtab[di->symtab_used++] = *sym;
    351    vg_assert(di->symtab_used <= di->symtab_size);
    352 }
    353 
    354 UInt ML_(fndn_ix) (const DebugInfo* di, Word locno)
    355 {
    356    UInt fndn_ix;
    357 
    358    switch(di->sizeof_fndn_ix) {
    359       case 1: fndn_ix = ((UChar*)  di->loctab_fndn_ix)[locno]; break;
    360       case 2: fndn_ix = ((UShort*) di->loctab_fndn_ix)[locno]; break;
    361       case 4: fndn_ix = ((UInt*)   di->loctab_fndn_ix)[locno]; break;
    362       default: vg_assert(0);
    363    }
    364    return fndn_ix;
    365 }
    366 
    367 static inline void set_fndn_ix (struct _DebugInfo* di, Word locno, UInt fndn_ix)
    368 {
    369    Word i;
    370 
    371    switch(di->sizeof_fndn_ix) {
    372       case 1:
    373          if (LIKELY (fndn_ix <= 255)) {
    374             ((UChar*) di->loctab_fndn_ix)[locno] = fndn_ix;
    375             return;
    376          }
    377          {
    378             UChar* old = (UChar*) di->loctab_fndn_ix;
    379             UShort* new = ML_(dinfo_zalloc)( "di.storage.sfix.1",
    380                                              di->loctab_size * 2 );
    381             for (i = 0; i < di->loctab_used; i++)
    382                new[i] = old[i];
    383             ML_(dinfo_free)(old);
    384             di->sizeof_fndn_ix = 2;
    385             di->loctab_fndn_ix = new;
    386          }
    387          // Fallthrough
    388 
    389       case 2:
    390          if (LIKELY (fndn_ix <= 65535)) {
    391             ((UShort*) di->loctab_fndn_ix)[locno] = fndn_ix;
    392             return;
    393          }
    394          {
    395             UShort* old = (UShort*) di->loctab_fndn_ix;
    396             UInt* new = ML_(dinfo_zalloc)( "di.storage.sfix.2",
    397                                            di->loctab_size * 4 );
    398             for (i = 0; i < di->loctab_used; i++)
    399                new[i] = old[i];
    400             ML_(dinfo_free)(old);
    401             di->sizeof_fndn_ix = 4;
    402             di->loctab_fndn_ix = new;
    403          }
    404          // Fallthrough
    405 
    406       case 4:
    407          ((UInt*) di->loctab_fndn_ix)[locno] = fndn_ix;
    408          return;
    409 
    410       default: vg_assert(0);
    411    }
    412 }
    413 
    414 /* Add a location to the location table.
    415 */
    416 static void addLoc ( struct _DebugInfo* di, DiLoc* loc, UInt fndn_ix )
    417 {
    418    /* Zero-sized locs should have been ignored earlier */
    419    vg_assert(loc->size > 0);
    420 
    421    if (di->loctab_used == di->loctab_size) {
    422       UInt   new_sz;
    423       DiLoc* new_loctab;
    424       void*  new_loctab_fndn_ix;
    425 
    426       new_sz = 2 * di->loctab_size;
    427       if (new_sz == 0) new_sz = 500;
    428       new_loctab = ML_(dinfo_zalloc)( "di.storage.addLoc.1",
    429                                       new_sz * sizeof(DiLoc) );
    430       if (di->sizeof_fndn_ix == 0)
    431          di->sizeof_fndn_ix = 1; // To start with.
    432       new_loctab_fndn_ix = ML_(dinfo_zalloc)( "di.storage.addLoc.2",
    433                                               new_sz * di->sizeof_fndn_ix );
    434       if (di->loctab != NULL) {
    435          VG_(memcpy)(new_loctab, di->loctab,
    436                      di->loctab_used * sizeof(DiLoc));
    437          VG_(memcpy)(new_loctab_fndn_ix, di->loctab_fndn_ix,
    438                      di->loctab_used * di->sizeof_fndn_ix);
    439          ML_(dinfo_free)(di->loctab);
    440          ML_(dinfo_free)(di->loctab_fndn_ix);
    441       }
    442       di->loctab = new_loctab;
    443       di->loctab_fndn_ix = new_loctab_fndn_ix;
    444       di->loctab_size = new_sz;
    445    }
    446 
    447    di->loctab[di->loctab_used] = *loc;
    448    set_fndn_ix (di, di->loctab_used, fndn_ix);
    449    di->loctab_used++;
    450    vg_assert(di->loctab_used <= di->loctab_size);
    451 }
    452 
    453 
    454 /* Resize the LocTab (line number table) to save memory, by removing
    455    (and, potentially, allowing m_mallocfree to unmap) any unused space
    456    at the end of the table. */
    457 static void shrinkLocTab ( struct _DebugInfo* di )
    458 {
    459    UWord new_sz = di->loctab_used;
    460    if (new_sz == di->loctab_size) return;
    461    vg_assert(new_sz < di->loctab_size);
    462    ML_(dinfo_shrink_block)( di->loctab, new_sz * sizeof(DiLoc));
    463    ML_(dinfo_shrink_block)( di->loctab_fndn_ix, new_sz * di->sizeof_fndn_ix);
    464    di->loctab_size = new_sz;
    465 }
    466 
    467 
    468 /* Top-level place to call to add a source-location mapping entry.
    469 */
    470 void ML_(addLineInfo) ( struct _DebugInfo* di,
    471                         UInt     fndn_ix,
    472                         Addr     this,
    473                         Addr     next,
    474                         Int      lineno,
    475                         Int      entry /* only needed for debug printing */
    476      )
    477 {
    478    static const Bool debug = False;
    479    DiLoc loc;
    480    UWord size = next - this;
    481 
    482    /* Ignore zero-sized locs */
    483    if (this == next) return;
    484 
    485    if (debug) {
    486       FnDn *fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix);
    487       VG_(printf)( "  src ix %u %s %s line %d %#lx-%#lx\n",
    488                    fndn_ix,
    489                    fndn->dirname ? fndn->dirname : "(unknown)",
    490                    fndn->filename, lineno, this, next );
    491    }
    492 
    493    /* Maximum sanity checking.  Some versions of GNU as do a shabby
    494     * job with stabs entries; if anything looks suspicious, revert to
    495     * a size of 1.  This should catch the instruction of interest
    496     * (since if using asm-level debug info, one instruction will
    497     * correspond to one line, unlike with C-level debug info where
    498     * multiple instructions can map to the one line), but avoid
    499     * catching any other instructions bogusly. */
    500    if (this > next) {
    501        if (VG_(clo_verbosity) > 2) {
    502            VG_(message)(Vg_DebugMsg,
    503                         "warning: line info addresses out of order "
    504                         "at entry %d: 0x%lx 0x%lx\n", entry, this, next);
    505        }
    506        size = 1;
    507    }
    508 
    509    if (size > MAX_LOC_SIZE) {
    510        if (0)
    511        VG_(message)(Vg_DebugMsg,
    512                     "warning: line info address range too large "
    513                     "at entry %d: %lu\n", entry, size);
    514        size = 1;
    515    }
    516 
    517    /* At this point, we know that the original value for |size|, viz
    518       |next - this|, will only still be used in the case where
    519       |this| <u |next|, so it can't have underflowed.  Considering
    520       that and the three checks that follow it, the following must
    521       hold. */
    522    vg_assert(size >= 1);
    523    vg_assert(size <= MAX_LOC_SIZE);
    524 
    525    /* Rule out ones which are completely outside the r-x mapped area.
    526       See "Comment_Regarding_Text_Range_Checks" elsewhere in this file
    527       for background and rationale. */
    528    vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map);
    529    if (ML_(find_rx_mapping)(di, this, this + size - 1) == NULL) {
    530        if (0)
    531           VG_(message)(Vg_DebugMsg,
    532                        "warning: ignoring line info entry falling "
    533                        "outside current DebugInfo: %#lx %#lx %#lx %#lx\n",
    534                        di->text_avma,
    535                        di->text_avma + di->text_size,
    536                        this, this + size - 1);
    537        return;
    538    }
    539 
    540    if (lineno < 0) {
    541       static Bool complained = False;
    542       if (!complained) {
    543          complained = True;
    544          VG_(message)(Vg_UserMsg,
    545                       "warning: ignoring line info entry with "
    546                       "negative line number (%d)\n", lineno);
    547          VG_(message)(Vg_UserMsg,
    548                       "(Nb: this message is only shown once)\n");
    549       }
    550       return;
    551    }
    552    if (lineno > MAX_LINENO) {
    553       static Bool complained = False;
    554       if (!complained) {
    555          complained = True;
    556          VG_(message)(Vg_UserMsg,
    557                       "warning: ignoring line info entry with "
    558                       "huge line number (%d)\n", lineno);
    559          VG_(message)(Vg_UserMsg,
    560                       "         Can't handle line numbers "
    561                       "greater than %d, sorry\n", MAX_LINENO);
    562          VG_(message)(Vg_UserMsg,
    563                       "(Nb: this message is only shown once)\n");
    564       }
    565       return;
    566    }
    567 
    568    loc.addr      = this;
    569    loc.size      = (UShort)size;
    570    loc.lineno    = lineno;
    571 
    572    if (0) VG_(message)(Vg_DebugMsg,
    573 		       "addLoc: addr %#lx, size %lu, line %d, fndn_ix %u\n",
    574 		       this,size,lineno,fndn_ix);
    575 
    576    addLoc ( di, &loc, fndn_ix );
    577 }
    578 
    579 /* Add an inlined call info to the inlined call table.
    580 */
    581 static void addInl ( struct _DebugInfo* di, DiInlLoc* inl )
    582 {
    583    UInt   new_sz, i;
    584    DiInlLoc* new_tab;
    585 
    586    /* empty inl should have been ignored earlier */
    587    vg_assert(inl->addr_lo < inl->addr_hi);
    588 
    589    if (di->inltab_used == di->inltab_size) {
    590       new_sz = 2 * di->inltab_size;
    591       if (new_sz == 0) new_sz = 500;
    592       new_tab = ML_(dinfo_zalloc)( "di.storage.addInl.1",
    593                                    new_sz * sizeof(DiInlLoc) );
    594       if (di->inltab != NULL) {
    595          for (i = 0; i < di->inltab_used; i++)
    596             new_tab[i] = di->inltab[i];
    597          ML_(dinfo_free)(di->inltab);
    598       }
    599       di->inltab = new_tab;
    600       di->inltab_size = new_sz;
    601    }
    602 
    603    di->inltab[di->inltab_used] = *inl;
    604    if (inl->addr_hi - inl->addr_lo > di->maxinl_codesz)
    605       di->maxinl_codesz = inl->addr_hi - inl->addr_lo;
    606    di->inltab_used++;
    607    vg_assert(di->inltab_used <= di->inltab_size);
    608 }
    609 
    610 
    611 /* Resize the InlTab (inlined call table) to save memory, by removing
    612    (and, potentially, allowing m_mallocfree to unmap) any unused space
    613    at the end of the table. */
    614 static void shrinkInlTab ( struct _DebugInfo* di )
    615 {
    616    UWord new_sz = di->inltab_used;
    617    if (new_sz == di->inltab_size) return;
    618    vg_assert(new_sz < di->inltab_size);
    619    ML_(dinfo_shrink_block)( di->inltab, new_sz * sizeof(DiInlLoc));
    620    di->inltab_size = new_sz;
    621 }
    622 
    623 /* Top-level place to call to add a addr-to-inlined fn info. */
    624 void ML_(addInlInfo) ( struct _DebugInfo* di,
    625                        Addr addr_lo, Addr addr_hi,
    626                        const HChar* inlinedfn,
    627                        UInt fndn_ix,
    628                        Int lineno, UShort level)
    629 {
    630    DiInlLoc inl;
    631 
    632    /* Similar paranoia as in ML_(addLineInfo). Unclear if needed. */
    633    if (addr_lo >= addr_hi) {
    634        if (VG_(clo_verbosity) > 2) {
    635            VG_(message)(Vg_DebugMsg,
    636                         "warning: inlined info addresses out of order "
    637                         "at: 0x%lx 0x%lx\n", addr_lo, addr_hi);
    638        }
    639        addr_hi = addr_lo + 1;
    640    }
    641 
    642    vg_assert(lineno >= 0);
    643    if (lineno > MAX_LINENO) {
    644       static Bool complained = False;
    645       if (!complained) {
    646          complained = True;
    647          VG_(message)(Vg_UserMsg,
    648                       "warning: ignoring inlined call info entry with "
    649                       "huge line number (%d)\n", lineno);
    650          VG_(message)(Vg_UserMsg,
    651                       "         Can't handle line numbers "
    652                       "greater than %d, sorry\n", MAX_LINENO);
    653          VG_(message)(Vg_UserMsg,
    654                       "(Nb: this message is only shown once)\n");
    655       }
    656       return;
    657    }
    658 
    659    // code resulting from inlining of inlinedfn:
    660    inl.addr_lo   = addr_lo;
    661    inl.addr_hi   = addr_hi;
    662    inl.inlinedfn = inlinedfn;
    663    // caller:
    664    inl.fndn_ix   = fndn_ix;
    665    inl.lineno    = lineno;
    666    inl.level     = level;
    667 
    668    if (0) VG_(message)
    669              (Vg_DebugMsg,
    670               "addInlInfo: fn %s inlined as addr_lo %#lx,addr_hi %#lx,"
    671               "caller fndn_ix %u %s:%d\n",
    672               inlinedfn, addr_lo, addr_hi, fndn_ix,
    673               ML_(fndn_ix2filename) (di, fndn_ix), lineno);
    674 
    675    addInl ( di, &inl );
    676 }
    677 
    678 DiCfSI_m* ML_(get_cfsi_m) (const DebugInfo* di, UInt pos)
    679 {
    680    UInt cfsi_m_ix;
    681 
    682    vg_assert(pos >= 0 && pos < di->cfsi_used);
    683    switch (di->sizeof_cfsi_m_ix) {
    684       case 1: cfsi_m_ix = ((UChar*)  di->cfsi_m_ix)[pos]; break;
    685       case 2: cfsi_m_ix = ((UShort*) di->cfsi_m_ix)[pos]; break;
    686       case 4: cfsi_m_ix = ((UInt*)   di->cfsi_m_ix)[pos]; break;
    687       default: vg_assert(0);
    688    }
    689    if (cfsi_m_ix == 0)
    690       return NULL; // cfi hole
    691    else
    692       return VG_(indexEltNumber) (di->cfsi_m_pool, cfsi_m_ix);
    693 }
    694 
    695 /* Top-level place to call to add a CFI summary record.  The supplied
    696    DiCfSI_m is copied. */
    697 void ML_(addDiCfSI) ( struct _DebugInfo* di,
    698                       Addr base, UInt len, DiCfSI_m* cfsi_m )
    699 {
    700    static const Bool debug = False;
    701    UInt    new_sz;
    702    DiCfSI* new_tab;
    703    SSizeT  delta;
    704    DebugInfoMapping* map;
    705    DebugInfoMapping* map2;
    706 
    707    if (debug) {
    708       VG_(printf)("adding DiCfSI: ");
    709       ML_(ppDiCfSI)(di->cfsi_exprs, base, len, cfsi_m);
    710    }
    711 
    712    /* sanity */
    713    vg_assert(len > 0);
    714    /* Issue a warning if LEN is unexpectedly large (exceeds 5 million).
    715       The implication is you have a single procedure
    716       with more than 5 million bytes of code.  Which is pretty
    717       unlikely.  Either that, or the debuginfo reader is somehow
    718       broken.  5 million is of course arbitrary; but it's big enough
    719       to be bigger than the size of any plausible piece of code that
    720       would fall within a single procedure. But occasionally it does
    721       happen (c.f. BZ #339542). */
    722    if (len >= 5000000)
    723       VG_(message)(Vg_DebugMsg,
    724                    "warning: DiCfSI %#lx .. %#lx is huge; length = %u (%s)\n",
    725                    base, base + len - 1, len, di->soname);
    726 
    727    vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map);
    728    /* Find mapping where at least one end of the CFSI falls into. */
    729    map  = ML_(find_rx_mapping)(di, base, base);
    730    map2 = ML_(find_rx_mapping)(di, base + len - 1,
    731                                    base + len - 1);
    732    if (map == NULL)
    733       map = map2;
    734    else if (map2 == NULL)
    735       map2 = map;
    736 
    737    /* Rule out ones which are completely outside the r-x mapped area
    738       (or which span across different areas).
    739       See "Comment_Regarding_Text_Range_Checks" elsewhere in this file
    740       for background and rationale. */
    741    if (map == NULL || map != map2) {
    742       static Int complaints = 10;
    743       if (VG_(clo_trace_cfi) || complaints > 0) {
    744          complaints--;
    745          if (VG_(clo_verbosity) > 1) {
    746             VG_(message)(
    747                Vg_DebugMsg,
    748                "warning: DiCfSI %#lx .. %#lx outside mapped rx segments (%s)\n",
    749                base,
    750                base + len - 1,
    751                di->soname
    752             );
    753          }
    754          if (VG_(clo_trace_cfi))
    755             ML_(ppDiCfSI)(di->cfsi_exprs, base, len, cfsi_m);
    756       }
    757       return;
    758    }
    759 
    760    /* Now we know the range is at least partially inside the r-x
    761       mapped area.  That implies that at least one of the ends of the
    762       range falls inside the area.  If necessary, clip it so it is
    763       completely within the area.  If we don't do this,
    764       check_CFSI_related_invariants() in debuginfo.c (invariant #2)
    765       will fail.  See
    766       "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
    767       priv_storage.h for background. */
    768    if (base < map->avma) {
    769       /* Lower end is outside the mapped area.  Hence upper end must
    770          be inside it. */
    771       if (0) VG_(printf)("XXX truncate lower\n");
    772       vg_assert(base + len - 1 >= map->avma);
    773       delta = (SSizeT)(map->avma - base);
    774       vg_assert(delta > 0);
    775       vg_assert(delta < (SSizeT)len);
    776       base += delta;
    777       len -= delta;
    778    }
    779    else
    780    if (base + len - 1 > map->avma + map->size - 1) {
    781       /* Upper end is outside the mapped area.  Hence lower end must be
    782          inside it. */
    783       if (0) VG_(printf)("XXX truncate upper\n");
    784       vg_assert(base <= map->avma + map->size - 1);
    785       delta = (SSizeT)( (base + len - 1)
    786                         - (map->avma + map->size - 1) );
    787       vg_assert(delta > 0);
    788       vg_assert(delta < (SSizeT)len);
    789       len -= delta;
    790    }
    791 
    792    /* Final checks */
    793 
    794    /* Because: either cfsi was entirely inside the range, in which
    795       case we asserted that len > 0 at the start, OR it fell partially
    796       inside the range, in which case we reduced it by some size
    797       (delta) which is < its original size. */
    798    vg_assert(len > 0);
    799 
    800    /* Similar logic applies for the next two assertions. */
    801    vg_assert(base >= map->avma);
    802    vg_assert(base + len - 1
    803              <= map->avma + map->size - 1);
    804 
    805    if (di->cfsi_used == di->cfsi_size) {
    806       new_sz = 2 * di->cfsi_size;
    807       if (new_sz == 0) new_sz = 20;
    808       new_tab = ML_(dinfo_zalloc)( "di.storage.addDiCfSI.1",
    809                                    new_sz * sizeof(DiCfSI) );
    810       if (di->cfsi_rd != NULL) {
    811          VG_(memcpy)(new_tab, di->cfsi_rd,
    812                      di->cfsi_used * sizeof(DiCfSI));
    813          ML_(dinfo_free)(di->cfsi_rd);
    814       }
    815       di->cfsi_rd = new_tab;
    816       di->cfsi_size = new_sz;
    817       if (di->cfsi_m_pool == NULL)
    818          di->cfsi_m_pool = VG_(newDedupPA)(1000 * sizeof(DiCfSI_m),
    819                                            vg_alignof(DiCfSI_m),
    820                                            ML_(dinfo_zalloc),
    821                                            "di.storage.DiCfSI_m_pool",
    822                                            ML_(dinfo_free));
    823    }
    824 
    825    di->cfsi_rd[di->cfsi_used].base = base;
    826    di->cfsi_rd[di->cfsi_used].len  = len;
    827    di->cfsi_rd[di->cfsi_used].cfsi_m_ix
    828       = VG_(allocFixedEltDedupPA)(di->cfsi_m_pool,
    829                                   sizeof(DiCfSI_m),
    830                                   cfsi_m);
    831    di->cfsi_used++;
    832    vg_assert(di->cfsi_used <= di->cfsi_size);
    833 }
    834 
    835 
    836 Int ML_(CfiExpr_Undef)( XArray* dst )
    837 {
    838    CfiExpr e;
    839    VG_(memset)( &e, 0, sizeof(e) );
    840    e.tag = Cex_Undef;
    841    return (Int)VG_(addToXA)( dst, &e );
    842 }
    843 Int ML_(CfiExpr_Deref)( XArray* dst, Int ixAddr )
    844 {
    845    CfiExpr e;
    846    VG_(memset)( &e, 0, sizeof(e) );
    847    e.tag = Cex_Deref;
    848    e.Cex.Deref.ixAddr = ixAddr;
    849    return (Int)VG_(addToXA)( dst, &e );
    850 }
    851 Int ML_(CfiExpr_Const)( XArray* dst, UWord con )
    852 {
    853    CfiExpr e;
    854    VG_(memset)( &e, 0, sizeof(e) );
    855    e.tag = Cex_Const;
    856    e.Cex.Const.con = con;
    857    return (Int)VG_(addToXA)( dst, &e );
    858 }
    859 Int ML_(CfiExpr_Unop)( XArray* dst, CfiUnop op, Int ix )
    860 {
    861    CfiExpr e;
    862    VG_(memset)( &e, 0, sizeof(e) );
    863    e.tag = Cex_Unop;
    864    e.Cex.Unop.op  = op;
    865    e.Cex.Unop.ix = ix;
    866    return (Int)VG_(addToXA)( dst, &e );
    867 }
    868 Int ML_(CfiExpr_Binop)( XArray* dst, CfiBinop op, Int ixL, Int ixR )
    869 {
    870    CfiExpr e;
    871    VG_(memset)( &e, 0, sizeof(e) );
    872    e.tag = Cex_Binop;
    873    e.Cex.Binop.op  = op;
    874    e.Cex.Binop.ixL = ixL;
    875    e.Cex.Binop.ixR = ixR;
    876    return (Int)VG_(addToXA)( dst, &e );
    877 }
    878 Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg )
    879 {
    880    CfiExpr e;
    881    VG_(memset)( &e, 0, sizeof(e) );
    882    e.tag = Cex_CfiReg;
    883    e.Cex.CfiReg.reg = reg;
    884    return (Int)VG_(addToXA)( dst, &e );
    885 }
    886 Int ML_(CfiExpr_DwReg)( XArray* dst, Int reg )
    887 {
    888    CfiExpr e;
    889    VG_(memset)( &e, 0, sizeof(e) );
    890    e.tag = Cex_DwReg;
    891    e.Cex.DwReg.reg = reg;
    892    return (Int)VG_(addToXA)( dst, &e );
    893 }
    894 
    895 static void ppCfiUnop ( CfiUnop op )
    896 {
    897    switch (op) {
    898       case Cunop_Abs: VG_(printf)("abs"); break;
    899       case Cunop_Neg: VG_(printf)("-"); break;
    900       case Cunop_Not: VG_(printf)("~"); break;
    901       default:        vg_assert(0);
    902    }
    903 }
    904 
    905 static void ppCfiBinop ( CfiBinop op )
    906 {
    907    switch (op) {
    908       case Cbinop_Add: VG_(printf)("+"); break;
    909       case Cbinop_Sub: VG_(printf)("-"); break;
    910       case Cbinop_And: VG_(printf)("&"); break;
    911       case Cbinop_Mul: VG_(printf)("*"); break;
    912       case Cbinop_Shl: VG_(printf)("<<"); break;
    913       case Cbinop_Shr: VG_(printf)(">>"); break;
    914       case Cbinop_Eq:  VG_(printf)("=="); break;
    915       case Cbinop_Ge:  VG_(printf)(">="); break;
    916       case Cbinop_Gt:  VG_(printf)(">"); break;
    917       case Cbinop_Le:  VG_(printf)("<="); break;
    918       case Cbinop_Lt:  VG_(printf)("<"); break;
    919       case Cbinop_Ne:  VG_(printf)("!="); break;
    920       default:         vg_assert(0);
    921    }
    922 }
    923 
    924 static void ppCfiReg ( CfiReg reg )
    925 {
    926    switch (reg) {
    927       case Creg_INVALID:   VG_(printf)("Creg_INVALID"); break;
    928       case Creg_IA_SP:     VG_(printf)("xSP"); break;
    929       case Creg_IA_BP:     VG_(printf)("xBP"); break;
    930       case Creg_IA_IP:     VG_(printf)("xIP"); break;
    931       case Creg_ARM_R13:   VG_(printf)("R13"); break;
    932       case Creg_ARM_R12:   VG_(printf)("R12"); break;
    933       case Creg_ARM_R15:   VG_(printf)("R15"); break;
    934       case Creg_ARM_R14:   VG_(printf)("R14"); break;
    935       case Creg_ARM_R7:    VG_(printf)("R7");  break;
    936       case Creg_ARM64_X30: VG_(printf)("X30"); break;
    937       case Creg_MIPS_RA:   VG_(printf)("RA"); break;
    938       case Creg_S390_IA:   VG_(printf)("IA"); break;
    939       case Creg_S390_SP:   VG_(printf)("SP"); break;
    940       case Creg_S390_FP:   VG_(printf)("FP"); break;
    941       case Creg_S390_LR:   VG_(printf)("LR"); break;
    942       case Creg_TILEGX_IP: VG_(printf)("PC");  break;
    943       case Creg_TILEGX_SP: VG_(printf)("SP");  break;
    944       case Creg_TILEGX_BP: VG_(printf)("BP");  break;
    945       case Creg_TILEGX_LR: VG_(printf)("R55"); break;
    946       default: vg_assert(0);
    947    }
    948 }
    949 
    950 void ML_(ppCfiExpr)( const XArray* src, Int ix )
    951 {
    952    /* VG_(indexXA) checks for invalid src/ix values, so we can
    953       use it indiscriminately. */
    954    const CfiExpr* e = VG_(indexXA)( src, ix );
    955    switch (e->tag) {
    956       case Cex_Undef:
    957          VG_(printf)("Undef");
    958          break;
    959       case Cex_Deref:
    960          VG_(printf)("*(");
    961          ML_(ppCfiExpr)(src, e->Cex.Deref.ixAddr);
    962          VG_(printf)(")");
    963          break;
    964       case Cex_Const:
    965          VG_(printf)("0x%lx", e->Cex.Const.con);
    966          break;
    967       case Cex_Unop:
    968          ppCfiUnop(e->Cex.Unop.op);
    969          VG_(printf)("(");
    970          ML_(ppCfiExpr)(src, e->Cex.Unop.ix);
    971          VG_(printf)(")");
    972          break;
    973       case Cex_Binop:
    974          VG_(printf)("(");
    975          ML_(ppCfiExpr)(src, e->Cex.Binop.ixL);
    976          VG_(printf)(")");
    977          ppCfiBinop(e->Cex.Binop.op);
    978          VG_(printf)("(");
    979          ML_(ppCfiExpr)(src, e->Cex.Binop.ixR);
    980          VG_(printf)(")");
    981          break;
    982       case Cex_CfiReg:
    983          ppCfiReg(e->Cex.CfiReg.reg);
    984          break;
    985       case Cex_DwReg:
    986          VG_(printf)("dwr%d", e->Cex.DwReg.reg);
    987          break;
    988       default:
    989          VG_(core_panic)("ML_(ppCfiExpr)");
    990          /*NOTREACHED*/
    991          break;
    992    }
    993 }
    994 
    995 
    996 Word ML_(cmp_for_DiAddrRange_range) ( const void* keyV,
    997                                       const void* elemV ) {
    998    const Addr* key = (const Addr*)keyV;
    999    const DiAddrRange* elem = (const DiAddrRange*)elemV;
   1000    if (0)
   1001       VG_(printf)("cmp_for_DiAddrRange_range: %#lx vs %#lx\n",
   1002                   *key, elem->aMin);
   1003    if ((*key) < elem->aMin) return -1;
   1004    if ((*key) > elem->aMax) return 1;
   1005    return 0;
   1006 }
   1007 
   1008 static
   1009 void show_scope ( OSet* /* of DiAddrRange */ scope, const HChar* who )
   1010 {
   1011    DiAddrRange* range;
   1012    VG_(printf)("Scope \"%s\" = {\n", who);
   1013    VG_(OSetGen_ResetIter)( scope );
   1014    while (True) {
   1015       range = VG_(OSetGen_Next)( scope );
   1016       if (!range) break;
   1017       VG_(printf)("   %#lx .. %#lx: %ld vars\n", range->aMin, range->aMax,
   1018                   range->vars ? VG_(sizeXA)(range->vars) : 0);
   1019    }
   1020    VG_(printf)("}\n");
   1021 }
   1022 
   1023 /* Add the variable 'var' to 'scope' for the address range [aMin,aMax]
   1024    (inclusive of aMin and aMax).  Split existing ranges as required if
   1025    aMin or aMax or both don't match existing range boundaries, and add
   1026    'var' to all required ranges.  Take great care to preserve the
   1027    invariant that the ranges in 'scope' cover the entire address range
   1028    exactly once, with no overlaps and no holes. */
   1029 static void add_var_to_arange (
   1030                /*MOD*/OSet* /* of DiAddrRange */ scope,
   1031                Addr aMin,
   1032                Addr aMax,
   1033                DiVariable* var
   1034             )
   1035 {
   1036    DiAddrRange *first, *last, *range;
   1037    /* These xx variables are for assertion checking only; they don't
   1038       contribute anything to the actual work of this function. */
   1039    DiAddrRange *xxRangep, *xxFirst, *xxLast;
   1040    UWord       xxIters;
   1041 
   1042    vg_assert(aMin <= aMax);
   1043 
   1044    if (0) VG_(printf)("add_var_to_arange: %#lx .. %#lx\n", aMin, aMax);
   1045    if (0) show_scope( scope, "add_var_to_arange(1)" );
   1046 
   1047    /* See if the lower end of the range (aMin) falls exactly on an
   1048       existing range boundary.  If not, find the range it does fall
   1049       into, and split it (copying the variables in the process), so
   1050       that aMin does exactly fall on a range boundary. */
   1051    first = VG_(OSetGen_Lookup)( scope, &aMin );
   1052    /* It must be present, since the presented OSet must cover
   1053       the entire address range. */
   1054    vg_assert(first);
   1055    vg_assert(first->aMin <= first->aMax);
   1056    vg_assert(first->aMin <= aMin && aMin <= first->aMax);
   1057 
   1058    /* Fast track common case, which is that the range specified for
   1059       the variable exactly coincides with one already-existing
   1060       range. */
   1061    if (first->aMin == aMin && first->aMax == aMax) {
   1062       vg_assert(first->vars);
   1063       VG_(addToXA)( first->vars, var );
   1064       return;
   1065    }
   1066 
   1067    /* We have to get into splitting ranges, which is complex
   1068       and slow. */
   1069    if (first->aMin < aMin) {
   1070       DiAddrRange* nyu;
   1071       /* Ok.  We'll have to split 'first'. */
   1072       /* truncate the upper end of 'first' */
   1073       Addr tmp = first->aMax;
   1074       first->aMax = aMin-1;
   1075       vg_assert(first->aMin <= first->aMax);
   1076       /* create a new range */
   1077       nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) );
   1078       nyu->aMin = aMin;
   1079       nyu->aMax = tmp;
   1080       vg_assert(nyu->aMin <= nyu->aMax);
   1081       /* copy vars into it */
   1082       vg_assert(first->vars);
   1083       nyu->vars = VG_(cloneXA)( "di.storage.avta.1", first->vars );
   1084       VG_(OSetGen_Insert)( scope, nyu );
   1085       first = nyu;
   1086    }
   1087 
   1088    vg_assert(first->aMin == aMin);
   1089 
   1090    /* Now do exactly the same for the upper end (aMax): if it doesn't
   1091       fall on a boundary, cause it to do so by splitting the range it
   1092       does currently fall into. */
   1093    last = VG_(OSetGen_Lookup)( scope, &aMax );
   1094    vg_assert(last->aMin <= last->aMax);
   1095    vg_assert(last->aMin <= aMax && aMax <= last->aMax);
   1096 
   1097    if (aMax < last->aMax) {
   1098       DiAddrRange* nyu;
   1099       /* We have to split 'last'. */
   1100       /* truncate the lower end of 'last' */
   1101       Addr tmp = last->aMin;
   1102       last->aMin = aMax+1;
   1103       vg_assert(last->aMin <= last->aMax);
   1104       /* create a new range */
   1105       nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) );
   1106       nyu->aMin = tmp;
   1107       nyu->aMax = aMax;
   1108       vg_assert(nyu->aMin <= nyu->aMax);
   1109       /* copy vars into it */
   1110       vg_assert(last->vars);
   1111       nyu->vars = VG_(cloneXA)( "di.storage.avta.2", last->vars );
   1112       VG_(OSetGen_Insert)( scope, nyu );
   1113       last = nyu;
   1114    }
   1115 
   1116    vg_assert(aMax == last->aMax);
   1117 
   1118    xxFirst = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMin);
   1119    xxLast  = (DiAddrRange*)VG_(OSetGen_Lookup)(scope, &aMax);
   1120    vg_assert(xxFirst);
   1121    vg_assert(xxLast);
   1122    vg_assert(xxFirst->aMin == aMin);
   1123    vg_assert(xxLast->aMax == aMax);
   1124    if (xxFirst != xxLast)
   1125       vg_assert(xxFirst->aMax < xxLast->aMin);
   1126 
   1127    /* Great.  Now we merely need to iterate over the segments from
   1128       'first' to 'last' inclusive, and add 'var' to the variable set
   1129       of each of them. */
   1130    if (0) {
   1131       static UWord ctr = 0;
   1132       ctr++;
   1133       VG_(printf)("ctr = %lu\n", ctr);
   1134       if (ctr >= 33263) show_scope( scope, "add_var_to_arange(2)" );
   1135    }
   1136 
   1137    xxIters = 0;
   1138    range = xxRangep = NULL;
   1139    VG_(OSetGen_ResetIterAt)( scope, &aMin );
   1140    while (True) {
   1141       xxRangep = range;
   1142       range    = VG_(OSetGen_Next)( scope );
   1143       if (!range) break;
   1144       if (range->aMin > aMax) break;
   1145       xxIters++;
   1146       if (0) VG_(printf)("have range %#lx %#lx\n",
   1147                          range->aMin, range->aMax);
   1148 
   1149       /* Sanity checks */
   1150       if (!xxRangep) {
   1151          /* This is the first in the range */
   1152          vg_assert(range->aMin == aMin);
   1153       } else {
   1154          vg_assert(xxRangep->aMax + 1 == range->aMin);
   1155       }
   1156 
   1157       vg_assert(range->vars);
   1158       VG_(addToXA)( range->vars, var );
   1159    }
   1160    /* Done.  We should have seen at least one range. */
   1161    vg_assert(xxIters >= 1);
   1162    if (xxIters == 1) vg_assert(xxFirst == xxLast);
   1163    if (xxFirst == xxLast) vg_assert(xxIters == 1);
   1164    vg_assert(xxRangep);
   1165    vg_assert(xxRangep->aMax == aMax);
   1166    vg_assert(xxRangep == xxLast);
   1167 }
   1168 
   1169 
   1170 /* Top-level place to call to add a variable description (as extracted
   1171    from a DWARF3 .debug_info section. */
   1172 void ML_(addVar)( struct _DebugInfo* di,
   1173                   Int    level,
   1174                   Addr   aMin,
   1175                   Addr   aMax,
   1176                   const  HChar* name, /* in di's .strpool */
   1177                   UWord  typeR, /* a cuOff */
   1178                   const GExpr* gexpr,
   1179                   const GExpr* fbGX,
   1180                   UInt   fndn_ix, /* where decl'd - may be zero.
   1181                                      index in in di's .fndnpool */
   1182                   Int    lineNo, /* where decl'd - may be zero */
   1183                   Bool   show )
   1184 {
   1185    OSet* /* of DiAddrRange */ scope;
   1186    DiVariable var;
   1187    Bool       all;
   1188    TyEnt*     ent;
   1189    MaybeULong mul;
   1190    const HChar* badness;
   1191 
   1192    vg_assert(di && di->admin_tyents);
   1193 
   1194    if (0) {
   1195       VG_(printf)("  ML_(addVar): level %d  %#lx-%#lx  %s :: ",
   1196                   level, aMin, aMax, name );
   1197       ML_(pp_TyEnt_C_ishly)( di->admin_tyents, typeR );
   1198       VG_(printf)("\n  Var=");
   1199       ML_(pp_GX)(gexpr);
   1200       VG_(printf)("\n");
   1201       if (fbGX) {
   1202          VG_(printf)("  FrB=");
   1203          ML_(pp_GX)( fbGX );
   1204          VG_(printf)("\n");
   1205       } else {
   1206          VG_(printf)("  FrB=none\n");
   1207       }
   1208       VG_(printf)("\n");
   1209    }
   1210 
   1211    vg_assert(level >= 0);
   1212    vg_assert(aMin <= aMax);
   1213    vg_assert(name);
   1214    vg_assert(gexpr);
   1215 
   1216    ent = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, typeR);
   1217    vg_assert(ent);
   1218    vg_assert(ML_(TyEnt__is_type)(ent));
   1219 
   1220    /* "Comment_Regarding_Text_Range_Checks" (is referred to elsewhere)
   1221       ----------------------------------------------------------------
   1222       Ignore any variables whose aMin .. aMax (that is, range of text
   1223       addresses for which they actually exist) falls outside the text
   1224       segment.  Is this indicative of a bug in the reader?  Maybe.
   1225       (LATER): instead of restricting strictly to the .text segment,
   1226       be a bit more relaxed, and accept any variable whose text range
   1227       falls inside the r-x mapped area.  This is useful because .text
   1228       is not always the only instruction-carrying segment: others are:
   1229       .init .plt __libc_freeres_fn and .fini.  This implicitly assumes
   1230       that those extra sections have the same bias as .text, but that
   1231       seems a reasonable assumption to me. */
   1232    /* This is assured us by top level steering logic in debuginfo.c,
   1233       and it is re-checked at the start of
   1234       ML_(read_elf_debug_info). */
   1235    vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map);
   1236    if (level > 0 && ML_(find_rx_mapping)(di, aMin, aMax) == NULL) {
   1237       if (VG_(clo_verbosity) >= 0) {
   1238          VG_(message)(Vg_DebugMsg,
   1239             "warning: addVar: in range %#lx .. %#lx outside "
   1240             "all rx mapped areas (%s)\n",
   1241             aMin, aMax, name
   1242          );
   1243       }
   1244       return;
   1245    }
   1246 
   1247    /* If the type's size is zero (which can mean unknown size), ignore
   1248       it.  We will never be able to actually relate a data address to
   1249       a data object with zero size, so there's no point in storing
   1250       info on it.  On 32-bit platforms, also reject types whose size
   1251       is 2^32 bytes or large.  (It's amazing what junk shows up ..) */
   1252    mul = ML_(sizeOfType)(di->admin_tyents, typeR);
   1253 
   1254    badness = NULL;
   1255    if (mul.b != True)
   1256       badness = "unknown size";
   1257    else if (mul.ul == 0)
   1258       badness = "zero size   ";
   1259    else if (sizeof(void*) == 4 && mul.ul >= (1ULL<<32))
   1260       badness = "implausibly large";
   1261 
   1262    if (badness) {
   1263       static Int complaints = 10;
   1264       if (VG_(clo_verbosity) >= 2 && complaints > 0) {
   1265          VG_(message)(Vg_DebugMsg, "warning: addVar: %s (%s)\n",
   1266                                    badness, name );
   1267          complaints--;
   1268       }
   1269       return;
   1270    }
   1271 
   1272    if (!di->varinfo) {
   1273       di->varinfo = VG_(newXA)( ML_(dinfo_zalloc),
   1274                                 "di.storage.addVar.1",
   1275                                 ML_(dinfo_free),
   1276                                 sizeof(OSet*) );
   1277    }
   1278 
   1279    vg_assert(level < 256); /* arbitrary; stay sane */
   1280    /* Expand the top level array enough to map this level */
   1281    while ( VG_(sizeXA)(di->varinfo) <= level ) {
   1282       DiAddrRange* nyu;
   1283       scope = VG_(OSetGen_Create)( offsetof(DiAddrRange,aMin),
   1284                                    ML_(cmp_for_DiAddrRange_range),
   1285                                    ML_(dinfo_zalloc), "di.storage.addVar.2",
   1286                                    ML_(dinfo_free) );
   1287       if (0) VG_(printf)("create: scope = %p, adding at %ld\n",
   1288                          scope, VG_(sizeXA)(di->varinfo));
   1289       VG_(addToXA)( di->varinfo, &scope );
   1290       /* Add a single range covering the entire address space.  At
   1291          level 0 we require this doesn't get split.  At levels above 0
   1292          we require that any additions to it cause it to get split.
   1293          All of these invariants get checked both add_var_to_arange
   1294          and after reading is complete, in canonicaliseVarInfo. */
   1295       nyu = VG_(OSetGen_AllocNode)( scope, sizeof(DiAddrRange) );
   1296       nyu->aMin = (Addr)0;
   1297       nyu->aMax = ~(Addr)0;
   1298       nyu->vars = VG_(newXA)( ML_(dinfo_zalloc), "di.storage.addVar.3",
   1299                               ML_(dinfo_free),
   1300                               sizeof(DiVariable) );
   1301       VG_(OSetGen_Insert)( scope, nyu );
   1302    }
   1303 
   1304    vg_assert( VG_(sizeXA)(di->varinfo) > level );
   1305    scope = *(OSet**)VG_(indexXA)( di->varinfo, level );
   1306    vg_assert(scope);
   1307 
   1308    var.name     = name;
   1309    var.typeR    = typeR;
   1310    var.gexpr    = gexpr;
   1311    var.fbGX     = fbGX;
   1312    var.fndn_ix  = fndn_ix;
   1313    var.lineNo   = lineNo;
   1314 
   1315    all = aMin == (Addr)0 && aMax == ~(Addr)0;
   1316    vg_assert(level == 0 ? all : !all);
   1317 
   1318    add_var_to_arange( /*MOD*/scope, aMin, aMax, &var );
   1319 }
   1320 
   1321 
   1322 /* This really just checks the constructed data structure, as there is
   1323    no canonicalisation to do. */
   1324 static void canonicaliseVarInfo ( struct _DebugInfo* di )
   1325 {
   1326    Word i, nInThisScope;
   1327 
   1328    if (!di->varinfo)
   1329       return;
   1330 
   1331    for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
   1332 
   1333       DiAddrRange *range, *rangep;
   1334       OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
   1335       if (!scope) continue;
   1336 
   1337       /* Deal with the global-scope case. */
   1338       if (i == 0) {
   1339          Addr zero = 0;
   1340          vg_assert(VG_(OSetGen_Size)( scope ) == 1);
   1341          range = VG_(OSetGen_Lookup)( scope, &zero );
   1342          vg_assert(range);
   1343          vg_assert(range->aMin == (Addr)0);
   1344          vg_assert(range->aMax == ~(Addr)0);
   1345          continue;
   1346       }
   1347 
   1348       /* All the rest of this is for the local-scope case. */
   1349       /* iterate over all entries in 'scope' */
   1350       nInThisScope = 0;
   1351       rangep = NULL;
   1352       VG_(OSetGen_ResetIter)(scope);
   1353       while (True) {
   1354          range = VG_(OSetGen_Next)(scope);
   1355          if (!range) {
   1356            /* We just saw the last one.  There must have been at
   1357               least one entry in the range. */
   1358            vg_assert(rangep);
   1359            vg_assert(rangep->aMax == ~(Addr)0);
   1360            break;
   1361          }
   1362 
   1363          vg_assert(range->aMin <= range->aMax);
   1364          vg_assert(range->vars);
   1365 
   1366          if (!rangep) {
   1367            /* This is the first entry in the range. */
   1368            vg_assert(range->aMin == 0);
   1369          } else {
   1370            vg_assert(rangep->aMax + 1 == range->aMin);
   1371          }
   1372 
   1373          rangep = range;
   1374          nInThisScope++;
   1375       } /* iterating over ranges in a given scope */
   1376 
   1377       /* If there's only one entry in this (local) scope, it must
   1378          cover the entire address space (obviously), but it must not
   1379          contain any vars. */
   1380 
   1381       vg_assert(nInThisScope > 0);
   1382       if (nInThisScope == 1) {
   1383          Addr zero = 0;
   1384          vg_assert(VG_(OSetGen_Size)( scope ) == 1);
   1385          range = VG_(OSetGen_Lookup)( scope, &zero );
   1386          vg_assert(range);
   1387          vg_assert(range->aMin == (Addr)0);
   1388          vg_assert(range->aMax == ~(Addr)0);
   1389          vg_assert(range->vars);
   1390          vg_assert(VG_(sizeXA)(range->vars) == 0);
   1391       }
   1392 
   1393    } /* iterate over scopes */
   1394 }
   1395 
   1396 
   1397 /*------------------------------------------------------------*/
   1398 /*--- Canonicalisers                                       ---*/
   1399 /*------------------------------------------------------------*/
   1400 
   1401 /* Sort the symtab by starting address, and emit warnings if any
   1402    symbols have overlapping address ranges.  We use that old chestnut,
   1403    shellsort.  Mash the table around so as to establish the property
   1404    that addresses are in order and the ranges to not overlap.  This
   1405    facilitates using binary search to map addresses to symbols when we
   1406    come to query the table.
   1407 */
   1408 static Int compare_DiSym ( const void* va, const void* vb )
   1409 {
   1410    const DiSym* a = va;
   1411    const DiSym* b = vb;
   1412    if (a->avmas.main < b->avmas.main) return -1;
   1413    if (a->avmas.main > b->avmas.main) return  1;
   1414    return 0;
   1415 }
   1416 
   1417 
   1418 /* An address is associated with more than one name.  Which do we
   1419    prefer as the "display" name (that we show the user in stack
   1420    traces)?  In order:
   1421 
   1422    - Prefer "PMPI_<foo>" over "MPI_<foo>".
   1423 
   1424    - Else, prefer a non-empty name over an empty one.
   1425 
   1426    - Else, prefer a non-whitespace name over an all-whitespace name.
   1427 
   1428    - Else, prefer the shorter symbol name.  If the symbol contains a
   1429      version symbol ('@' on Linux, other platforms may differ), which means it
   1430      is versioned, then the length up to the version symbol is used for length
   1431      comparison purposes (so "foo (at) GLIBC_2.4.2" is considered shorter than
   1432      "foobar").
   1433 
   1434    - Else, if two symbols have the same length, prefer a versioned symbol over
   1435      a non-versioned symbol.
   1436 
   1437    - Else, use alphabetical ordering.
   1438 
   1439    - Otherwise, they must be the same;  use the name with the lower address.
   1440 
   1441    Very occasionally this goes wrong (eg. 'memcmp' and 'bcmp' are
   1442    aliases in glibc, we choose the 'bcmp' symbol because it's shorter,
   1443    so we can misdescribe memcmp() as bcmp()).  This is hard to avoid.
   1444    It's mentioned in the FAQ file.
   1445 
   1446    Returned value is True if a_name is preferred, False if b_name is
   1447    preferred.
   1448  */
   1449 static
   1450 Bool preferName ( const DebugInfo* di,
   1451                   const HChar* a_name, const HChar* b_name,
   1452                   Addr sym_avma/*exposition only*/ )
   1453 {
   1454    Word cmp;
   1455    Word vlena, vlenb;		/* length without version */
   1456    const HChar *vpa, *vpb;
   1457 
   1458    Bool preferA = False;
   1459    Bool preferB = False;
   1460 
   1461    vg_assert(a_name);
   1462    vg_assert(b_name);
   1463    // vg_assert(a_name != b_name);
   1464    // ???? now the pointers can be equal but is that
   1465    // ???? not the indication of a latent bug ????
   1466 
   1467    vlena = VG_(strlen)(a_name);
   1468    vlenb = VG_(strlen)(b_name);
   1469 
   1470 #  if defined(VGO_linux) || defined(VGO_solaris)
   1471 #    define VERSION_CHAR '@'
   1472 #  elif defined(VGO_darwin)
   1473 #    define VERSION_CHAR '$'
   1474 #  else
   1475 #    error Unknown OS
   1476 #  endif
   1477 
   1478    vpa = VG_(strchr)(a_name, VERSION_CHAR);
   1479    vpb = VG_(strchr)(b_name, VERSION_CHAR);
   1480 
   1481 #  undef VERSION_CHAR
   1482 
   1483    if (vpa)
   1484       vlena = vpa - a_name;
   1485    if (vpb)
   1486       vlenb = vpb - b_name;
   1487 
   1488    /* MPI hack: prefer PMPI_Foo over MPI_Foo */
   1489    if (0==VG_(strncmp)(a_name, "MPI_", 4)
   1490        && 0==VG_(strncmp)(b_name, "PMPI_", 5)
   1491        && 0==VG_(strcmp)(a_name, 1+b_name)) {
   1492       preferB = True; goto out;
   1493    }
   1494    if (0==VG_(strncmp)(b_name, "MPI_", 4)
   1495        && 0==VG_(strncmp)(a_name, "PMPI_", 5)
   1496        && 0==VG_(strcmp)(b_name, 1+a_name)) {
   1497       preferA = True; goto out;
   1498    }
   1499 
   1500    /* Prefer non-empty name. */
   1501    if (vlena  &&  !vlenb) {
   1502       preferA = True; goto out;
   1503    }
   1504    if (vlenb  &&  !vlena) {
   1505       preferB = True; goto out;
   1506    }
   1507 
   1508    /* Prefer non-whitespace name. */
   1509    {
   1510       Bool blankA = True;
   1511       Bool blankB = True;
   1512       const HChar *s;
   1513       s = a_name;
   1514       while (*s) {
   1515          if (!VG_(isspace)(*s++)) {
   1516             blankA = False;
   1517             break;
   1518          }
   1519       }
   1520       s = b_name;
   1521       while (*s) {
   1522          if (!VG_(isspace)(*s++)) {
   1523             blankB = False;
   1524             break;
   1525          }
   1526       }
   1527 
   1528       if (!blankA  &&  blankB) {
   1529          preferA = True; goto out;
   1530       }
   1531       if (!blankB  &&  blankA) {
   1532          preferB = True; goto out;
   1533       }
   1534    }
   1535 
   1536    /* Select the shortest unversioned name */
   1537    if (vlena < vlenb) {
   1538       preferA = True; goto out;
   1539    }
   1540    if (vlenb < vlena) {
   1541       preferB = True; goto out;
   1542    }
   1543 
   1544    /* Equal lengths; select the versioned name */
   1545    if (vpa && !vpb) {
   1546       preferA = True; goto out;
   1547    }
   1548    if (vpb && !vpa) {
   1549       preferB = True; goto out;
   1550    }
   1551 
   1552    /* Either both versioned or neither is versioned; select them
   1553       alphabetically */
   1554    cmp = VG_(strcmp)(a_name, b_name);
   1555    if (cmp < 0) {
   1556       preferA = True; goto out;
   1557    }
   1558    if (cmp > 0) {
   1559       preferB = True; goto out;
   1560    }
   1561 
   1562    /* If we get here, they are the same name. */
   1563 
   1564    /* In this case we could choose either (arbitrarily), but might as
   1565       well choose the one with the lowest DiSym* address, so as to try
   1566       and make the comparison mechanism more stable (a la sorting
   1567       parlance).  Also, skip the diagnostic printing in this case. */
   1568    return a_name <= b_name  ? True  : False;
   1569 
   1570    /*NOTREACHED*/
   1571    vg_assert(0);
   1572   out:
   1573    if (preferA && !preferB) {
   1574       TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n",
   1575                    sym_avma, a_name, b_name );
   1576       return True;
   1577    }
   1578    if (preferB && !preferA) {
   1579       TRACE_SYMTAB("sym at %#lx: prefer '%s' to '%s'\n",
   1580                    sym_avma, b_name, a_name );
   1581       return False;
   1582    }
   1583    /*NOTREACHED*/
   1584    vg_assert(0);
   1585 }
   1586 
   1587 
   1588 /* Add the names in FROM to the names in TO. */
   1589 static
   1590 void add_DiSym_names_to_from ( const DebugInfo* di, DiSym* to,
   1591                                const DiSym* from )
   1592 {
   1593    vg_assert(to->pri_name);
   1594    vg_assert(from->pri_name);
   1595    /* Figure out how many names there will be in the new combined
   1596       secondary vector. */
   1597    const HChar** to_sec   = to->sec_names;
   1598    const HChar** from_sec = from->sec_names;
   1599    Word n_new_sec = 1;
   1600    if (from_sec) {
   1601       while (*from_sec) {
   1602          n_new_sec++;
   1603          from_sec++;
   1604       }
   1605    }
   1606    if (to_sec) {
   1607       while (*to_sec) {
   1608          n_new_sec++;
   1609          to_sec++;
   1610       }
   1611    }
   1612    if (0)
   1613       TRACE_SYMTAB("merge: -> %ld\n", n_new_sec);
   1614    /* Create the new sec and copy stuff into it, putting the new
   1615       entries at the end. */
   1616    const HChar** new_sec = ML_(dinfo_zalloc)( "di.storage.aDntf.1",
   1617                                               (n_new_sec+1) * sizeof(HChar*) );
   1618    from_sec = from->sec_names;
   1619    to_sec   = to->sec_names;
   1620    Word i = 0;
   1621    if (to_sec) {
   1622       while (*to_sec) {
   1623          new_sec[i++] = *to_sec;
   1624          to_sec++;
   1625       }
   1626    }
   1627    new_sec[i++] = from->pri_name;
   1628    if (from_sec) {
   1629       while (*from_sec) {
   1630          new_sec[i++] = *from_sec;
   1631          from_sec++;
   1632       }
   1633    }
   1634    vg_assert(i == n_new_sec);
   1635    vg_assert(new_sec[i] == NULL);
   1636    /* If we're replacing an existing secondary vector, free it. */
   1637    if (to->sec_names) {
   1638       ML_(dinfo_free)(to->sec_names);
   1639    }
   1640    to->sec_names = new_sec;
   1641 }
   1642 
   1643 
   1644 static void canonicaliseSymtab ( struct _DebugInfo* di )
   1645 {
   1646    Word  i, j, n_truncated;
   1647    Addr  sta1, sta2, end1, end2, toc1, toc2;
   1648    const HChar *pri1, *pri2, **sec1, **sec2;
   1649    Bool  ist1, ist2, isf1, isf2;
   1650 
   1651 #  define SWAP(ty,aa,bb) \
   1652       do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0)
   1653 
   1654    if (di->symtab_used == 0)
   1655       return;
   1656 
   1657    /* Check initial invariants */
   1658    for (i = 0; i < di->symtab_used; i++) {
   1659       DiSym* sym = &di->symtab[i];
   1660       vg_assert(sym->pri_name);
   1661       vg_assert(!sym->sec_names);
   1662    }
   1663 
   1664    /* Sort by address. */
   1665    VG_(ssort)(di->symtab, di->symtab_used,
   1666                           sizeof(*di->symtab), compare_DiSym);
   1667 
   1668   cleanup_more:
   1669 
   1670    /* BEGIN Detect and "fix" identical address ranges. */
   1671    while (1) {
   1672       Word r, w, n_merged;
   1673       n_merged = 0;
   1674       w = 0;
   1675       /* A pass merging entries together in the case where they agree
   1676          on .isText -- that is, either: both are .isText or both are
   1677          not .isText.  They are merged into a single entry, but both
   1678          sets of names are preserved, so we end up knowing all the
   1679          names for that particular address range.*/
   1680       for (r = 1; r < di->symtab_used; r++) {
   1681          vg_assert(w < r);
   1682          if (   di->symtab[w].avmas.main == di->symtab[r].avmas.main
   1683              && di->symtab[w].size       == di->symtab[r].size
   1684              && !!di->symtab[w].isText   == !!di->symtab[r].isText) {
   1685             /* merge the two into one */
   1686             n_merged++;
   1687             /* Add r names to w if r has secondary names
   1688                or r and w primary names differ. */
   1689             if (di->symtab[r].sec_names
   1690                 || (0 != VG_(strcmp)(di->symtab[r].pri_name,
   1691                                      di->symtab[w].pri_name))) {
   1692                add_DiSym_names_to_from(di, &di->symtab[w], &di->symtab[r]);
   1693             }
   1694             /* mark w as an IFunc if either w or r are */
   1695             di->symtab[w].isIFunc = di->symtab[w].isIFunc || di->symtab[r].isIFunc;
   1696             /* and use ::pri_names to indicate this slot is no longer in use */
   1697             di->symtab[r].pri_name = NULL;
   1698             if (di->symtab[r].sec_names) {
   1699                ML_(dinfo_free)(di->symtab[r].sec_names);
   1700                di->symtab[r].sec_names = NULL;
   1701             }
   1702             /* Completely zap the entry -- paranoia to make it more
   1703                likely we'll notice if we inadvertantly use it
   1704                again. */
   1705             VG_(memset)(&di->symtab[r], 0, sizeof(DiSym));
   1706          } else {
   1707             w = r;
   1708          }
   1709       }
   1710 
   1711       /* A second pass merging entries together where one .isText but
   1712          the other isn't.  In such cases, just ignore the non-.isText
   1713          one (a heuristic hack.) */
   1714       for (r = 1; r < di->symtab_used; r++) {
   1715          /* Either of the symbols might already have been zapped by
   1716             the previous pass, so we first have to check that. */
   1717          if (di->symtab[r-1].pri_name == NULL) continue;
   1718          if (di->symtab[r-0].pri_name == NULL) continue;
   1719          /* ok, they are both still valid.  Identical address ranges? */
   1720          if (di->symtab[r-1].avmas.main != di->symtab[r-0].avmas.main) continue;
   1721          if (di->symtab[r-1].size       != di->symtab[r-0].size) continue;
   1722          /* Identical address ranges.  They must disagree on .isText
   1723             since if they agreed, the previous pass would have merged
   1724             them. */
   1725          if (di->symtab[r-1].isText && di->symtab[r-0].isText) vg_assert(0);
   1726          if (!di->symtab[r-1].isText && !di->symtab[r-0].isText) vg_assert(0);
   1727          Word to_zap  = di->symtab[r-1].isText ? (r-0) : (r-1);
   1728          Word to_keep = di->symtab[r-1].isText ? (r-1) : (r-0);
   1729          vg_assert(!di->symtab[to_zap].isText);
   1730          vg_assert(di->symtab[to_keep].isText);
   1731          /* Add to_zap's names to to_keep if to_zap has secondary names
   1732             or to_zap's and to_keep's primary names differ. */
   1733          if (di->symtab[to_zap].sec_names
   1734              || (0 != VG_(strcmp)(di->symtab[to_zap].pri_name,
   1735                                   di->symtab[to_keep].pri_name))) {
   1736             add_DiSym_names_to_from(di, &di->symtab[to_keep],
   1737                                         &di->symtab[to_zap]);
   1738          }
   1739          /* Mark to_zap as not-in use in the same way as in the
   1740             previous loop. */
   1741          di->symtab[to_zap].pri_name = NULL;
   1742          if (di->symtab[to_zap].sec_names) {
   1743             ML_(dinfo_free)(di->symtab[to_zap].sec_names);
   1744             di->symtab[to_zap].sec_names = NULL;
   1745          }
   1746          VG_(memset)(&di->symtab[to_zap], 0, sizeof(DiSym));
   1747          n_merged++;
   1748       }
   1749 
   1750       TRACE_SYMTAB( "canonicaliseSymtab: %ld symbols merged\n", n_merged);
   1751       if (n_merged == 0)
   1752          break;
   1753       /* Now a pass to squeeze out any unused ones */
   1754       w = 0;
   1755       for (r = 0; r < di->symtab_used; r++) {
   1756          vg_assert(w <= r);
   1757          if (di->symtab[r].pri_name == NULL)
   1758             continue;
   1759          if (w < r) {
   1760             di->symtab[w] = di->symtab[r];
   1761          }
   1762          w++;
   1763       }
   1764       vg_assert(w + n_merged == di->symtab_used);
   1765       di->symtab_used = w;
   1766    } /* while (1) */
   1767    /* END Detect and "fix" identical address ranges. */
   1768 
   1769    /* BEGIN Detect and "fix" overlapping address ranges. */
   1770    n_truncated = 0;
   1771 
   1772    for (i = 0; i < ((Word)di->symtab_used) -1; i++) {
   1773 
   1774       vg_assert(di->symtab[i].avmas.main <= di->symtab[i+1].avmas.main);
   1775 
   1776       /* Check for common (no overlap) case. */
   1777       if (di->symtab[i].avmas.main + di->symtab[i].size
   1778           <= di->symtab[i+1].avmas.main)
   1779          continue;
   1780 
   1781       /* There's an overlap.  Truncate one or the other. */
   1782       if (di->trace_symtab) {
   1783          VG_(printf)("overlapping address ranges in symbol table\n\t");
   1784          ML_(ppSym)( i, &di->symtab[i] );
   1785          VG_(printf)("\t");
   1786          ML_(ppSym)( i+1, &di->symtab[i+1] );
   1787          VG_(printf)("\n");
   1788       }
   1789 
   1790       /* Truncate one or the other. */
   1791       sta1 = di->symtab[i].avmas.main;
   1792       end1 = sta1 + di->symtab[i].size - 1;
   1793       toc1 = GET_TOCPTR_AVMA(di->symtab[i].avmas);
   1794       // aren't we missing local_ep here ????
   1795       pri1 = di->symtab[i].pri_name;
   1796       sec1 = di->symtab[i].sec_names;
   1797       ist1 = di->symtab[i].isText;
   1798       isf1 = di->symtab[i].isIFunc;
   1799 
   1800       sta2 = di->symtab[i+1].avmas.main;
   1801       end2 = sta2 + di->symtab[i+1].size - 1;
   1802       toc2 = GET_TOCPTR_AVMA(di->symtab[i+1].avmas);
   1803       // aren't we missing local_ep here ????
   1804       pri2 = di->symtab[i+1].pri_name;
   1805       sec2 = di->symtab[i+1].sec_names;
   1806       ist2 = di->symtab[i+1].isText;
   1807       isf2 = di->symtab[i+1].isIFunc;
   1808 
   1809       if (sta1 < sta2) {
   1810          end1 = sta2 - 1;
   1811       } else {
   1812          vg_assert(sta1 == sta2);
   1813          if (end1 > end2) {
   1814             sta1 = end2 + 1;
   1815             SWAP(Addr,sta1,sta2); SWAP(Addr,end1,end2); SWAP(Addr,toc1,toc2);
   1816             SWAP(const HChar*,pri1,pri2); SWAP(const HChar**,sec1,sec2);
   1817             SWAP(Bool,ist1,ist2); SWAP(Bool,isf1,isf2);
   1818          } else
   1819          if (end1 < end2) {
   1820             sta2 = end1 + 1;
   1821          } else {
   1822 	   /* end1 == end2.  Identical addr ranges.  We'll eventually wind
   1823               up back at cleanup_more, which will take care of it. */
   1824 	 }
   1825       }
   1826       di->symtab[i].avmas.main = sta1;
   1827       di->symtab[i].size       = end1 - sta1 + 1;
   1828       SET_TOCPTR_AVMA(di->symtab[i].avmas, toc1);
   1829       // missing local_ep ???
   1830       di->symtab[i].pri_name  = pri1;
   1831       di->symtab[i].sec_names = sec1;
   1832       di->symtab[i].isText    = ist1;
   1833       di->symtab[i].isIFunc   = isf1;
   1834 
   1835       di->symtab[i+1].avmas.main = sta2;
   1836       di->symtab[i+1].size       = end2 - sta2 + 1;
   1837       SET_TOCPTR_AVMA(di->symtab[i+1].avmas, toc2);
   1838       // missing local_ep ???
   1839       di->symtab[i+1].pri_name  = pri2;
   1840       di->symtab[i+1].sec_names = sec2;
   1841       di->symtab[i+1].isText    = ist2;
   1842       di->symtab[i+1].isIFunc   = isf2;
   1843 
   1844       vg_assert(sta1 <= sta2);
   1845       vg_assert(di->symtab[i].size > 0);
   1846       vg_assert(di->symtab[i+1].size > 0);
   1847       /* It may be that the i+1 entry now needs to be moved further
   1848          along to maintain the address order requirement. */
   1849       j = i+1;
   1850       while (j < ((Word)di->symtab_used)-1
   1851              && di->symtab[j].avmas.main > di->symtab[j+1].avmas.main) {
   1852          SWAP(DiSym,di->symtab[j],di->symtab[j+1]);
   1853          j++;
   1854       }
   1855       n_truncated++;
   1856    }
   1857    /* END Detect and "fix" overlapping address ranges. */
   1858 
   1859    if (n_truncated > 0) goto cleanup_more;
   1860 
   1861    /* Ensure relevant postconditions hold. */
   1862    for (i = 0; i < ((Word)di->symtab_used)-1; i++) {
   1863       /* No zero-sized symbols. */
   1864       vg_assert(di->symtab[i].size > 0);
   1865       /* In order. */
   1866       vg_assert(di->symtab[i].avmas.main < di->symtab[i+1].avmas.main);
   1867       /* No overlaps. */
   1868       vg_assert(di->symtab[i].avmas.main + di->symtab[i].size - 1
   1869                 < di->symtab[i+1].avmas.main);
   1870       /* Names are sane(ish) */
   1871       vg_assert(di->symtab[i].pri_name);
   1872       if (di->symtab[i].sec_names) {
   1873          vg_assert(di->symtab[i].sec_names[0]);
   1874       }
   1875    }
   1876 
   1877    /* For each symbol that has more than one name, use preferName to
   1878       select the primary name.  This is a complete kludge in that
   1879       doing it properly requires making a total ordering on the
   1880       candidate names, whilst what we have to work with is an ad-hoc
   1881       binary relation (preferName) that certainly doesn't have the
   1882       relevant transitivity etc properties that are needed to induce a
   1883       legitimate total order.  Doesn't matter though if it doesn't
   1884       always work right since this is only used to generate names to
   1885       show the user. */
   1886    for (i = 0; i < ((Word)di->symtab_used)-1; i++) {
   1887       DiSym*  sym = &di->symtab[i];
   1888       const HChar** sec = sym->sec_names;
   1889       if (!sec)
   1890          continue;
   1891       /* Slow but simple.  Copy all the cands into a temp array,
   1892          choose the primary name, and copy them all back again. */
   1893       Word n_tmp = 1;
   1894       while (*sec) { n_tmp++; sec++; }
   1895       j = 0;
   1896       const HChar** tmp = ML_(dinfo_zalloc)( "di.storage.cS.1",
   1897                                              (n_tmp+1) * sizeof(HChar*) );
   1898       tmp[j++] = sym->pri_name;
   1899       sec = sym->sec_names;
   1900       while (*sec) { tmp[j++] = *sec; sec++; }
   1901       vg_assert(j == n_tmp);
   1902       vg_assert(tmp[n_tmp] == NULL); /* because of zalloc */
   1903       /* Choose the most favoured. */
   1904       Word best = 0;
   1905       for (j = 1; j < n_tmp; j++) {
   1906          if (preferName(di, tmp[best], tmp[j], di->symtab[i].avmas.main)) {
   1907             /* best is unchanged */
   1908          } else {
   1909             best = j;
   1910          }
   1911       }
   1912       vg_assert(best >= 0 && best < n_tmp);
   1913       /* Copy back */
   1914       sym->pri_name = tmp[best];
   1915       const HChar** cursor = sym->sec_names;
   1916       for (j = 0; j < n_tmp; j++) {
   1917          if (j == best)
   1918             continue;
   1919          *cursor = tmp[j];
   1920          cursor++;
   1921       }
   1922       vg_assert(*cursor == NULL);
   1923       ML_(dinfo_free)( tmp );
   1924    }
   1925 
   1926 #  undef SWAP
   1927 }
   1928 
   1929 
   1930 static DiLoc* sorting_loctab = NULL;
   1931 static Int compare_DiLoc_via_ix ( const void* va, const void* vb )
   1932 {
   1933    const DiLoc* a = &sorting_loctab[*(const UInt*)va];
   1934    const DiLoc* b = &sorting_loctab[*(const UInt*)vb];
   1935    if (a->addr < b->addr) return -1;
   1936    if (a->addr > b->addr) return  1;
   1937    return 0;
   1938 }
   1939 static void sort_loctab_and_loctab_fndn_ix (struct _DebugInfo* di )
   1940 {
   1941    /* We have to sort the array loctab by addr
   1942       together with its "parallel" array loctab_fndn_ix.
   1943       We first build sort_ix : an array of indexes in loctab,
   1944       that we sort by loctab address. Then we can reorder both
   1945       arrays according to sort_ix. */
   1946    UInt *sort_ix = ML_(dinfo_zalloc)("di.storage.six",
   1947                                      di->loctab_used*sizeof(UInt));
   1948    Word i, j, k;
   1949 
   1950    for (i = 0; i < di->loctab_used; i++) sort_ix[i] = i;
   1951    sorting_loctab = di->loctab;
   1952    VG_(ssort)(sort_ix, di->loctab_used,
   1953               sizeof(*sort_ix), compare_DiLoc_via_ix);
   1954    sorting_loctab = NULL;
   1955 
   1956    // Permute in place, using the sort_ix.
   1957    for (i=0; i < di->loctab_used; i++) {
   1958       DiLoc tmp_diloc;
   1959       UInt  tmp_fndn_ix;
   1960 
   1961       if (i == sort_ix[i])
   1962          continue; // i already at the good place
   1963 
   1964       tmp_diloc = di->loctab[i];
   1965       tmp_fndn_ix = ML_(fndn_ix)(di, i);
   1966       j = i;
   1967       for (;;) {
   1968          k = sort_ix[j];
   1969          sort_ix[j] = j;
   1970          if (k == i)
   1971             break;
   1972          di->loctab[j] = di->loctab[k];
   1973          set_fndn_ix (di, j, ML_(fndn_ix)(di, k));
   1974          j = k;
   1975       }
   1976       di->loctab[j] = tmp_diloc;
   1977       set_fndn_ix (di, j, tmp_fndn_ix);
   1978    }
   1979    ML_(dinfo_free)(sort_ix);
   1980 }
   1981 
   1982 /* Sort the location table by starting address.  Mash the table around
   1983    so as to establish the property that addresses are in order and the
   1984    ranges do not overlap.  This facilitates using binary search to map
   1985    addresses to locations when we come to query the table.
   1986 */
   1987 static void canonicaliseLoctab ( struct _DebugInfo* di )
   1988 {
   1989    Word i, j;
   1990 
   1991    if (di->loctab_used == 0)
   1992       return;
   1993 
   1994    /* sort loctab and loctab_fndn_ix by addr. */
   1995    sort_loctab_and_loctab_fndn_ix (di);
   1996 
   1997    /* If two adjacent entries overlap, truncate the first. */
   1998    for (i = 0; i < ((Word)di->loctab_used)-1; i++) {
   1999       vg_assert(di->loctab[i].size < 10000);
   2000       if (di->loctab[i].addr + di->loctab[i].size > di->loctab[i+1].addr) {
   2001          /* Do this in signed int32 because the actual .size fields
   2002             are only 12 bits. */
   2003          Int new_size = di->loctab[i+1].addr - di->loctab[i].addr;
   2004          if (new_size < 0) {
   2005             di->loctab[i].size = 0;
   2006          } else
   2007          if (new_size > MAX_LOC_SIZE) {
   2008            di->loctab[i].size = MAX_LOC_SIZE;
   2009          } else {
   2010            di->loctab[i].size = (UShort)new_size;
   2011          }
   2012       }
   2013    }
   2014 
   2015    /* Zap any zero-sized entries resulting from the truncation
   2016       process. */
   2017    j = 0;
   2018    for (i = 0; i < (Word)di->loctab_used; i++) {
   2019       if (di->loctab[i].size > 0) {
   2020          if (j != i) {
   2021             di->loctab[j] = di->loctab[i];
   2022             set_fndn_ix(di, j, ML_(fndn_ix)(di, i));
   2023          }
   2024          j++;
   2025       }
   2026    }
   2027    di->loctab_used = j;
   2028 
   2029    /* Ensure relevant postconditions hold. */
   2030    for (i = 0; i < ((Word)di->loctab_used)-1; i++) {
   2031       if (0)
   2032          VG_(printf)("%ld  0x%p  lno:%d sz:%d fndn_ix:%u  i+1 0x%p\n",
   2033                      i,
   2034                      (void*)di->loctab[i].addr,
   2035                      di->loctab[i].lineno,
   2036                      di->loctab[i].size,
   2037                      ML_(fndn_ix)(di, i),
   2038                      (void*)di->loctab[i+1].addr);
   2039 
   2040       /* No zero-sized symbols. */
   2041       vg_assert(di->loctab[i].size > 0);
   2042       /* In order. */
   2043       vg_assert(di->loctab[i].addr < di->loctab[i+1].addr);
   2044       /* No overlaps. */
   2045       vg_assert(di->loctab[i].addr + di->loctab[i].size - 1
   2046                 < di->loctab[i+1].addr);
   2047    }
   2048 
   2049    /* Free up unused space at the end of the table. */
   2050    shrinkLocTab(di);
   2051 }
   2052 
   2053 /* Sort the inlined call table by starting address.  Mash the table around
   2054    so as to establish the property that addresses are in order.
   2055    This facilitates using binary search to map addresses to locations when
   2056    we come to query the table.
   2057    Note : ranges can overlap, multiple ranges can start at an address,
   2058    multiple ranges can end at an address.
   2059 */
   2060 static Int compare_DiInlLoc ( const void* va, const void* vb )
   2061 {
   2062    const DiInlLoc* a = va;
   2063    const DiInlLoc* b = vb;
   2064    if (a->addr_lo < b->addr_lo) return -1;
   2065    if (a->addr_lo > b->addr_lo) return  1;
   2066    return 0;
   2067 }
   2068 
   2069 static void canonicaliseInltab ( struct _DebugInfo* di )
   2070 {
   2071    Word i;
   2072 
   2073    if (di->inltab_used == 0)
   2074       return;
   2075 
   2076    /* Sort by start address. */
   2077    VG_(ssort)(di->inltab, di->inltab_used,
   2078                           sizeof(*di->inltab), compare_DiInlLoc);
   2079 
   2080    /* Ensure relevant postconditions hold. */
   2081    for (i = 0; i < ((Word)di->inltab_used)-1; i++) {
   2082       /* No zero-sized inlined call. */
   2083       vg_assert(di->inltab[i].addr_lo < di->inltab[i].addr_hi);
   2084       /* In order, but we can have duplicates and overlapping ranges. */
   2085       vg_assert(di->inltab[i].addr_lo <= di->inltab[i+1].addr_lo);
   2086    }
   2087 
   2088    /* Free up unused space at the end of the table. */
   2089    shrinkInlTab(di);
   2090 }
   2091 
   2092 
   2093 /* Sort the call-frame-info cfsi_rd by starting address.  Mash the table
   2094    around so as to establish the property that addresses are in order
   2095    and the ranges do not overlap.  This facilitates using binary
   2096    search to map addresses to locations when we come to query the
   2097    table.
   2098 
   2099    Also, set cfisi_minaddr and cfisi_maxaddr to be the min and max of
   2100    any of the address ranges contained in cfisi[0 .. cfisi_used-1], so
   2101    as to facilitate rapidly skipping this SegInfo when looking for an
   2102    address which falls outside that range.
   2103 */
   2104 static Int compare_DiCfSI ( const void* va, const void* vb )
   2105 {
   2106    const DiCfSI* a = va;
   2107    const DiCfSI* b = vb;
   2108    if (a->base < b->base) return -1;
   2109    if (a->base > b->base) return  1;
   2110    return 0;
   2111 }
   2112 
   2113 static void get_cfsi_rd_stats ( const DebugInfo* di,
   2114                                 UWord *n_mergeables, UWord *n_holes )
   2115 {
   2116    Word i;
   2117 
   2118    *n_mergeables = 0;
   2119    *n_holes = 0;
   2120 
   2121    vg_assert (di->cfsi_used == 0 || di->cfsi_rd);
   2122    for (i = 1; i < (Word)di->cfsi_used; i++) {
   2123       Addr here_min = di->cfsi_rd[i].base;
   2124       Addr prev_max = di->cfsi_rd[i-1].base + di->cfsi_rd[i-1].len - 1;
   2125       Addr sep = here_min - prev_max;
   2126       if (sep > 1)
   2127          (*n_holes)++;
   2128       if (sep == 1 && di->cfsi_rd[i-1].cfsi_m_ix == di->cfsi_rd[i].cfsi_m_ix)
   2129          (*n_mergeables)++;
   2130    }
   2131 }
   2132 
   2133 void ML_(canonicaliseCFI) ( struct _DebugInfo* di )
   2134 {
   2135    Word  i, j;
   2136    const Addr minAvma = 0;
   2137    const Addr maxAvma = ~minAvma;
   2138 
   2139    /* Note: take care in here.  di->cfsi can be NULL, in which
   2140       case _used and _size fields will be zero. */
   2141    if (di->cfsi_rd == NULL) {
   2142       vg_assert(di->cfsi_used == 0);
   2143       vg_assert(di->cfsi_size == 0);
   2144       vg_assert(di->cfsi_m_pool == NULL);
   2145    } else {
   2146       vg_assert(di->cfsi_size != 0);
   2147       vg_assert(di->cfsi_m_pool != NULL);
   2148    }
   2149 
   2150    /* Set cfsi_minavma and cfsi_maxavma to summarise the entire
   2151       address range contained in cfsi_rd[0 .. cfsi_used-1]. */
   2152    di->cfsi_minavma = maxAvma;
   2153    di->cfsi_maxavma = minAvma;
   2154    for (i = 0; i < (Word)di->cfsi_used; i++) {
   2155       Addr here_min = di->cfsi_rd[i].base;
   2156       Addr here_max = di->cfsi_rd[i].base + di->cfsi_rd[i].len - 1;
   2157       if (here_min < di->cfsi_minavma)
   2158          di->cfsi_minavma = here_min;
   2159       if (here_max > di->cfsi_maxavma)
   2160          di->cfsi_maxavma = here_max;
   2161    }
   2162 
   2163    if (di->trace_cfi)
   2164       VG_(printf)("canonicaliseCfiSI: %lu entries, %#lx .. %#lx\n",
   2165                   di->cfsi_used,
   2166                   di->cfsi_minavma, di->cfsi_maxavma);
   2167 
   2168    /* Sort the cfsi_rd array by base address. */
   2169    VG_(ssort)(di->cfsi_rd, di->cfsi_used, sizeof(*di->cfsi_rd), compare_DiCfSI);
   2170 
   2171    /* If two adjacent entries overlap, truncate the first. */
   2172    for (i = 0; i < (Word)di->cfsi_used-1; i++) {
   2173       if (di->cfsi_rd[i].base + di->cfsi_rd[i].len > di->cfsi_rd[i+1].base) {
   2174          Word new_len = di->cfsi_rd[i+1].base - di->cfsi_rd[i].base;
   2175          /* how could it be otherwise?  The entries are sorted by the
   2176             .base field. */
   2177          vg_assert(new_len >= 0);
   2178 	 vg_assert(new_len <= di->cfsi_rd[i].len);
   2179          di->cfsi_rd[i].len = new_len;
   2180       }
   2181    }
   2182 
   2183    /* Zap any zero-sized entries resulting from the truncation
   2184       process. */
   2185    j = 0;
   2186    for (i = 0; i < (Word)di->cfsi_used; i++) {
   2187       if (di->cfsi_rd[i].len > 0) {
   2188          if (j != i)
   2189             di->cfsi_rd[j] = di->cfsi_rd[i];
   2190          j++;
   2191       }
   2192    }
   2193    /* VG_(printf)("XXXXXXXXXXXXX %d %d\n", di->cfsi_used, j); */
   2194    di->cfsi_used = j;
   2195 
   2196    /* Ensure relevant postconditions hold. */
   2197    for (i = 0; i < (Word)di->cfsi_used; i++) {
   2198       /* No zero-length ranges. */
   2199       vg_assert(di->cfsi_rd[i].len > 0);
   2200       /* Makes sense w.r.t. summary address range */
   2201       vg_assert(di->cfsi_rd[i].base >= di->cfsi_minavma);
   2202       vg_assert(di->cfsi_rd[i].base + di->cfsi_rd[i].len - 1
   2203                 <= di->cfsi_maxavma);
   2204 
   2205       if (i < di->cfsi_used - 1) {
   2206          /*
   2207          if (!(di->cfsi[i].base < di->cfsi[i+1].base)) {
   2208             VG_(printf)("\nOOO cfsis:\n");
   2209             ML_(ppCfiSI)(&di->cfsi[i]);
   2210             ML_(ppCfiSI)(&di->cfsi[i+1]);
   2211          }
   2212          */
   2213          /* In order. */
   2214          vg_assert(di->cfsi_rd[i].base < di->cfsi_rd[i+1].base);
   2215          /* No overlaps. */
   2216          vg_assert(di->cfsi_rd[i].base + di->cfsi_rd[i].len - 1
   2217                    < di->cfsi_rd[i+1].base);
   2218       }
   2219    }
   2220 
   2221    if (VG_(clo_stats) && VG_(clo_verbosity) >= 3) {
   2222       UWord n_mergeables, n_holes;
   2223       get_cfsi_rd_stats (di, &n_mergeables, &n_holes);
   2224       VG_(dmsg)("CFSI total %lu mergeables %lu holes %lu uniq cfsi_m %u\n",
   2225                 di->cfsi_used, n_mergeables, n_holes,
   2226                 di->cfsi_m_pool ? VG_(sizeDedupPA) (di->cfsi_m_pool) : 0);
   2227    }
   2228 }
   2229 
   2230 void ML_(finish_CFSI_arrays) ( struct _DebugInfo* di )
   2231 {
   2232    UWord n_mergeables, n_holes;
   2233    UWord new_used;
   2234    UWord i;
   2235    UWord pos;
   2236    UWord f_mergeables, f_holes;
   2237    UInt sz_cfsi_m_pool;
   2238 
   2239    get_cfsi_rd_stats (di, &n_mergeables, &n_holes);
   2240 
   2241    if (di->cfsi_used == 0) {
   2242       vg_assert (di->cfsi_rd == NULL);
   2243       vg_assert (di->cfsi_m_pool == NULL);
   2244       vg_assert (n_mergeables == 0);
   2245       vg_assert (n_holes == 0);
   2246       return;
   2247    }
   2248 
   2249    vg_assert (di->cfsi_used > n_mergeables);
   2250    new_used = di->cfsi_used - n_mergeables + n_holes;
   2251 
   2252    sz_cfsi_m_pool = VG_(sizeDedupPA)(di->cfsi_m_pool);
   2253    vg_assert (sz_cfsi_m_pool > 0);
   2254    if (sz_cfsi_m_pool <= 255)
   2255       di->sizeof_cfsi_m_ix = 1;
   2256    else if (sz_cfsi_m_pool <= 65535)
   2257       di->sizeof_cfsi_m_ix = 2;
   2258    else
   2259       di->sizeof_cfsi_m_ix = 4;
   2260 
   2261    di->cfsi_base = ML_(dinfo_zalloc)( "di.storage.finCfSI.1",
   2262                                        new_used * sizeof(Addr) );
   2263    di->cfsi_m_ix = ML_(dinfo_zalloc)( "di.storage.finCfSI.2",
   2264                                       new_used * sizeof(UChar)*di->sizeof_cfsi_m_ix);
   2265 
   2266    pos = 0;
   2267    f_mergeables = 0;
   2268    f_holes = 0;
   2269    for (i = 0; i < (Word)di->cfsi_used; i++) {
   2270       if (i > 0) {
   2271          Addr here_min = di->cfsi_rd[i].base;
   2272          Addr prev_max = di->cfsi_rd[i-1].base + di->cfsi_rd[i-1].len - 1;
   2273          SizeT sep = here_min - prev_max;
   2274 
   2275          // Skip a mergeable entry.
   2276          if (sep == 1) {
   2277             if (di->cfsi_rd[i-1].cfsi_m_ix == di->cfsi_rd[i].cfsi_m_ix) {
   2278                f_mergeables++;
   2279                continue;
   2280             }
   2281          }
   2282          // Insert a hole if needed.
   2283          if (sep > 1) {
   2284             f_holes++;
   2285             di->cfsi_base[pos] = prev_max + 1;
   2286             switch (di->sizeof_cfsi_m_ix) {
   2287                case 1: ((UChar*) di->cfsi_m_ix)[pos] = 0; break;
   2288                case 2: ((UShort*)di->cfsi_m_ix)[pos] = 0; break;
   2289                case 4: ((UInt*)  di->cfsi_m_ix)[pos] = 0; break;
   2290                default: vg_assert(0);
   2291             }
   2292             pos++;
   2293          }
   2294       }
   2295 
   2296       // Insert the cfsi entry i.
   2297       di->cfsi_base[pos] = di->cfsi_rd[i].base;
   2298       switch (di->sizeof_cfsi_m_ix) {
   2299          case 1: ((UChar*) di->cfsi_m_ix)[pos] = di->cfsi_rd[i].cfsi_m_ix; break;
   2300          case 2: ((UShort*)di->cfsi_m_ix)[pos] = di->cfsi_rd[i].cfsi_m_ix; break;
   2301          case 4: ((UInt*)  di->cfsi_m_ix)[pos] = di->cfsi_rd[i].cfsi_m_ix; break;
   2302          default: vg_assert(0);
   2303       }
   2304       pos++;
   2305    }
   2306 
   2307    vg_assert (f_mergeables == n_mergeables);
   2308    vg_assert (f_holes == n_holes);
   2309    vg_assert (pos == new_used);
   2310 
   2311    di->cfsi_used = new_used;
   2312    di->cfsi_size = new_used;
   2313    ML_(dinfo_free) (di->cfsi_rd);
   2314    di->cfsi_rd = NULL;
   2315 }
   2316 
   2317 
   2318 /* Canonicalise the tables held by 'di', in preparation for use.  Call
   2319    this after finishing adding entries to these tables. */
   2320 void ML_(canonicaliseTables) ( struct _DebugInfo* di )
   2321 {
   2322    canonicaliseSymtab ( di );
   2323    canonicaliseLoctab ( di );
   2324    canonicaliseInltab ( di );
   2325    ML_(canonicaliseCFI) ( di );
   2326    if (di->cfsi_m_pool)
   2327       VG_(freezeDedupPA) (di->cfsi_m_pool, ML_(dinfo_shrink_block));
   2328    canonicaliseVarInfo ( di );
   2329    if (di->strpool)
   2330       VG_(freezeDedupPA) (di->strpool, ML_(dinfo_shrink_block));
   2331    if (di->fndnpool)
   2332       VG_(freezeDedupPA) (di->fndnpool, ML_(dinfo_shrink_block));
   2333 }
   2334 
   2335 
   2336 /*------------------------------------------------------------*/
   2337 /*--- Searching the tables                                 ---*/
   2338 /*------------------------------------------------------------*/
   2339 
   2340 /* Find a symbol-table index containing the specified pointer, or -1
   2341    if not found.  Binary search.  */
   2342 
   2343 Word ML_(search_one_symtab) ( const DebugInfo* di, Addr ptr,
   2344                               Bool match_anywhere_in_sym,
   2345                               Bool findText )
   2346 {
   2347    Addr a_mid_lo, a_mid_hi;
   2348    Word mid, size,
   2349         lo = 0,
   2350         hi = di->symtab_used-1;
   2351    while (True) {
   2352       /* current unsearched space is from lo to hi, inclusive. */
   2353       if (lo > hi) return -1; /* not found */
   2354       mid      = (lo + hi) / 2;
   2355       a_mid_lo = di->symtab[mid].avmas.main;
   2356       size = ( match_anywhere_in_sym
   2357              ? di->symtab[mid].size
   2358              : 1);
   2359       a_mid_hi = ((Addr)di->symtab[mid].avmas.main) + size - 1;
   2360 
   2361       if (ptr < a_mid_lo) { hi = mid-1; continue; }
   2362       if (ptr > a_mid_hi) { lo = mid+1; continue; }
   2363       vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
   2364       /* Found a symbol with the correct address range.  But is it
   2365          of the right kind (text vs data) ? */
   2366       if (  findText   &&   di->symtab[mid].isText  ) return mid;
   2367       if ( (!findText) && (!di->symtab[mid].isText) ) return mid;
   2368       return -1;
   2369    }
   2370 }
   2371 
   2372 
   2373 /* Find a location-table index containing the specified pointer, or -1
   2374    if not found.  Binary search.  */
   2375 
   2376 Word ML_(search_one_loctab) ( const DebugInfo* di, Addr ptr )
   2377 {
   2378    Addr a_mid_lo, a_mid_hi;
   2379    Word mid,
   2380         lo = 0,
   2381         hi = di->loctab_used-1;
   2382    while (True) {
   2383       /* current unsearched space is from lo to hi, inclusive. */
   2384       if (lo > hi) return -1; /* not found */
   2385       mid      = (lo + hi) / 2;
   2386       a_mid_lo = di->loctab[mid].addr;
   2387       a_mid_hi = ((Addr)di->loctab[mid].addr) + di->loctab[mid].size - 1;
   2388 
   2389       if (ptr < a_mid_lo) { hi = mid-1; continue; }
   2390       if (ptr > a_mid_hi) { lo = mid+1; continue; }
   2391       vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
   2392       return mid;
   2393    }
   2394 }
   2395 
   2396 
   2397 /* Find a CFI-table index containing the specified pointer, or -1
   2398    if not found.  Binary search.  */
   2399 
   2400 Word ML_(search_one_cfitab) ( const DebugInfo* di, Addr ptr )
   2401 {
   2402    Word mid,
   2403         lo = 0,
   2404         hi = di->cfsi_used-1;
   2405 
   2406    while (lo <= hi) {
   2407       /* Invariants : hi == cfsi_used-1 || ptr < cfsi_base[hi+1]
   2408                       lo == 0           || ptr > cfsi_base[lo-1]
   2409          (the first part of the invariants is similar to considering
   2410          that cfsi_base[-1] is 0 and cfsi_base[cfsi_used] is ~0) */
   2411       mid      = (lo + hi) / 2;
   2412       if (ptr < di->cfsi_base[mid]) { hi = mid-1; continue; }
   2413       if (ptr > di->cfsi_base[mid]) { lo = mid+1; continue; }
   2414       lo = mid+1; break;
   2415    }
   2416 
   2417 #if 0
   2418    for (mid = 0; mid <= di->cfsi_used-1; mid++)
   2419       if (ptr < di->cfsi_base[mid])
   2420          break;
   2421    vg_assert (lo - 1 == mid - 1);
   2422 #endif
   2423    return lo - 1;
   2424 }
   2425 
   2426 
   2427 /* Find a FPO-table index containing the specified pointer, or -1
   2428    if not found.  Binary search.  */
   2429 
   2430 Word ML_(search_one_fpotab) ( const DebugInfo* di, Addr ptr )
   2431 {
   2432    Addr const addr = ptr - di->fpo_base_avma;
   2433    Addr a_mid_lo, a_mid_hi;
   2434    Word mid, size,
   2435         lo = 0,
   2436         hi = di->fpo_size-1;
   2437    while (True) {
   2438       /* current unsearched space is from lo to hi, inclusive. */
   2439       if (lo > hi) return -1; /* not found */
   2440       mid      = (lo + hi) / 2;
   2441       a_mid_lo = di->fpo[mid].ulOffStart;
   2442       size     = di->fpo[mid].cbProcSize;
   2443       a_mid_hi = a_mid_lo + size - 1;
   2444       vg_assert(a_mid_hi >= a_mid_lo);
   2445       if (addr < a_mid_lo) { hi = mid-1; continue; }
   2446       if (addr > a_mid_hi) { lo = mid+1; continue; }
   2447       vg_assert(addr >= a_mid_lo && addr <= a_mid_hi);
   2448       return mid;
   2449    }
   2450 }
   2451 
   2452 /*--------------------------------------------------------------------*/
   2453 /*--- end                                                          ---*/
   2454 /*--------------------------------------------------------------------*/
   2455