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