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