/* -*- mode: C; c-basic-offset: 3; -*- */

/*--------------------------------------------------------------------*/
/*--- Read DWARF3/4 ".debug_info" sections (DIE trees).            ---*/
/*---                                                 readdwarf3.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2008-2013 OpenWorks LLP
      info@open-works.co.uk

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.

   Neither the names of the U.S. Department of Energy nor the
   University of California nor the names of its contributors may be
   used to endorse or promote products derived from this software
   without prior written permission.
*/

#if defined(VGO_linux) || defined(VGO_darwin)

/* REFERENCE (without which this code will not make much sense):

   DWARF Debugging Information Format, Version 3, 
   dated 20 December 2005 (the "D3 spec").

   Available at http://www.dwarfstd.org/Dwarf3.pdf.  There's also a
   .doc (MS Word) version, but for some reason the section numbers
   between the Word and PDF versions differ by 1 in the first digit.
   All section references in this code are to the PDF version.

   CURRENT HACKS:

   DW_TAG_{const,volatile}_type no DW_AT_type is allowed; it is
      assumed to mean "const void" or "volatile void" respectively.
      GDB appears to interpret them like this, anyway.

   In many cases it is important to know the svma of a CU (the "base
   address of the CU", as the D3 spec calls it).  There are some
   situations in which the spec implies this value is unknown, but the
   Dwarf3 produced by gcc-4.1 seems to assume is not unknown but
   merely zero when not explicitly stated.  So we too have to make
   that assumption.

   POTENTIAL BUG?  Spotted 6 Sept 08.  Why doesn't
   unitary_range_list() bias the resulting range list in the same way
   that its more general cousin, get_range_list(), does?  I don't
   know.

   TODO, 2008 Feb 17:

   get rid of cu_svma_known and document the assumed-zero svma hack.

   ML_(sizeOfType): differentiate between zero sized types and types
   for which the size is unknown.  Is this important?  I don't know.

   DW_TAG_array_types: deal with explicit sizes (currently we compute
   the size from the bounds and the element size, although that's
   fragile, if the bounds incompletely specified, or completely
   absent)

   Document reason for difference (by 1) of stack preening depth in
   parse_var_DIE vs parse_type_DIE.

   Don't hand to ML_(addVars), vars whose locations are entirely in
   registers (DW_OP_reg*).  This is merely a space-saving
   optimisation, as ML_(evaluate_Dwarf3_Expr) should handle these
   expressions correctly, by failing to evaluate them and hence
   effectively ignoring the variable with which they are associated.

   Deal with DW_TAG_array_types which have element size != stride

   In some cases, the info for a variable is split between two
   different DIEs (generally a declarer and a definer).  We punt on
   these.  Could do better here.

   The 'data_bias' argument passed to the expression evaluator
   (ML_(evaluate_Dwarf3_Expr)) should really be changed to a
   MaybeUWord, to make it clear when we do vs don't know what it is
   for the evaluation of an expression.  At the moment zero is passed
   for this parameter in the don't know case.  That's a bit fragile
   and obscure; using a MaybeUWord would be clearer.

   POTENTIAL PERFORMANCE IMPROVEMENTS:

   Currently, duplicate removal and all other queries for the type
   entities array is done using cuOffset-based pointing, which
   involves a binary search (VG_(lookupXA)) for each access.  This is
   wildly inefficient, although simple.  It would be better to
   translate all the cuOffset-based references (iow, all the "R" and
   "Rs" fields in the TyEnts in 'tyents') to direct index numbers in
   'tyents' right at the start of dedup_types(), and use direct
   indexing (VG_(indexXA)) wherever possible after that.

   cmp__XArrays_of_AddrRange is also a performance bottleneck.  Move
   VG_(indexXA) into pub_tool_xarray.h so it can be inlined at all use
   points, and possibly also make an _UNCHECKED version which skips
   the range checks in performance-critical situations such as this.

   Handle interaction between read_DIE and parse_{var,type}_DIE
   better.  Currently read_DIE reads the entire DIE just to find where
   the end is (and for debug printing), so that it can later reliably
   move the cursor to the end regardless of what parse_{var,type}_DIE
   do.  This means many DIEs (most, even?) are read twice.  It would
   be smarter to make parse_{var,type}_DIE return a Bool indicating
   whether or not they advanced the DIE cursor, and only if they
   didn't should read_DIE itself read through the DIE.

   ML_(addVar) and add_var_to_arange: quite a lot of DiAddrRanges have
   zero variables in their .vars XArray.  Rather than have an XArray
   with zero elements (which uses 2 malloc'd blocks), allow the .vars
   pointer to be NULL in this case.

   More generally, reduce the amount of memory allocated and freed
   while reading Dwarf3 type/variable information.  Even modest (20MB)
   objects cause this module to allocate and free hundreds of
   thousands of small blocks, and ML_(arena_malloc) and its various
   groupies always show up at the top of performance profiles. */

#include "pub_core_basics.h"
#include "pub_core_debuginfo.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcsetjmp.h"   // setjmp facilities
#include "pub_core_hashtable.h"
#include "pub_core_options.h"
#include "pub_core_tooliface.h"    /* VG_(needs) */
#include "pub_core_xarray.h"
#include "pub_core_wordfm.h"
#include "priv_misc.h"             /* dinfo_zalloc/free */
#include "priv_image.h"
#include "priv_tytypes.h"
#include "priv_d3basics.h"
#include "priv_storage.h"
#include "priv_readdwarf3.h"       /* self */


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Basic machinery for parsing DIEs.                    ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

#define TRACE_D3(format, args...) \
   if (UNLIKELY(td3)) { VG_(printf)(format, ## args); }

#define D3_INVALID_CUOFF  ((UWord)(-1UL))
#define D3_FAKEVOID_CUOFF ((UWord)(-2UL))

typedef
   struct {
      DiSlice sli;      // to which this cursor applies
      DiOffT  sli_next; // offset in underlying DiImage; must be >= sli.ioff
      void (*barf)( const HChar* ) __attribute__((noreturn));
      const HChar* barfstr;
   }
   Cursor;

static inline Bool is_sane_Cursor ( Cursor* c ) {
   if (!c)                return False;
   if (!c->barf)          return False;
   if (!c->barfstr)       return False;
   if (!ML_(sli_is_valid)(c->sli))    return False;
   if (c->sli.ioff == DiOffT_INVALID) return False;
   if (c->sli_next < c->sli.ioff)     return False;
   return True;
}

// Initialise a cursor from a DiSlice (ELF section, really) so as to
// start reading at offset |sli_initial_offset| from the start of the
// slice.
static void init_Cursor ( /*OUT*/Cursor* c,
                          DiSlice sli,
                          ULong   sli_initial_offset,
                          __attribute__((noreturn)) void (*barf)(const HChar*),
                          const HChar* barfstr )
{
   vg_assert(c);
   VG_(bzero_inline)(c, sizeof(*c));
   c->sli              = sli;
   c->sli_next         = c->sli.ioff + sli_initial_offset;
   c->barf             = barf;
   c->barfstr          = barfstr;
   vg_assert(is_sane_Cursor(c));
}

static Bool is_at_end_Cursor ( Cursor* c ) {
   vg_assert(is_sane_Cursor(c));
   return c->sli_next >= c->sli.ioff + c->sli.szB;
}

static inline ULong get_position_of_Cursor ( Cursor* c ) {
   vg_assert(is_sane_Cursor(c));
   return c->sli_next - c->sli.ioff;
}
static inline void set_position_of_Cursor ( Cursor* c, ULong pos ) {
   c->sli_next = c->sli.ioff + pos;
   vg_assert(is_sane_Cursor(c));
}

static /*signed*/Long get_remaining_length_Cursor ( Cursor* c ) {
   vg_assert(is_sane_Cursor(c));
   return c->sli.ioff + c->sli.szB - c->sli_next;
}

//static void* get_address_of_Cursor ( Cursor* c ) {
//   vg_assert(is_sane_Cursor(c));
//   return &c->region_start_img[ c->region_next ];
//}

static DiCursor get_DiCursor_from_Cursor ( Cursor* c ) {
   return mk_DiCursor(c->sli.img, c->sli_next);
}

/* FIXME: document assumptions on endianness for
   get_UShort/UInt/ULong. */
static inline UChar get_UChar ( Cursor* c ) {
   UChar r;
   vg_assert(is_sane_Cursor(c));
   if (c->sli_next + sizeof(UChar) > c->sli.ioff + c->sli.szB) {
      c->barf(c->barfstr);
      /*NOTREACHED*/
      vg_assert(0);
   }
   r = ML_(img_get_UChar)(c->sli.img, c->sli_next);
   c->sli_next += sizeof(UChar);
   return r;
}
static UShort get_UShort ( Cursor* c ) {
   UShort r;
   vg_assert(is_sane_Cursor(c));
   if (c->sli_next + sizeof(UShort) > c->sli.ioff + c->sli.szB) {
      c->barf(c->barfstr);
      /*NOTREACHED*/
      vg_assert(0);
   }
   r = ML_(img_get_UShort)(c->sli.img, c->sli_next);
   c->sli_next += sizeof(UShort);
   return r;
}
static UInt get_UInt ( Cursor* c ) {
   UInt r;
   vg_assert(is_sane_Cursor(c));
   if (c->sli_next + sizeof(UInt) > c->sli.ioff + c->sli.szB) {
      c->barf(c->barfstr);
      /*NOTREACHED*/
      vg_assert(0);
   }
   r = ML_(img_get_UInt)(c->sli.img, c->sli_next);
   c->sli_next += sizeof(UInt);
   return r;
}
static ULong get_ULong ( Cursor* c ) {
   ULong r;
   vg_assert(is_sane_Cursor(c));
   if (c->sli_next + sizeof(ULong) > c->sli.ioff + c->sli.szB) {
      c->barf(c->barfstr);
      /*NOTREACHED*/
      vg_assert(0);
   }
   r = ML_(img_get_ULong)(c->sli.img, c->sli_next);
   c->sli_next += sizeof(ULong);
   return r;
}
static ULong get_ULEB128 ( Cursor* c ) {
   ULong result;
   Int   shift;
   UChar byte;
   /* unroll first iteration */
   byte = get_UChar( c );
   result = (ULong)(byte & 0x7f);
   if (LIKELY(!(byte & 0x80))) return result;
   shift = 7;
   /* end unroll first iteration */
   do {
      byte = get_UChar( c );
      result |= ((ULong)(byte & 0x7f)) << shift;
      shift += 7;
   } while (byte & 0x80);
   return result;
}
static Long get_SLEB128 ( Cursor* c ) {
   ULong  result = 0;
   Int    shift = 0;
   UChar  byte;
   do {
      byte = get_UChar(c);
      result |= ((ULong)(byte & 0x7f)) << shift;
      shift += 7;
   } while (byte & 0x80);
   if (shift < 64 && (byte & 0x40))
      result |= -(1ULL << shift);
   return result;
}

/* Assume 'c' points to the start of a string.  Return a DiCursor of
   whatever it points at, and advance it past the terminating zero.
   This makes it safe for the caller to then copy the string with
   ML_(addStr), since (w.r.t. image overruns) the process of advancing
   past the terminating zero will already have "vetted" the string. */
static DiCursor get_AsciiZ ( Cursor* c ) {
   UChar uc;
   DiCursor res = get_DiCursor_from_Cursor(c);
   do { uc = get_UChar(c); } while (uc != 0);
   return res;
}

static ULong peek_ULEB128 ( Cursor* c ) {
   DiOffT here = c->sli_next;
   ULong  r    = get_ULEB128( c );
   c->sli_next = here;
   return r;
}
static UChar peek_UChar ( Cursor* c ) {
   DiOffT here = c->sli_next;
   UChar  r    = get_UChar( c );
   c->sli_next = here;
   return r;
}

static ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) {
   return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c);
}

static UWord get_UWord ( Cursor* c ) {
   vg_assert(sizeof(UWord) == sizeof(void*));
   if (sizeof(UWord) == 4) return get_UInt(c);
   if (sizeof(UWord) == 8) return get_ULong(c);
   vg_assert(0);
}

/* Read a DWARF3 'Initial Length' field */
static ULong get_Initial_Length ( /*OUT*/Bool* is64,
                                  Cursor* c, 
                                  const HChar* barfMsg )
{
   ULong w64;
   UInt  w32;
   *is64 = False;
   w32 = get_UInt( c );
   if (w32 >= 0xFFFFFFF0 && w32 < 0xFFFFFFFF) {
      c->barf( barfMsg );
   }
   else if (w32 == 0xFFFFFFFF) {
      *is64 = True;
      w64   = get_ULong( c );
   } else {
      *is64 = False;
      w64 = (ULong)w32;
   }
   return w64;
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- "CUConst" structure                                  ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

typedef
   struct _name_form {
      ULong at_name;
      ULong at_form;
   } name_form;

typedef
   struct _g_abbv {
      struct _g_abbv *next; // read/write by hash table.
      UWord  abbv_code;     // key, read by hash table
      ULong  atag;
      ULong  has_children;
      name_form nf[0];
      /* Variable-length array of name/form pairs, terminated
         by a 0/0 pair. */
    } g_abbv;

/* Holds information that is constant through the parsing of a
   Compilation Unit.  This is basically plumbed through to
   everywhere. */
typedef
   struct {
      /* Call here if anything goes wrong */
      void (*barf)( const HChar* ) __attribute__((noreturn));
      /* Is this 64-bit DWARF ? */
      Bool   is_dw64;
      /* Which DWARF version ?  (2, 3 or 4) */
      UShort version;
      /* Length of this Compilation Unit, as stated in the
         .unit_length :: InitialLength field of the CU Header.
         However, this size (as specified by the D3 spec) does not
         include the size of the .unit_length field itself, which is
         either 4 or 12 bytes (32-bit or 64-bit Dwarf3).  That value
         can be obtained through the expression ".is_dw64 ? 12 : 4". */
      ULong  unit_length;
      /* Offset of start of this unit in .debug_info */
      UWord  cu_start_offset;
      /* SVMA for this CU.  In the D3 spec, is known as the "base
         address of the compilation unit (last para sec 3.1.1).
         Needed for (amongst things) interpretation of location-list
         values. */
      Addr   cu_svma;
      Bool   cu_svma_known;

      /* The debug_abbreviations table to be used for this Unit */
      //UChar* debug_abbv;
      /* Upper bound on size thereof (an overestimate, in general) */
      //UWord  debug_abbv_maxszB;
      /* A bounded area of the image, to be used as the
         debug_abbreviations table tobe used for this Unit. */
      DiSlice debug_abbv;

      /* Image information for various sections. */
      DiSlice escn_debug_str;
      DiSlice escn_debug_ranges;
      DiSlice escn_debug_loc;
      DiSlice escn_debug_line;
      DiSlice escn_debug_info;
      DiSlice escn_debug_types;
      DiSlice escn_debug_info_alt;
      DiSlice escn_debug_str_alt;
      /* How much to add to .debug_types resp. alternate .debug_info offsets
         in cook_die*.  */
      UWord  types_cuOff_bias;
      UWord  alt_cuOff_bias;
      /* --- Needed so we can add stuff to the string table. --- */
      struct _DebugInfo* di;
      /* --- a hash table of g_abbv (i.e. parsed abbreviations) --- */
      VgHashTable ht_abbvs;

      /* True if this came from .debug_types; otherwise it came from
         .debug_info.  */
      Bool is_type_unit;
      /* For a unit coming from .debug_types, these hold the TU's type
         signature and the uncooked DIE offset of the TU's signatured
         type.  For a unit coming from .debug_info, these are unused.  */
      ULong type_signature;
      ULong type_offset;

      /* Signatured type hash; computed once and then shared by all
         CUs.  */
      VgHashTable signature_types;

      /* True if this came from alternate .debug_info; otherwise
         it came from normal .debug_info or .debug_types.  */
      Bool is_alt_info;
   }
   CUConst;


/* Return the cooked value of DIE depending on whether CC represents a
   .debug_types unit.  To cook a DIE, we pretend that the .debug_info,
   .debug_types and optional alternate .debug_info sections form
   a contiguous whole, so that DIEs coming from .debug_types are numbered
   starting at the end of .debug_info and DIEs coming from alternate
   .debug_info are numbered starting at the end of .debug_types.  */
static UWord cook_die( CUConst* cc, UWord die )
{
   if (cc->is_type_unit)
      die += cc->types_cuOff_bias;
   else if (cc->is_alt_info)
      die += cc->alt_cuOff_bias;
   return die;
}

/* Like cook_die, but understand that DIEs coming from a
   DW_FORM_ref_sig8 reference are already cooked.  Also, handle
   DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types
   as reference to alternate .debug_info.  */
static UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form)
{
   if (form == DW_FORM_ref_sig8)
      return die;
   if (form == DW_FORM_GNU_ref_alt)
      return die + cc->alt_cuOff_bias;
   return cook_die( cc, die );
}

/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE
   came from the .debug_types section and *ALT_FLAG to true if the DIE
   came from alternate .debug_info section.  */
static UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag,
                         Bool *alt_flag )
{
   *alt_flag = False;
   *type_flag = False;
   /* The use of escn_debug_{info,types}.szB seems safe to me even if
      escn_debug_{info,types} are DiSlice_INVALID (meaning the
      sections were not found), because DiSlice_INVALID.szB is always
      zero.  That said, it seems unlikely we'd ever get here if
      .debug_info or .debug_types were missing. */
   if (die >= cc->escn_debug_info.szB) {
      if (die >= cc->escn_debug_info.szB + cc->escn_debug_types.szB) {
         *alt_flag = True;
         die -= cc->escn_debug_info.szB + cc->escn_debug_types.szB;
      } else {
         *type_flag = True;
         die -= cc->escn_debug_info.szB;
      }
   }
   return die;
}

/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Helper functions for Guarded Expressions             ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

/* Parse the location list starting at img-offset 'debug_loc_offset'
   in .debug_loc.  Results are biased with 'svma_of_referencing_CU'
   and so I believe are correct SVMAs for the object as a whole.  This
   function allocates the UChar*, and the caller must deallocate it.
   The resulting block is in so-called Guarded-Expression format.

   Guarded-Expression format is similar but not identical to the DWARF3
   location-list format.  The format of each returned block is:

      UChar biasMe;
      UChar isEnd;
      followed by zero or more of

      (Addr aMin;  Addr aMax;  UShort nbytes;  ..bytes..;  UChar isEnd)

   '..bytes..' is an standard DWARF3 location expression which is
   valid when aMin <= pc <= aMax (possibly after suitable biasing).

   The number of bytes in '..bytes..' is nbytes.

   The end of the sequence is marked by an isEnd == 1 value.  All
   previous isEnd values must be zero.

   biasMe is 1 if the aMin/aMax fields need this DebugInfo's
   text_bias added before use, and 0 if the GX is this is not
   necessary (is ready to go).

   Hence the block can be quickly parsed and is self-describing.  Note
   that aMax is 1 less than the corresponding value in a DWARF3
   location list.  Zero length ranges, with aMax == aMin-1, are not
   allowed.
*/
/* 2008-sept-12: moved ML_(pp_GX) from here to d3basics.c, where
   it more logically belongs. */


/* Apply a text bias to a GX. */
static void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
{
   UShort nbytes;
   UChar* p = &gx->payload[0];
   UChar* pA;
   UChar  uc;
   uc = *p++; /*biasMe*/
   if (uc == 0)
      return;
   vg_assert(uc == 1);
   p[-1] = 0; /* mark it as done */
   while (True) {
      uc = *p++;
      if (uc == 1)
         break; /*isEnd*/
      vg_assert(uc == 0);
      /* t-bias aMin */
      pA = (UChar*)p;
      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
      p += sizeof(Addr);
      /* t-bias aMax */
      pA = (UChar*)p;
      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
      p += sizeof(Addr);
      /* nbytes, and actual expression */
      nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
      p += nbytes;
   }
}

__attribute__((noinline))
static GExpr* make_singleton_GX ( DiCursor block, ULong nbytes )
{
   SizeT  bytesReqd;
   GExpr* gx;
   UChar *p, *pstart;

   vg_assert(sizeof(UWord) == sizeof(Addr));
   vg_assert(nbytes <= 0xFFFF); /* else we overflow the nbytes field */
   bytesReqd
      =   sizeof(UChar)  /*biasMe*/    + sizeof(UChar) /*!isEnd*/
        + sizeof(UWord)  /*aMin*/      + sizeof(UWord) /*aMax*/
        + sizeof(UShort) /*nbytes*/    + (SizeT)nbytes
        + sizeof(UChar); /*isEnd*/

   gx = ML_(dinfo_zalloc)( "di.readdwarf3.msGX.1", 
                           sizeof(GExpr) + bytesReqd );
   vg_assert(gx);

   p = pstart = &gx->payload[0];

   p = ML_(write_UChar)(p, 0);        /*biasMe*/
   p = ML_(write_UChar)(p, 0);        /*!isEnd*/
   p = ML_(write_Addr)(p, 0);         /*aMin*/
   p = ML_(write_Addr)(p, ~0);        /*aMax*/
   p = ML_(write_UShort)(p, nbytes);  /*nbytes*/
   ML_(cur_read_get)(p, block, nbytes); p += nbytes;
   p = ML_(write_UChar)(p, 1);        /*isEnd*/

   vg_assert( (SizeT)(p - pstart) == bytesReqd);
   vg_assert( &gx->payload[bytesReqd] 
              == ((UChar*)gx) + sizeof(GExpr) + bytesReqd );

   return gx;
}

__attribute__((noinline))
static GExpr* make_general_GX ( CUConst* cc,
                                Bool     td3,
                                ULong    debug_loc_offset,
                                Addr     svma_of_referencing_CU )
{
   Addr      base;
   Cursor    loc;
   XArray*   xa; /* XArray of UChar */
   GExpr*    gx;
   Word      nbytes;

   vg_assert(sizeof(UWord) == sizeof(Addr));
   if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0)
      cc->barf("make_general_GX: .debug_loc is empty/missing");

   init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf,
                "Overrun whilst reading .debug_loc section(2)" );
   set_position_of_Cursor( &loc, debug_loc_offset );

   TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n",
            debug_loc_offset, (ULong)get_DiCursor_from_Cursor(&loc).ioff );

   /* Who frees this xa?  It is freed before this fn exits. */
   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1", 
                    ML_(dinfo_free),
                    sizeof(UChar) );

   { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }

   base = 0;
   while (True) {
      Bool  acquire;
      UWord len;
      /* Read a (host-)word pair.  This is something of a hack since
         the word size to read is really dictated by the ELF file;
         however, we assume we're reading a file with the same
         word-sizeness as the host.  Reasonably enough. */
      UWord w1 = get_UWord( &loc );
      UWord w2 = get_UWord( &loc );

      TRACE_D3("   %08lx %08lx\n", w1, w2);
      if (w1 == 0 && w2 == 0)
         break; /* end of list */

      if (w1 == -1UL) {
         /* new value for 'base' */
         base = w2;
         continue;
      }

      /* else a location expression follows */
      /* else enumerate [w1+base, w2+base) */
      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
         (sec 2.17.2) */
      if (w1 > w2) {
         TRACE_D3("negative range is for .debug_loc expr at "
                  "file offset %llu\n", 
                  debug_loc_offset);
         cc->barf( "negative range in .debug_loc section" );
      }

      /* ignore zero length ranges */
      acquire = w1 < w2;
      len     = (UWord)get_UShort( &loc );

      if (acquire) {
         UWord  w;
         UShort s;
         UChar  c;
         c = 0; /* !isEnd*/
         VG_(addBytesToXA)( xa, &c, sizeof(c) );
         w = w1    + base + svma_of_referencing_CU;
         VG_(addBytesToXA)( xa, &w, sizeof(w) );
         w = w2 -1 + base + svma_of_referencing_CU;
         VG_(addBytesToXA)( xa, &w, sizeof(w) );
         s = (UShort)len;
         VG_(addBytesToXA)( xa, &s, sizeof(s) );
      }

      while (len > 0) {
         UChar byte = get_UChar( &loc );
         TRACE_D3("%02x", (UInt)byte);
         if (acquire)
            VG_(addBytesToXA)( xa, &byte, 1 );
         len--;
      }
      TRACE_D3("\n");
   }

   { UChar c = 1; /*isEnd*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }

   nbytes = VG_(sizeXA)( xa );
   vg_assert(nbytes >= 1);

   gx = ML_(dinfo_zalloc)( "di.readdwarf3.mgGX.2", sizeof(GExpr) + nbytes );
   vg_assert(gx);
   VG_(memcpy)( &gx->payload[0], (UChar*)VG_(indexXA)(xa,0), nbytes );
   vg_assert( &gx->payload[nbytes] 
              == ((UChar*)gx) + sizeof(GExpr) + nbytes );

   VG_(deleteXA)( xa );

   TRACE_D3("}\n");

   return gx;
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Helper functions for range lists and CU headers      ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

/* Denotes an address range.  Both aMin and aMax are included in the
   range; hence a complete range is (0, ~0) and an empty range is any
   (X, X-1) for X > 0.*/
typedef 
   struct { Addr aMin; Addr aMax; }
   AddrRange;


/* Generate an arbitrary structural total ordering on
   XArray* of AddrRange. */
static Word cmp__XArrays_of_AddrRange ( XArray* rngs1, XArray* rngs2 )
{
   Word n1, n2, i;
   tl_assert(rngs1 && rngs2);
   n1 = VG_(sizeXA)( rngs1 );  
   n2 = VG_(sizeXA)( rngs2 );
   if (n1 < n2) return -1;
   if (n1 > n2) return 1;
   for (i = 0; i < n1; i++) {
      AddrRange* rng1 = (AddrRange*)VG_(indexXA)( rngs1, i );
      AddrRange* rng2 = (AddrRange*)VG_(indexXA)( rngs2, i );
      if (rng1->aMin < rng2->aMin) return -1;
      if (rng1->aMin > rng2->aMin) return 1;
      if (rng1->aMax < rng2->aMax) return -1;
      if (rng1->aMax > rng2->aMax) return 1;
   }
   return 0;
}


__attribute__((noinline))
static XArray* /* of AddrRange */ empty_range_list ( void )
{
   XArray* xa; /* XArray of AddrRange */
   /* Who frees this xa?  varstack_preen() does. */
   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.erl.1",
                    ML_(dinfo_free),
                    sizeof(AddrRange) );
   return xa;
}


__attribute__((noinline))
static XArray* unitary_range_list ( Addr aMin, Addr aMax )
{
   XArray*   xa;
   AddrRange pair;
   vg_assert(aMin <= aMax);
   /* Who frees this xa?  varstack_preen() does. */
   xa = VG_(newXA)( ML_(dinfo_zalloc),  "di.readdwarf3.url.1",
                    ML_(dinfo_free),
                    sizeof(AddrRange) );
   pair.aMin = aMin;
   pair.aMax = aMax;
   VG_(addToXA)( xa, &pair );
   return xa;
}


/* Enumerate the address ranges starting at img-offset
   'debug_ranges_offset' in .debug_ranges.  Results are biased with
   'svma_of_referencing_CU' and so I believe are correct SVMAs for the
   object as a whole.  This function allocates the XArray, and the
   caller must deallocate it. */
__attribute__((noinline))
static XArray* /* of AddrRange */
       get_range_list ( CUConst* cc,
                        Bool     td3,
                        UWord    debug_ranges_offset,
                        Addr     svma_of_referencing_CU )
{
   Addr      base;
   Cursor    ranges;
   XArray*   xa; /* XArray of AddrRange */
   AddrRange pair;

   if (!ML_(sli_is_valid)(cc->escn_debug_ranges)
       || cc->escn_debug_ranges.szB == 0)
      cc->barf("get_range_list: .debug_ranges is empty/missing");

   init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf,
                "Overrun whilst reading .debug_ranges section(2)" );
   set_position_of_Cursor( &ranges, debug_ranges_offset );

   /* Who frees this xa?  varstack_preen() does. */
   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free),
                    sizeof(AddrRange) );
   base = 0;
   while (True) {
      /* Read a (host-)word pair.  This is something of a hack since
         the word size to read is really dictated by the ELF file;
         however, we assume we're reading a file with the same
         word-sizeness as the host.  Reasonably enough. */
      UWord w1 = get_UWord( &ranges );
      UWord w2 = get_UWord( &ranges );

      if (w1 == 0 && w2 == 0)
         break; /* end of list. */

      if (w1 == -1UL) {
         /* new value for 'base' */
         base = w2;
         continue;
      }

      /* else enumerate [w1+base, w2+base) */
      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
         (sec 2.17.2) */
      if (w1 > w2)
         cc->barf( "negative range in .debug_ranges section" );
      if (w1 < w2) {
         pair.aMin = w1     + base + svma_of_referencing_CU;
         pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
         vg_assert(pair.aMin <= pair.aMax);
         VG_(addToXA)( xa, &pair );
      }
   }
   return xa;
}

/* Initialises the hash table of abbreviations.
   We do a single scan of the abbv slice to parse and
   build all abbreviations, for the following reasons:
     * all or most abbreviations will be needed in any case
       (at least for var-info reading).
     * re-reading each time an abbreviation causes a lot of calls
       to get_ULEB128.
     * a CU should not have many abbreviations. */
static void init_ht_abbvs (CUConst* cc,
                           Bool td3)
{
   Cursor c;
   g_abbv *ta; // temporary abbreviation, reallocated if needed.
   UInt ta_nf_maxE; // max nr of pairs in ta.nf[], doubled when reallocated.
   UInt ta_nf_n;    // nr of pairs in ta->nf that are initialised.
   g_abbv *ht_ta; // abbv to insert in hash table. 

   #define SZ_G_ABBV(_nf_szE) (sizeof(g_abbv) + _nf_szE * sizeof(name_form))

   ta_nf_maxE = 10; // starting with enough for 9 pairs+terminating pair.
   ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf", SZ_G_ABBV(ta_nf_maxE));
   cc->ht_abbvs = VG_(HT_construct) ("di.readdwarf3.ht_abbvs");

   init_Cursor( &c, cc->debug_abbv, 0, cc->barf,
               "Overrun whilst parsing .debug_abbrev section(2)" );
   while (True) {
      ta->abbv_code = get_ULEB128( &c );
      if (ta->abbv_code == 0) break; /* end of the table */

      ta->atag = get_ULEB128( &c );
      ta->has_children = get_UChar( &c );
      ta_nf_n = 0;
      while (True) {
         if (ta_nf_n >= ta_nf_maxE) {
            g_abbv *old_ta = ta;
            ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf",
                                    SZ_G_ABBV(2 * ta_nf_maxE));
            ta_nf_maxE = 2 * ta_nf_maxE;
            VG_(memcpy) (ta, old_ta, SZ_G_ABBV(ta_nf_n));
            ML_(dinfo_free) (old_ta);
         }
         ta->nf[ta_nf_n].at_name = get_ULEB128( &c );
         ta->nf[ta_nf_n].at_form = get_ULEB128( &c );
         if (ta->nf[ta_nf_n].at_name == 0 && ta->nf[ta_nf_n].at_form == 0) {
            ta_nf_n++;
            break; 
         }
        ta_nf_n++;
      }
      ht_ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta", SZ_G_ABBV(ta_nf_n));
      VG_(memcpy) (ht_ta, ta, SZ_G_ABBV(ta_nf_n));
      VG_(HT_add_node) ( cc->ht_abbvs, ht_ta );
      TRACE_D3("  Adding abbv_code %llu TAG  %s [%s] nf %d\n",
               (ULong) ht_ta->abbv_code, ML_(pp_DW_TAG)(ht_ta->atag),
               ML_(pp_DW_children)(ht_ta->has_children),
               ta_nf_n);
   }

   ML_(dinfo_free) (ta);
   #undef SZ_G_ABBV
}

static g_abbv* get_abbv (CUConst* cc, ULong abbv_code)
{
   g_abbv *abbv;

   abbv = VG_(HT_lookup) (cc->ht_abbvs, abbv_code);
   if (!abbv)
      cc->barf ("abbv_code not found in ht_abbvs table");
   return abbv;
}

/* Free the memory allocated in CUConst. */
static void clear_CUConst (CUConst* cc)
{
   VG_(HT_destruct) ( cc->ht_abbvs, ML_(dinfo_free));
   cc->ht_abbvs = NULL;
}

/* Parse the Compilation Unit header indicated at 'c' and 
   initialise 'cc' accordingly. */
static __attribute__((noinline))
void parse_CU_Header ( /*OUT*/CUConst* cc,
                       Bool td3,
                       Cursor* c, 
                       DiSlice escn_debug_abbv,
		       Bool type_unit,
                       Bool alt_info )
{
   UChar  address_size;
   ULong  debug_abbrev_offset;

   VG_(memset)(cc, 0, sizeof(*cc));
   vg_assert(c && c->barf);
   cc->barf = c->barf;

   /* initial_length field */
   cc->unit_length 
      = get_Initial_Length( &cc->is_dw64, c, 
           "parse_CU_Header: invalid initial-length field" );

   TRACE_D3("   Length:        %lld\n", cc->unit_length );

   /* version */
   cc->version = get_UShort( c );
   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
   TRACE_D3("   Version:       %d\n", (Int)cc->version );

   /* debug_abbrev_offset */
   debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
   if (debug_abbrev_offset >= escn_debug_abbv.szB)
      cc->barf( "parse_CU_Header: invalid debug_abbrev_offset" );
   TRACE_D3("   Abbrev Offset: %lld\n", debug_abbrev_offset );

   /* address size.  If this isn't equal to the host word size, just
      give up.  This makes it safe to assume elsewhere that
      DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
      word. */
   address_size = get_UChar( c );
   if (address_size != sizeof(void*))
      cc->barf( "parse_CU_Header: invalid address_size" );
   TRACE_D3("   Pointer Size:  %d\n", (Int)address_size );

   cc->is_type_unit = type_unit;
   cc->is_alt_info = alt_info;

   if (type_unit) {
      cc->type_signature = get_ULong( c );
      cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
   }

   /* Set up cc->debug_abbv to point to the relevant table for this
      CU.  Set its .szB so that at least we can't read off the end of
      the debug_abbrev section -- potentially (and quite likely) too
      big, if this isn't the last table in the section, but at least
      it's safe.

      This amounts to taking debug_abbv_escn and moving the start
      position along by debug_abbrev_offset bytes, hence forming a
      smaller DiSlice which has the same end point.  Since we checked
      just above that debug_abbrev_offset is less than the size of
      debug_abbv_escn, this should leave us with a nonempty slice. */
   vg_assert(debug_abbrev_offset < escn_debug_abbv.szB);
   cc->debug_abbv      = escn_debug_abbv;
   cc->debug_abbv.ioff += debug_abbrev_offset;
   cc->debug_abbv.szB  -= debug_abbrev_offset;

   init_ht_abbvs(cc, td3);
}

/* This represents a single signatured type.  It maps a type signature
   (a ULong) to a cooked DIE offset.  Objects of this type are stored
   in the type signature hash table.  */
typedef
   struct D3SignatureType {
      struct D3SignatureType *next;
      UWord data;
      ULong type_signature;
      UWord die;
   }
   D3SignatureType;

/* Record a signatured type in the hash table.  */
static void record_signatured_type ( VgHashTable tab,
                                     ULong type_signature,
                                     UWord die )
{
   D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype",
                                                 sizeof(D3SignatureType) );
   dstype->data = (UWord) type_signature;
   dstype->type_signature = type_signature;
   dstype->die = die;
   VG_(HT_add_node) ( tab, dstype );
}

/* Given a type signature hash table and a type signature, return the
   cooked DIE offset of the type.  If the type cannot be found, call
   BARF.  */
static UWord lookup_signatured_type ( VgHashTable tab,
                                      ULong type_signature,
                                      void (*barf)( const HChar* ) __attribute__((noreturn)) )
{
   D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature );
   /* This may be unwarranted chumminess with the hash table
      implementation.  */
   while ( dstype != NULL && dstype->type_signature != type_signature)
      dstype = dstype->next;
   if (dstype == NULL) {
      barf("lookup_signatured_type: could not find signatured type");
      /*NOTREACHED*/
      vg_assert(0);
   }
   return dstype->die;
}


/* Represents Form data.  If szB is 1/2/4/8 then the result is in the
   lowest 1/2/4/8 bytes of u.val.  If szB is zero or negative then the
   result is an image section beginning at u.cur and with size -szB.
   No other szB values are allowed. */
typedef
   struct {
      Long szB; // 1, 2, 4, 8 or non-positive values only.
      union { ULong val; DiCursor cur; } u;
   }
   FormContents;

/* From 'c', get the Form data into 'cts'.  Either it gets a 1/2/4/8
   byte scalar value, or (a reference to) zero or more bytes starting
   at a DiCursor.*/
static
void get_Form_contents ( /*OUT*/FormContents* cts,
                         CUConst* cc, Cursor* c,
                         Bool td3, DW_FORM form )
{
   VG_(bzero_inline)(cts, sizeof(*cts));
   switch (form) {
      case DW_FORM_data1:
         cts->u.val = (ULong)(UChar)get_UChar(c);
         cts->szB   = 1;
         TRACE_D3("%u", (UInt)cts->u.val);
         break;
      case DW_FORM_data2:
         cts->u.val = (ULong)(UShort)get_UShort(c);
         cts->szB   = 2;
         TRACE_D3("%u", (UInt)cts->u.val);
         break;
      case DW_FORM_data4:
         cts->u.val = (ULong)(UInt)get_UInt(c);
         cts->szB   = 4;
         TRACE_D3("%u", (UInt)cts->u.val);
         break;
      case DW_FORM_data8:
         cts->u.val = get_ULong(c);
         cts->szB   = 8;
         TRACE_D3("%llu", cts->u.val);
         break;
      case DW_FORM_sec_offset:
         cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
         cts->szB   = cc->is_dw64 ? 8 : 4;
         TRACE_D3("%llu", cts->u.val);
         break;
      case DW_FORM_sdata:
         cts->u.val = (ULong)(Long)get_SLEB128(c);
         cts->szB   = 8;
         TRACE_D3("%lld", (Long)cts->u.val);
         break;
      case DW_FORM_udata:
         cts->u.val = (ULong)(Long)get_ULEB128(c);
         cts->szB   = 8;
         TRACE_D3("%llu", (Long)cts->u.val);
         break;
      case DW_FORM_addr:
         /* note, this is a hack.  DW_FORM_addr is defined as getting
            a word the size of the target machine as defined by the
            address_size field in the CU Header.  However,
            parse_CU_Header() rejects all inputs except those for
            which address_size == sizeof(Word), hence we can just
            treat it as a (host) Word.  */
         cts->u.val = (ULong)(UWord)get_UWord(c);
         cts->szB   = sizeof(UWord);
         TRACE_D3("0x%lx", (UWord)cts->u.val);
         break;

      case DW_FORM_ref_addr:
         /* We make the same word-size assumption as DW_FORM_addr. */
         /* What does this really mean?  From D3 Sec 7.5.4,
            description of "reference", it would appear to reference
            some other DIE, by specifying the offset from the
            beginning of a .debug_info section.  The D3 spec mentions
            that this might be in some other shared object and
            executable.  But I don't see how the name of the other
            object/exe is specified.

            At least for the DW_FORM_ref_addrs created by icc11, the
            references seem to be within the same object/executable.
            So for the moment we merely range-check, to see that they
            actually do specify a plausible offset within this
            object's .debug_info, and return the value unchanged.

            In DWARF 2, DW_FORM_ref_addr is address-sized, but in
            DWARF 3 and later, it is offset-sized.
         */
         if (cc->version == 2) {
            cts->u.val = (ULong)(UWord)get_UWord(c);
            cts->szB   = sizeof(UWord);
         } else {
            cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
            cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
         }
         TRACE_D3("0x%lx", (UWord)cts->u.val);
         if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)cts->u.val);
         if (/* the following is surely impossible, but ... */
             !ML_(sli_is_valid)(cc->escn_debug_info)
             || cts->u.val >= (ULong)cc->escn_debug_info.szB) {
            /* Hmm.  Offset is nonsensical for this object's .debug_info
               section.  Be safe and reject it. */
            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
                     "outside .debug_info");
         }
         break;

      case DW_FORM_strp: {
         /* this is an offset into .debug_str */
         UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
         if (!ML_(sli_is_valid)(cc->escn_debug_str)
             || uw >= cc->escn_debug_str.szB)
            cc->barf("get_Form_contents: DW_FORM_strp "
                     "points outside .debug_str");
         /* FIXME: check the entire string lies inside debug_str,
            not just the first byte of it. */
         DiCursor str
            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), uw );
         if (td3) {
            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1");
            TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, tmp);
            ML_(dinfo_free)(tmp);
         }
         cts->u.cur = str;
         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
         break;
      }
      case DW_FORM_string: {
         DiCursor str = get_AsciiZ(c);
         if (td3) {
            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.2");
            TRACE_D3("%s", tmp);
            ML_(dinfo_free)(tmp);
         }
         cts->u.cur = str;
         /* strlen is safe because get_AsciiZ already 'vetted' the
            entire string */
         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
         break;
      }
      case DW_FORM_ref1: {
         UChar u8   = get_UChar(c);
         UWord res  = cc->cu_start_offset + (UWord)u8;
         cts->u.val = (ULong)res;
         cts->szB   = sizeof(UWord);
         TRACE_D3("<%lx>", res);
         break;
      }
      case DW_FORM_ref2: {
         UShort u16 = get_UShort(c);
         UWord  res = cc->cu_start_offset + (UWord)u16;
         cts->u.val = (ULong)res;
         cts->szB   = sizeof(UWord);
         TRACE_D3("<%lx>", res);
         break;
      }
      case DW_FORM_ref4: {
         UInt  u32  = get_UInt(c);
         UWord res  = cc->cu_start_offset + (UWord)u32;
         cts->u.val = (ULong)res;
         cts->szB   = sizeof(UWord);
         TRACE_D3("<%lx>", res);
         break;
      }
      case DW_FORM_ref8: {
         ULong u64  = get_ULong(c);
         UWord res  = cc->cu_start_offset + (UWord)u64;
         cts->u.val = (ULong)res;
         cts->szB   = sizeof(UWord);
         TRACE_D3("<%lx>", res);
         break;
      }
      case DW_FORM_ref_udata: {
         ULong u64  = get_ULEB128(c);
         UWord res  = cc->cu_start_offset + (UWord)u64;
         cts->u.val = (ULong)res;
         cts->szB   = sizeof(UWord);
         TRACE_D3("<%lx>", res);
         break;
      }
      case DW_FORM_flag: {
         UChar u8 = get_UChar(c);
         TRACE_D3("%u", (UInt)u8);
         cts->u.val = (ULong)u8;
         cts->szB   = 1;
         break;
      }
      case DW_FORM_flag_present:
         TRACE_D3("1");
         cts->u.val = 1;
         cts->szB   = 1;
         break;
      case DW_FORM_block1: {
         ULong    u64b;
         ULong    u64   = (ULong)get_UChar(c);
         DiCursor block = get_DiCursor_from_Cursor(c);
         TRACE_D3("%llu byte block: ", u64);
         for (u64b = u64; u64b > 0; u64b--) {
            UChar u8 = get_UChar(c);
            TRACE_D3("%x ", (UInt)u8);
         }
         cts->u.cur = block;
         cts->szB   = - (Long)u64;
         break;
      }
      case DW_FORM_block2: {
         ULong    u64b;
         ULong    u64   = (ULong)get_UShort(c);
         DiCursor block = get_DiCursor_from_Cursor(c);
         TRACE_D3("%llu byte block: ", u64);
         for (u64b = u64; u64b > 0; u64b--) {
            UChar u8 = get_UChar(c);
            TRACE_D3("%x ", (UInt)u8);
         }
         cts->u.cur = block;
         cts->szB   = - (Long)u64;
         break;
      }
      case DW_FORM_block4: {
         ULong    u64b;
         ULong    u64   = (ULong)get_UInt(c);
         DiCursor block = get_DiCursor_from_Cursor(c);
         TRACE_D3("%llu byte block: ", u64);
         for (u64b = u64; u64b > 0; u64b--) {
            UChar u8 = get_UChar(c);
            TRACE_D3("%x ", (UInt)u8);
         }
         cts->u.cur = block;
         cts->szB   = - (Long)u64;
         break;
      }
      case DW_FORM_exprloc:
      case DW_FORM_block: {
         ULong    u64b;
         ULong    u64   = (ULong)get_ULEB128(c);
         DiCursor block = get_DiCursor_from_Cursor(c);
         TRACE_D3("%llu byte block: ", u64);
         for (u64b = u64; u64b > 0; u64b--) {
            UChar u8 = get_UChar(c);
            TRACE_D3("%x ", (UInt)u8);
         }
         cts->u.cur = block;
         cts->szB   = - (Long)u64;
         break;
      }
      case DW_FORM_ref_sig8: {
         ULong  u64b;
         ULong  signature = get_ULong (c);
         ULong  work = signature;
         TRACE_D3("8 byte signature: ");
         for (u64b = 8; u64b > 0; u64b--) {
            UChar u8 = work & 0xff;
            TRACE_D3("%x ", (UInt)u8);
            work >>= 8;
         }
         /* Due to the way that the hash table is constructed, the
            resulting DIE offset here is already "cooked".  See
            cook_die_using_form.  */
         cts->u.val = lookup_signatured_type (cc->signature_types, signature,
                                              c->barf);
         cts->szB   = sizeof(UWord);
         break;
      }
      case DW_FORM_indirect:
         get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c));
         return;

      case DW_FORM_GNU_ref_alt:
         cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
         cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
         TRACE_D3("0x%lx", (UWord)cts->u.val);
         if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)cts->u.val);
         if (/* the following is surely impossible, but ... */
             !ML_(sli_is_valid)(cc->escn_debug_info_alt)
             || cts->u.val >= (ULong)cc->escn_debug_info_alt.szB) {
            /* Hmm.  Offset is nonsensical for this object's .debug_info
               section.  Be safe and reject it. */
            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
                     "outside alternate .debug_info");
         }
         break;

      case DW_FORM_GNU_strp_alt: {
         /* this is an offset into alternate .debug_str */
         SizeT uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
         if (!ML_(sli_is_valid)(cc->escn_debug_str_alt)
             || uw >= cc->escn_debug_str_alt.szB)
            cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt "
                     "points outside alternate .debug_str");
         /* FIXME: check the entire string lies inside debug_str,
            not just the first byte of it. */
         DiCursor str
            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str_alt), uw);
         if (td3) {
            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.3");
            TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, tmp);
            ML_(dinfo_free)(tmp);
         }
         cts->u.cur = str;
         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
         break;
      }

      default:
         VG_(printf)(
            "get_Form_contents: unhandled %d (%s) at <%llx>\n",
            form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
         c->barf("get_Form_contents: unhandled DW_FORM");
   }
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Parsing of variable-related DIEs                     ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

typedef
   struct _TempVar {
      HChar*  name; /* in DebugInfo's .strpool */
      /* Represent ranges economically.  nRanges is the number of
         ranges.  Cases:
         0: .rngOneMin .rngOneMax .manyRanges are all zero
         1: .rngOneMin .rngOneMax hold the range; .rngMany is NULL
         2: .rngOneMin .rngOneMax are zero; .rngMany holds the ranges.
         This is merely an optimisation to avoid having to allocate
         and free the XArray in the common (98%) of cases where there
         is zero or one address ranges. */
      UWord   nRanges;
      Addr    rngOneMin;
      Addr    rngOneMax;
      XArray* rngMany; /* of AddrRange.  NON-UNIQUE PTR in AR_DINFO. */
      /* Do not free .rngMany, since many TempVars will have the same
         value.  Instead the associated storage is to be freed by
         deleting 'rangetree', which stores a single copy of each
         range. */
      /* --- */
      Int     level;
      UWord   typeR; /* a cuOff */
      GExpr*  gexpr; /* for this variable */
      GExpr*  fbGX;  /* to find the frame base of the enclosing fn, if
                        any */
      HChar*  fName; /* declaring file name, or NULL */
      Int     fLine; /* declaring file line number, or zero */
      /* offset in .debug_info, so that abstract instances can be
         found to satisfy references from concrete instances. */
      UWord   dioff;
      UWord   absOri; /* so the absOri fields refer to dioff fields
                         in some other, related TempVar. */
   }
   TempVar;

#define N_D3_VAR_STACK 48

typedef
   struct {
      /* Contains the range stack: a stack of address ranges, one
         stack entry for each nested scope.  

         Some scope entries are created by function definitions
         (DW_AT_subprogram), and for those, we also note the GExpr
         derived from its DW_AT_frame_base attribute, if any.
         Consequently it should be possible to find, for any
         variable's DIE, the GExpr for the the containing function's
         DW_AT_frame_base by scanning back through the stack to find
         the nearest entry associated with a function.  This somewhat
         elaborate scheme is provided so as to make it possible to
         obtain the correct DW_AT_frame_base expression even in the
         presence of nested functions (or to be more precise, in the
         presence of nested DW_AT_subprogram DIEs). 
      */
      Int     sp; /* [sp] is innermost active entry; sp==-1 for empty
                     stack */
      XArray* ranges[N_D3_VAR_STACK]; /* XArray of AddrRange */
      Int     level[N_D3_VAR_STACK];  /* D3 DIE levels */
      Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
      GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
                                         expr, else NULL */
      /* The file name table.  Is a mapping from integer index to the
         (permanent) copy of the string in in DebugInfo's .strpool. */
      XArray* /* of UChar* */ filenameTable;
   }
   D3VarParser;

static void varstack_show ( D3VarParser* parser, const HChar* str ) {
   Word i, j;
   VG_(printf)("  varstack (%s) {\n", str);
   for (i = 0; i <= parser->sp; i++) {
      XArray* xa = parser->ranges[i];
      vg_assert(xa);
      VG_(printf)("    [%ld] (level %d)", i, parser->level[i]);
      if (parser->isFunc[i]) {
         VG_(printf)(" (fbGX=%p)", parser->fbGX[i]);
      } else {
         vg_assert(parser->fbGX[i] == NULL);
      }
      VG_(printf)(": ");
      if (VG_(sizeXA)( xa ) == 0) {
         VG_(printf)("** empty PC range array **");
      } else {
         for (j = 0; j < VG_(sizeXA)( xa ); j++) {
            AddrRange* range = (AddrRange*) VG_(indexXA)( xa, j );
            vg_assert(range);
            VG_(printf)("[%#lx,%#lx] ", range->aMin, range->aMax);
         }
      }
      VG_(printf)("\n");
   }
   VG_(printf)("  }\n");
}

/* Remove from the stack, all entries with .level > 'level' */
static 
void varstack_preen ( D3VarParser* parser, Bool td3, Int level )
{
   Bool changed = False;
   vg_assert(parser->sp < N_D3_VAR_STACK);
   while (True) {
      vg_assert(parser->sp >= -1);
      if (parser->sp == -1) break;
      if (parser->level[parser->sp] <= level) break;
      if (0) 
         TRACE_D3("BBBBAAAA varstack_pop [newsp=%d]\n", parser->sp-1);
      vg_assert(parser->ranges[parser->sp]);
      /* Who allocated this xa?  get_range_list() or
         unitary_range_list(). */
      VG_(deleteXA)( parser->ranges[parser->sp] );
      parser->ranges[parser->sp] = NULL;
      parser->level[parser->sp]  = 0;
      parser->isFunc[parser->sp] = False;
      parser->fbGX[parser->sp]   = NULL;
      parser->sp--;
      changed = True;
   }
   if (changed && td3)
      varstack_show( parser, "after preen" );
}

static void varstack_push ( CUConst* cc,
                            D3VarParser* parser,
                            Bool td3,
                            XArray* ranges, Int level,
                            Bool    isFunc, GExpr* fbGX ) {
   if (0)
   TRACE_D3("BBBBAAAA varstack_push[newsp=%d]: %d  %p\n",
            parser->sp+1, level, ranges);

   /* First we need to zap everything >= 'level', as we are about to
      replace any previous entry at 'level', so .. */
   varstack_preen(parser, /*td3*/False, level-1);

   vg_assert(parser->sp >= -1);
   vg_assert(parser->sp < N_D3_VAR_STACK);
   if (parser->sp == N_D3_VAR_STACK-1)
      cc->barf("varstack_push: N_D3_VAR_STACK is too low; "
               "increase and recompile");
   if (parser->sp >= 0)
      vg_assert(parser->level[parser->sp] < level);
   parser->sp++;
   vg_assert(parser->ranges[parser->sp] == NULL);
   vg_assert(parser->level[parser->sp]  == 0);
   vg_assert(parser->isFunc[parser->sp] == False);
   vg_assert(parser->fbGX[parser->sp]   == NULL);
   vg_assert(ranges != NULL);
   if (!isFunc) vg_assert(fbGX == NULL);
   parser->ranges[parser->sp] = ranges;
   parser->level[parser->sp]  = level;
   parser->isFunc[parser->sp] = isFunc;
   parser->fbGX[parser->sp]   = fbGX;
   if (td3)
      varstack_show( parser, "after push" );
}


/* cts is derived from a DW_AT_location and so refers either to a
   location expression or to a location list.  Figure out which, and
   in both cases bundle the expression or location list into a
   so-called GExpr (guarded expression). */
__attribute__((noinline))
static GExpr* get_GX ( CUConst* cc, Bool td3, const FormContents* cts )
{
   GExpr* gexpr = NULL;
   if (cts->szB < 0) {
      /* represents a non-empty in-line location expression, and
         cts->u.cur points at the image bytes */
      gexpr = make_singleton_GX( cts->u.cur, (ULong)(- cts->szB) );
   }
   else 
   if (cts->szB > 0) {
      /* represents a location list.  cts->u.val is the offset of it
         in .debug_loc. */
      if (!cc->cu_svma_known)
         cc->barf("get_GX: location list, but CU svma is unknown");
      gexpr = make_general_GX( cc, td3, cts->u.val, cc->cu_svma );
   }
   else {
      vg_assert(0); /* else caller is bogus */
   }
   return gexpr;
}


static 
void read_filename_table( /*MOD*/XArray* /* of UChar* */ filenameTable,
                          CUConst* cc, ULong debug_line_offset,
                          Bool td3 )
{
   Bool   is_dw64;
   Cursor c;
   Word   i;
   UShort version;
   UChar  opcode_base;
   HChar* str;

   vg_assert(filenameTable && cc && cc->barf);
   if (!ML_(sli_is_valid)(cc->escn_debug_line)
       || cc->escn_debug_line.szB <= debug_line_offset) {
      cc->barf("read_filename_table: .debug_line is missing?");
   }

   init_Cursor( &c, cc->escn_debug_line, debug_line_offset, cc->barf, 
                "Overrun whilst reading .debug_line section(1)" );

   /* unit_length = */
      get_Initial_Length( &is_dw64, &c,
           "read_filename_table: invalid initial-length field" );
   version = get_UShort( &c );
   if (version != 2 && version != 3 && version != 4)
     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
              "is currently supported.");
   /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
   /*minimum_instruction_length = */ get_UChar( &c );
   if (version >= 4)
      /*maximum_operations_per_insn = */ get_UChar( &c );
   /*default_is_stmt            = */ get_UChar( &c );
   /*line_base                  = (Char)*/ get_UChar( &c );
   /*line_range                 = */ get_UChar( &c );
   opcode_base                = get_UChar( &c );
   /* skip over "standard_opcode_lengths" */
   for (i = 1; i < (Word)opcode_base; i++)
     (void)get_UChar( &c );

   /* skip over the directory names table */
   while (peek_UChar(&c) != 0) {
     (void)get_AsciiZ(&c);
   }
   (void)get_UChar(&c); /* skip terminating zero */

   /* Read and record the file names table */
   vg_assert( VG_(sizeXA)( filenameTable ) == 0 );
   /* Add a dummy index-zero entry.  DWARF3 numbers its files
      from 1, for some reason. */
   str = ML_(addStr)( cc->di, "<unknown_file>", -1 );
   VG_(addToXA)( filenameTable, &str );
   while (peek_UChar(&c) != 0) {
      DiCursor cur = get_AsciiZ(&c);
      str = ML_(addStrFromCursor)( cc->di, cur );
      TRACE_D3("  read_filename_table: %ld %s\n",
               VG_(sizeXA)(filenameTable), str);
      VG_(addToXA)( filenameTable, &str );
      (void)get_ULEB128( &c ); /* skip directory index # */
      (void)get_ULEB128( &c ); /* skip last mod time */
      (void)get_ULEB128( &c ); /* file size */
   }
   /* We're done!  The rest of it is not interesting. */
}

/* setup_cu_svma to be called when a cu is found at level 0,
   to establish the cu_svma. */
static void setup_cu_svma(CUConst* cc, Bool have_lo, Addr ip_lo, Bool td3)
{
   Addr cu_svma;
   /* We have potentially more than one type of parser parsing the
      dwarf information. At least currently, each parser establishes
      the cu_svma. So, in case cu_svma_known, we check that the same
      result is obtained by the 2nd parsing of the cu.

      Alternatively, we could reset cu_svma_known after each parsing
      and then check that we only see a single DW_TAG_compile_unit DIE
      at level 0, DWARF3 only allows exactly one top level DIE per
      CU. */

   if (have_lo)
      cu_svma = ip_lo;
   else {
      /* Now, it may be that this DIE doesn't tell us the CU's
         SVMA, by way of not having a DW_AT_low_pc.  That's OK --
         the CU doesn't *have* to have its SVMA specified.
         
         But as per last para D3 spec sec 3.1.1 ("Normal and
         Partial Compilation Unit Entries", "If the base address
         (viz, the SVMA) is undefined, then any DWARF entry of
         structure defined interms of the base address of that
         compilation unit is not valid.".  So that means, if whilst
         processing the children of this top level DIE (or their
         children, etc) we see a DW_AT_range, and cu_svma_known is
         False, then the DIE that contains it is (per the spec)
         invalid, and we can legitimately stop and complain. */
      /* .. whereas The Reality is, simply assume the SVMA is zero
         if it isn't specified. */
      cu_svma = 0;
   }

   if (cc->cu_svma_known) {
      vg_assert (cu_svma == cc->cu_svma);
   } else {
      cc->cu_svma_known = True;
      cc->cu_svma = cu_svma;
      if (0)
         TRACE_D3("setup_cu_svma: acquire CU_SVMA of %p\n", (void*) cc->cu_svma);
   }
}

__attribute__((noreturn))
static void dump_bad_die_and_barf(
   DW_TAG dtag,
   UWord posn,
   Int level,
   Cursor* c_die,  UWord saved_die_c_offset,
   g_abbv *abbv,
   CUConst* cc)
{
   FormContents cts;
   UInt nf_i;
   Bool  debug_types_flag;
   Bool  alt_flag;

   set_position_of_Cursor( c_die,  saved_die_c_offset );
   posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
   if (debug_types_flag) {
      VG_(printf)(" (in .debug_types)");
   }
   else if (alt_flag) {
      VG_(printf)(" (in alternate .debug_info)");
   }
   VG_(printf)("\n");
   nf_i = 0;
   while (True) {
      DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
      DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
      nf_i++;
      if (attr == 0 && form == 0) break;
      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
      /* Get the form contents, so as to print them */
      get_Form_contents( &cts, cc, c_die, True, form );
      VG_(printf)("\t\n");
   }
   VG_(printf)("\n");
   cc->barf("parse_var_DIE: confused by the above DIE");
}

__attribute__((noinline))
static void bad_DIE_confusion(int linenr)
{
   VG_(printf)("\nparse_var_DIE(%d): confused by:\n", linenr);
}
#define goto_bad_DIE do {bad_DIE_confusion(__LINE__); goto bad_DIE;} while (0)

__attribute__((noinline))
static void parse_var_DIE (
   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
   /*MOD*/XArray* /* of TempVar* */ tempvars,
   /*MOD*/XArray* /* of GExpr* */ gexprs,
   /*MOD*/D3VarParser* parser,
   DW_TAG dtag,
   UWord posn,
   Int level,
   Cursor* c_die,
   g_abbv *abbv,
   CUConst* cc,
   Bool td3
)
{
   FormContents cts;
   UInt nf_i;

   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );

   varstack_preen( parser, td3, level-1 );

   if (dtag == DW_TAG_compile_unit
       || dtag == DW_TAG_type_unit
       || dtag == DW_TAG_partial_unit) {
      Bool have_lo    = False;
      Bool have_hi1   = False;
      Bool hiIsRelative = False;
      Bool have_range = False;
      Addr ip_lo    = 0;
      Addr ip_hi1   = 0;
      Addr rangeoff = 0;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_low_pc && cts.szB > 0) {
            ip_lo   = cts.u.val;
            have_lo = True;
         }
         if (attr == DW_AT_high_pc && cts.szB > 0) {
            ip_hi1   = cts.u.val;
            have_hi1 = True;
            if (form != DW_FORM_addr)
               hiIsRelative = True;
         }
         if (attr == DW_AT_ranges && cts.szB > 0) {
            rangeoff   = cts.u.val;
            have_range = True;
         }
         if (attr == DW_AT_stmt_list && cts.szB > 0) {
            read_filename_table( parser->filenameTable, cc, cts.u.val, td3 );
         }
      }
      if (have_lo && have_hi1 && hiIsRelative)
         ip_hi1 += ip_lo;

      /* Now, does this give us an opportunity to find this
         CU's svma? */
      if (level == 0)
         setup_cu_svma(cc, have_lo, ip_lo, td3);

      /* Do we have something that looks sane? */
      if (have_lo && have_hi1 && (!have_range)) {
         if (ip_lo < ip_hi1)
            varstack_push( cc, parser, td3, 
                           unitary_range_list(ip_lo, ip_hi1 - 1),
                           level,
                           False/*isFunc*/, NULL/*fbGX*/ );
         else if (ip_lo == 0 && ip_hi1 == 0)
            /* CU has no code, presumably?
               Such situations have been encountered for code
               compiled with -ffunction-sections -fdata-sections
               and linked with --gc-sections. Completely
               eliminated CU gives such 0 lo/hi pc. Similarly
               to a CU which has no lo/hi/range pc, we push
               an empty range list. */
            varstack_push( cc, parser, td3,
                           empty_range_list(),
                           level,
                           False/*isFunc*/, NULL/*fbGX*/ );
      } else
      if ((!have_lo) && (!have_hi1) && have_range) {
         varstack_push( cc, parser, td3, 
                        get_range_list( cc, td3,
                                        rangeoff, cc->cu_svma ),
                        level,
                        False/*isFunc*/, NULL/*fbGX*/ );
      } else
      if ((!have_lo) && (!have_hi1) && (!have_range)) {
         /* CU has no code, presumably? */
         varstack_push( cc, parser, td3, 
                        empty_range_list(),
                        level,
                        False/*isFunc*/, NULL/*fbGX*/ );
      } else
      if (have_lo && (!have_hi1) && have_range && ip_lo == 0) {
         /* broken DIE created by gcc-4.3.X ?  Ignore the
            apparently-redundant DW_AT_low_pc and use the DW_AT_ranges
            instead. */
         varstack_push( cc, parser, td3, 
                        get_range_list( cc, td3,
                                        rangeoff, cc->cu_svma ),
                        level,
                        False/*isFunc*/, NULL/*fbGX*/ );
      } else {
         if (0) VG_(printf)("I got hlo %d hhi1 %d hrange %d\n",
                            (Int)have_lo, (Int)have_hi1, (Int)have_range);
         goto_bad_DIE;
      }
   }

   if (dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram) {
      Bool   have_lo    = False;
      Bool   have_hi1   = False;
      Bool   have_range = False;
      Bool   hiIsRelative = False;
      Addr   ip_lo      = 0;
      Addr   ip_hi1     = 0;
      Addr   rangeoff   = 0;
      Bool   isFunc     = dtag == DW_TAG_subprogram;
      GExpr* fbGX       = NULL;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_low_pc && cts.szB > 0) {
            ip_lo   = cts.u.val;
            have_lo = True;
         }
         if (attr == DW_AT_high_pc && cts.szB > 0) {
            ip_hi1   = cts.u.val;
            have_hi1 = True;
            if (form != DW_FORM_addr)
               hiIsRelative = True;
         }
         if (attr == DW_AT_ranges && cts.szB > 0) {
            rangeoff   = cts.u.val;
            have_range = True;
         }
         if (isFunc
             && attr == DW_AT_frame_base
             && cts.szB != 0 /* either scalar or nonempty block */) {
            fbGX = get_GX( cc, False/*td3*/, &cts );
            vg_assert(fbGX);
            VG_(addToXA)(gexprs, &fbGX);
         }
      }
      if (have_lo && have_hi1 && hiIsRelative)
         ip_hi1 += ip_lo;
      /* Do we have something that looks sane? */
      if (dtag == DW_TAG_subprogram 
          && (!have_lo) && (!have_hi1) && (!have_range)) {
         /* This is legit - ignore it. Sec 3.3.3: "A subroutine entry
            representing a subroutine declaration that is not also a
            definition does not have code address or range
            attributes." */
      } else
      if (dtag == DW_TAG_lexical_block
          && (!have_lo) && (!have_hi1) && (!have_range)) {
         /* I believe this is legit, and means the lexical block
            contains no insns (whatever that might mean).  Ignore. */
      } else
      if (have_lo && have_hi1 && (!have_range)) {
         /* This scope supplies just a single address range. */
         if (ip_lo < ip_hi1)
            varstack_push( cc, parser, td3, 
                           unitary_range_list(ip_lo, ip_hi1 - 1),
                           level, isFunc, fbGX );
      } else
      if ((!have_lo) && (!have_hi1) && have_range) {
         /* This scope supplies multiple address ranges via the use of
            a range list. */
         varstack_push( cc, parser, td3, 
                        get_range_list( cc, td3,
                                        rangeoff, cc->cu_svma ),
                        level, isFunc, fbGX );
      } else
      if (have_lo && (!have_hi1) && (!have_range)) {
         /* This scope is bogus.  The D3 spec sec 3.4 (Lexical Block
            Entries) says fairly clearly that a scope must have either
            _range or (_low_pc and _high_pc). */
         /* The spec is a bit ambiguous though.  Perhaps a single byte
            range is intended?  See sec 2.17 (Code Addresses And Ranges) */
         /* This case is here because icc9 produced this:
         <2><13bd>: DW_TAG_lexical_block
            DW_AT_decl_line   : 5229
            DW_AT_decl_column : 37
            DW_AT_decl_file   : 1
            DW_AT_low_pc      : 0x401b03
         */
         /* Ignore (seems safe than pushing a single byte range) */
      } else
         goto_bad_DIE;
   }

   if (dtag == DW_TAG_variable || dtag == DW_TAG_formal_parameter) {
      HChar* name        = NULL;
      UWord  typeR       = D3_INVALID_CUOFF;
      Bool   global      = False;
      GExpr* gexpr       = NULL;
      Int    n_attrs     = 0;
      UWord  abs_ori     = (UWord)D3_INVALID_CUOFF;
      Int    lineNo      = 0;
      HChar* fileName    = NULL;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         n_attrs++;
         if (attr == DW_AT_name && cts.szB < 0) {
            name = ML_(addStrFromCursor)( cc->di, cts.u.cur );
         }
         if (attr == DW_AT_location
             && cts.szB != 0 /* either scalar or nonempty block */) {
            gexpr = get_GX( cc, False/*td3*/, &cts );
            vg_assert(gexpr);
            VG_(addToXA)(gexprs, &gexpr);
         }
         if (attr == DW_AT_type && cts.szB > 0) {
            typeR = cook_die_using_form( cc, cts.u.val, form );
         }
         if (attr == DW_AT_external && cts.szB > 0 && cts.u.val > 0) {
            global = True;
         }
         if (attr == DW_AT_abstract_origin && cts.szB > 0) {
            abs_ori = (UWord)cts.u.val;
         }
         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
            /*declaration = True;*/
         }
         if (attr == DW_AT_decl_line && cts.szB > 0) {
            lineNo = (Int)cts.u.val;
         }
         if (attr == DW_AT_decl_file && cts.szB > 0) {
            Int ftabIx = (Int)cts.u.val;
            if (ftabIx >= 1
                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
               fileName = *(HChar**)
                          VG_(indexXA)( parser->filenameTable, ftabIx );
               vg_assert(fileName);
            }
            if (0) VG_(printf)("XXX filename = %s\n", fileName);
         }
      }
      if (!global && dtag == DW_TAG_variable && level == 1) {
         /* Case of a static variable. It is better to declare
            it global as the variable is not really related to
            a PC range, as its address can be used by program
            counters outside of the ranges where it is visible . */
         global = True;
      }

      /* We'll collect it under if one of the following three
         conditions holds:
         (1) has location and type    -> completed
         (2) has type only            -> is an abstract instance
         (3) has location and abs_ori -> is a concrete instance
         Name, filename and line number are all optional frills.
      */
      if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF) 
           /* 2 */ || (typeR != D3_INVALID_CUOFF)
           /* 3 */ || (gexpr && abs_ori != (UWord)D3_INVALID_CUOFF) ) {

         /* Add this variable to the list of interesting looking
            variables.  Crucially, note along with it the address
            range(s) associated with the variable, which for locals
            will be the address ranges at the top of the varparser's
            stack. */
         GExpr*   fbGX = NULL;
         Word     i, nRanges;
         XArray*  /* of AddrRange */ xa;
         TempVar* tv;
         /* Stack can't be empty; we put a dummy entry on it for the
            entire address range before starting with the DIEs for
            this CU. */
         vg_assert(parser->sp >= 0);

         /* If this is a local variable (non-global), try to find
            the GExpr for the DW_AT_frame_base of the containing
            function.  It should have been pushed on the stack at the
            time we encountered its DW_TAG_subprogram DIE, so the way
            to find it is to scan back down the stack looking for it.
            If there isn't an enclosing stack entry marked 'isFunc'
            then we must be seeing variable or formal param DIEs
            outside of a function, so we deem the Dwarf to be
            malformed if that happens.  Note that the fbGX may be NULL
            if the containing DT_TAG_subprogram didn't supply a
            DW_AT_frame_base -- that's OK, but there must actually be
            a containing DW_TAG_subprogram. */
         if (!global) {
            Bool found = False;
            for (i = parser->sp; i >= 0; i--) {
               if (parser->isFunc[i]) {
                  fbGX = parser->fbGX[i];
                  found = True;
                  break;
               }
            }
            if (!found) {
               if (0 && VG_(clo_verbosity) >= 0) {
                  VG_(message)(Vg_DebugMsg, 
                     "warning: parse_var_DIE: non-global variable "
                     "outside DW_TAG_subprogram\n");
               }
               /* goto_bad_DIE; */
               /* This seems to happen a lot.  Just ignore it -- if,
                  when we come to evaluation of the location (guarded)
                  expression, it requires a frame base value, and
                  there's no expression for that, then evaluation as a
                  whole will fail.  Harmless - a bit of a waste of
                  cycles but nothing more. */
            }
         }

         /* re "global ? 0 : parser->sp" (twice), if the var is
            marked 'global' then we must put it at the global scope,
            as only the global scope (level 0) covers the entire PC
            address space.  It is asserted elsewhere that level 0 
            always covers the entire address space. */
         xa = parser->ranges[global ? 0 : parser->sp];
         nRanges = VG_(sizeXA)(xa);
         vg_assert(nRanges >= 0);

         tv = ML_(dinfo_zalloc)( "di.readdwarf3.pvD.1", sizeof(TempVar) );
         tv->name   = name;
         tv->level  = global ? 0 : parser->sp;
         tv->typeR  = typeR;
         tv->gexpr  = gexpr;
         tv->fbGX   = fbGX;
         tv->fName  = fileName;
         tv->fLine  = lineNo;
         tv->dioff  = posn;
         tv->absOri = abs_ori;

         /* See explanation on definition of type TempVar for the
            reason for this elaboration. */
         tv->nRanges = nRanges;
         tv->rngOneMin = 0;
         tv->rngOneMax = 0;
         tv->rngMany = NULL;
         if (nRanges == 1) {
            AddrRange* range = VG_(indexXA)(xa, 0);
            tv->rngOneMin = range->aMin;
            tv->rngOneMax = range->aMax;
         }
         else if (nRanges > 1) {
            /* See if we already have a range list which is
               structurally identical.  If so, use that; if not, clone
               this one, and add it to our collection. */
            UWord keyW, valW;
            if (VG_(lookupFM)( rangestree, &keyW, &valW, (UWord)xa )) {
               XArray* old = (XArray*)keyW;
               tl_assert(valW == 0);
               tl_assert(old != xa);
               tv->rngMany = old;
            } else {
               XArray* cloned = VG_(cloneXA)( "di.readdwarf3.pvD.2", xa );
               tv->rngMany = cloned;
               VG_(addToFM)( rangestree, (UWord)cloned, 0 );
            }
         }

         VG_(addToXA)( tempvars, &tv );

         TRACE_D3("  Recording this variable, with %ld PC range(s)\n",
                  VG_(sizeXA)(xa) );
         /* collect stats on how effective the ->ranges special
            casing is */
         if (0) {
            static Int ntot=0, ngt=0;
            ntot++;
            if (tv->rngMany) ngt++;
            if (0 == (ntot % 100000))
               VG_(printf)("XXXX %d tot, %d cloned\n", ntot, ngt);
         }

      }

      /* Here are some other weird cases seen in the wild:

            We have a variable with a name and a type, but no
            location.  I guess that's a sign that it has been
            optimised away.  Ignore it.  Here's an example:

            static Int lc_compar(void* n1, void* n2) {
               MC_Chunk* mc1 = *(MC_Chunk**)n1;
               MC_Chunk* mc2 = *(MC_Chunk**)n2;
               return (mc1->data < mc2->data ? -1 : 1);
            }

            Both mc1 and mc2 are like this
            <2><5bc>: Abbrev Number: 21 (DW_TAG_variable)
                DW_AT_name        : mc1
                DW_AT_decl_file   : 1
                DW_AT_decl_line   : 216
                DW_AT_type        : <5d3>

            whereas n1 and n2 do have locations specified.

            ---------------------------------------------

            We see a DW_TAG_formal_parameter with a type, but
            no name and no location.  It's probably part of a function type
            construction, thusly, hence ignore it:
         <1><2b4>: Abbrev Number: 12 (DW_TAG_subroutine_type)
             DW_AT_sibling     : <2c9>
             DW_AT_prototyped  : 1
             DW_AT_type        : <114>
         <2><2be>: Abbrev Number: 13 (DW_TAG_formal_parameter)
             DW_AT_type        : <13e>
         <2><2c3>: Abbrev Number: 13 (DW_TAG_formal_parameter)
             DW_AT_type        : <133>

            ---------------------------------------------

            Is very minimal, like this:
            <4><81d>: Abbrev Number: 44 (DW_TAG_variable)
                DW_AT_abstract_origin: <7ba>
            What that signifies I have no idea.  Ignore.

            ----------------------------------------------

            Is very minimal, like this:
            <200f>: DW_TAG_formal_parameter
                DW_AT_abstract_ori: <1f4c>
                DW_AT_location    : 13440
            What that signifies I have no idea.  Ignore. 
            It might be significant, though: the variable at least
            has a location and so might exist somewhere.
            Maybe we should handle this.

            ---------------------------------------------

            <22407>: DW_TAG_variable
              DW_AT_name        : (indirect string, offset: 0x6579):
                                  vgPlain_trampoline_stuff_start
              DW_AT_decl_file   : 29
              DW_AT_decl_line   : 56
              DW_AT_external    : 1
              DW_AT_declaration : 1

            Nameless and typeless variable that has a location?  Who
            knows.  Not me.
            <2><3d178>: Abbrev Number: 22 (DW_TAG_variable)
                 DW_AT_location    : 9 byte block: 3 c0 c7 13 38 0 0 0 0
                                     (DW_OP_addr: 3813c7c0)

            No, really.  Check it out.  gcc is quite simply borked.
            <3><168cc>: Abbrev Number: 141 (DW_TAG_variable)
            // followed by no attributes, and the next DIE is a sibling,
            // not a child
            */
   }
   return;

  bad_DIE:
   dump_bad_die_and_barf(dtag, posn, level,
                         c_die, saved_die_c_offset,
                         abbv,
                         cc);
   /*NOTREACHED*/
}

typedef
   struct {
      /* The file name table.  Is a mapping from integer index to the
         (permanent) copy of the string in DebugInfo's .strchunks. */
      XArray* /* of UChar* */ filenameTable;
   }
   D3InlParser;

/* Return the function name corresponding to absori.
   The return value is a (permanent) string in DebugInfo's .strchunks. */
static HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3)
{
   Cursor c;
   g_abbv *abbv;
   ULong  atag, abbv_code;
   UInt   has_children;
   UWord  posn;
   HChar *ret = NULL;
   FormContents cts;
   UInt nf_i;

   init_Cursor (&c, cc->escn_debug_info, absori, cc->barf, 
                "Overrun get_inlFnName absori");

   posn      = cook_die( cc, get_position_of_Cursor( &c ) );
   abbv_code = get_ULEB128( &c );
   abbv      = get_abbv ( cc, abbv_code);
   atag      = abbv->atag;
   TRACE_D3("\n");
   TRACE_D3(" <get_inlFnName><%lx>: Abbrev Number: %llu (%s)\n",
            posn, abbv_code, ML_(pp_DW_TAG)( atag ) );

   if (atag == 0)
      cc->barf("get_inlFnName: invalid zero tag on DIE");

   has_children = abbv->has_children;
   if (has_children != DW_children_no && has_children != DW_children_yes)
      cc->barf("get_inlFnName: invalid has_children value");

   if (atag != DW_TAG_subprogram)
      cc->barf("get_inlFnName: absori not a subprogram");

   nf_i = 0;
   while (True) {
      DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
      DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
      nf_i++;
      if (attr == 0 && form == 0) break;
      get_Form_contents( &cts, cc, &c, False/*td3*/, form );
      if (attr == DW_AT_name) {
         HChar *fnname;
         if (cts.szB >= 0)
            cc->barf("get_inlFnName: expecting indirect string");
         fnname = ML_(cur_read_strdup)( cts.u.cur,
                                        "get_inlFnName.1" );
         ret = ML_(addStr)(cc->di, fnname, -1);
         ML_(dinfo_free) (fnname);
         break;
      }
   }

   if (ret)
      return ret;
   else
      return ML_(addStr)(cc->di, "AbsOriFnNameNotFound", -1);
}

/* Returns True if the (possibly) childrens of the current DIE are interesting
   to parse. Returns False otherwise.
   If the current DIE has a sibling, the non interesting children can
   maybe be skipped (if the DIE has a DW_AT_sibling).  */
__attribute__((noinline))
static Bool parse_inl_DIE (
   /*MOD*/D3InlParser* parser,
   DW_TAG dtag,
   UWord posn,
   Int level,
   Cursor* c_die,
   g_abbv *abbv,
   CUConst* cc,
   Bool td3
)
{
   FormContents cts;
   UInt nf_i;

   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );

   /* Get info about DW_TAG_compile_unit and DW_TAG_partial_unit 'which
      in theory could also contain inlined fn calls).  */
   if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit) {
      Bool have_lo    = False;
      Addr ip_lo    = 0;

      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_low_pc && cts.szB > 0) {
            ip_lo   = cts.u.val;
            have_lo = True;
         }
         if (attr == DW_AT_stmt_list && cts.szB > 0) {
            read_filename_table( parser->filenameTable, cc, cts.u.val, td3 );
         }
      }
      if (level == 0)
         setup_cu_svma (cc, have_lo, ip_lo, td3);
   }

   if (dtag == DW_TAG_inlined_subroutine) {
      Bool   have_lo    = False;
      Bool   have_hi1   = False;
      Bool   have_range = False;
      Bool   hiIsRelative = False;
      Addr   ip_lo      = 0;
      Addr   ip_hi1     = 0;
      Addr   rangeoff   = 0;
      HChar* caller_filename = NULL;
      Int caller_lineno = 0;
      Int inlinedfn_abstract_origin = 0;

      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_call_file && cts.szB > 0) {
            Int ftabIx = (Int)cts.u.val;
            if (ftabIx >= 1
                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
               caller_filename = *(HChar**)
                          VG_(indexXA)( parser->filenameTable, ftabIx );
               vg_assert(caller_filename);
            }
            if (0) VG_(printf)("XXX caller_filename = %s\n", caller_filename);
         }  
         if (attr == DW_AT_call_line && cts.szB > 0) {
            caller_lineno = cts.u.val;
         }  

         if (attr == DW_AT_abstract_origin  && cts.szB > 0) {
            inlinedfn_abstract_origin = cts.u.val;
         }

         if (attr == DW_AT_low_pc && cts.szB > 0) {
            ip_lo   = cts.u.val;
            have_lo = True;
         }
         if (attr == DW_AT_high_pc && cts.szB > 0) {
            ip_hi1   = cts.u.val;
            have_hi1 = True;
            if (form != DW_FORM_addr)
               hiIsRelative = True;
         }
         if (attr == DW_AT_ranges && cts.szB > 0) {
            rangeoff   = cts.u.val;
            have_range = True;
         }
      }
      if (have_lo && have_hi1 && hiIsRelative)
         ip_hi1 += ip_lo;
      /* Do we have something that looks sane? */
      if (dtag == DW_TAG_inlined_subroutine
          && (!have_lo) && (!have_hi1) && (!have_range)) {
         /* Seems strange. How can an inlined subroutine have
            no code ? */
         goto_bad_DIE;
      } else
      if (have_lo && have_hi1 && (!have_range)) {
         /* This inlined call is just a single address range. */
         if (ip_lo < ip_hi1) {
            ML_(addInlInfo) (cc->di,
                             ip_lo, ip_hi1, 
                             get_inlFnName (inlinedfn_abstract_origin, cc, td3),
                             caller_filename,
                             NULL, // INLINED TBD dirname ?????
                             caller_lineno, level);
         }
      } else if (have_range) {
         /* This inlined call is several address ranges. */
         XArray *ranges;
         Word j;
         HChar *inlfnname = get_inlFnName (inlinedfn_abstract_origin, cc, td3);

         ranges = get_range_list( cc, td3,
                                  rangeoff, cc->cu_svma );
         for (j = 0; j < VG_(sizeXA)( ranges ); j++) {
            AddrRange* range = (AddrRange*) VG_(indexXA)( ranges, j );
            ML_(addInlInfo) (cc->di,
                             range->aMin, range->aMax+1,
                             // aMax+1 as range has its last bound included
                             // while ML_(addInlInfo) expects last bound not
                             // included.
                             inlfnname,
                             caller_filename,
                             NULL, // INLINED TBD dirname ?????
                             caller_lineno, level);
         }
         VG_(deleteXA)( ranges );
      } else
         goto_bad_DIE;
   }

   // Only recursively parse the (possible) children for the DIE which
   // might maybe contain a DW_TAG_inlined_subroutine:
   return dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram
      || dtag == DW_TAG_inlined_subroutine
      || dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit;

  bad_DIE:
   dump_bad_die_and_barf(dtag, posn, level,
                         c_die, saved_die_c_offset,
                         abbv,
                         cc);
   /*NOTREACHED*/
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Parsing of type-related DIEs                         ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

#define N_D3_TYPE_STACK 16

typedef
   struct {
      /* What source language?  'A'=Ada83/95,
                                'C'=C/C++, 
                                'F'=Fortran,
                                '?'=other
         Established once per compilation unit. */
      UChar language;
      /* A stack of types which are currently under construction */
      Int   sp; /* [sp] is innermost active entry; sp==-1 for empty
                   stack */
      /* Note that the TyEnts in qparentE are temporary copies of the
         ones accumulating in the main tyent array.  So it is not safe
         to free up anything on them when popping them off the stack
         (iow, it isn't safe to use TyEnt__make_EMPTY on them).  Just
         memset them to zero when done. */
      TyEnt qparentE[N_D3_TYPE_STACK]; /* parent TyEnts */
      Int   qlevel[N_D3_TYPE_STACK];

   }
   D3TypeParser;

static void typestack_show ( D3TypeParser* parser, const HChar* str ) {
   Word i;
   VG_(printf)("  typestack (%s) {\n", str);
   for (i = 0; i <= parser->sp; i++) {
      VG_(printf)("    [%ld] (level %d): ", i, parser->qlevel[i]);
      ML_(pp_TyEnt)( &parser->qparentE[i] );
      VG_(printf)("\n");
   }
   VG_(printf)("  }\n");
}

/* Remove from the stack, all entries with .level > 'level' */
static 
void typestack_preen ( D3TypeParser* parser, Bool td3, Int level )
{
   Bool changed = False;
   vg_assert(parser->sp < N_D3_TYPE_STACK);
   while (True) {
      vg_assert(parser->sp >= -1);
      if (parser->sp == -1) break;
      if (parser->qlevel[parser->sp] <= level) break;
      if (0) 
         TRACE_D3("BBBBAAAA typestack_pop [newsp=%d]\n", parser->sp-1);
      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
      VG_(memset)(&parser->qparentE[parser->sp], 0, sizeof(TyEnt));
      parser->qparentE[parser->sp].cuOff = D3_INVALID_CUOFF;
      parser->qparentE[parser->sp].tag = Te_EMPTY;
      parser->qlevel[parser->sp] = 0;
      parser->sp--;
      changed = True;
   }
   if (changed && td3)
      typestack_show( parser, "after preen" );
}

static Bool typestack_is_empty ( D3TypeParser* parser ) {
   vg_assert(parser->sp >= -1 && parser->sp < N_D3_TYPE_STACK);
   return parser->sp == -1;
}

static void typestack_push ( CUConst* cc,
                             D3TypeParser* parser,
                             Bool td3,
                             TyEnt* parentE, Int level ) {
   if (0)
   TRACE_D3("BBBBAAAA typestack_push[newsp=%d]: %d  %05lx\n",
            parser->sp+1, level, parentE->cuOff);

   /* First we need to zap everything >= 'level', as we are about to
      replace any previous entry at 'level', so .. */
   typestack_preen(parser, /*td3*/False, level-1);

   vg_assert(parser->sp >= -1);
   vg_assert(parser->sp < N_D3_TYPE_STACK);
   if (parser->sp == N_D3_TYPE_STACK-1)
      cc->barf("typestack_push: N_D3_TYPE_STACK is too low; "
               "increase and recompile");
   if (parser->sp >= 0)
      vg_assert(parser->qlevel[parser->sp] < level);
   parser->sp++;
   vg_assert(parser->qparentE[parser->sp].tag == Te_EMPTY);
   vg_assert(parser->qlevel[parser->sp]  == 0);
   vg_assert(parentE);
   vg_assert(ML_(TyEnt__is_type)(parentE));
   vg_assert(parentE->cuOff != D3_INVALID_CUOFF);
   parser->qparentE[parser->sp] = *parentE;
   parser->qlevel[parser->sp]  = level;
   if (td3)
      typestack_show( parser, "after push" );
}

/* True if the subrange type being parsed gives the bounds of an array. */
static Bool subrange_type_denotes_array_bounds ( D3TypeParser* parser,
                                                 DW_TAG dtag ) {
   vg_assert(dtag == DW_TAG_subrange_type);
   /* For most languages, a subrange_type dtag always gives the 
      bounds of an array.
      For Ada, there are additional conditions as a subrange_type
      is also used for other purposes. */
   if (parser->language != 'A')
      /* not Ada, so it definitely denotes an array bound. */
      return True;
   else
      /* Extra constraints for Ada: it only denotes an array bound if .. */
      return (! typestack_is_empty(parser)
              && parser->qparentE[parser->sp].tag == Te_TyArray);
}

/* Parse a type-related DIE.  'parser' holds the current parser state.
   'admin' is where the completed types are dumped.  'dtag' is the tag
   for this DIE.  'c_die' points to the start of the data fields (FORM
   stuff) for the DIE.  abbv is the parsed abbreviation which describe
   the DIE.

   We may find the DIE uninteresting, in which case we should ignore
   it.

   What happens: the DIE is examined.  If uninteresting, it is ignored.
   Otherwise, the DIE gives rise to two things:

   (1) the offset of this DIE in the CU -- the cuOffset, a UWord
   (2) a TyAdmin structure, which holds the type, or related stuff

   (2) is added at the end of 'tyadmins', at some index, say 'i'.

   A pair (cuOffset, i) is added to 'tydict'.

   Hence 'tyadmins' holds the actual type entities, and 'tydict' holds
   a mapping from cuOffset to the index of the corresponding entry in
   'tyadmin'.

   When resolving a cuOffset to a TyAdmin, first look up the cuOffset
   in the tydict (by binary search).  This gives an index into
   tyadmins, and the required entity lives in tyadmins at that index.
*/
__attribute__((noinline))
static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
                             /*MOD*/D3TypeParser* parser,
                             DW_TAG dtag,
                             UWord posn,
                             Int level,
                             Cursor* c_die,
                             g_abbv *abbv,
                             CUConst* cc,
                             Bool td3 )
{
   FormContents cts;
   UInt nf_i;
   TyEnt typeE;
   TyEnt atomE;
   TyEnt fieldE;
   TyEnt boundE;

   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );

   VG_(memset)( &typeE,  0xAA, sizeof(typeE) );
   VG_(memset)( &atomE,  0xAA, sizeof(atomE) );
   VG_(memset)( &fieldE, 0xAA, sizeof(fieldE) );
   VG_(memset)( &boundE, 0xAA, sizeof(boundE) );

   /* If we've returned to a level at or above any previously noted
      parent, un-note it, so we don't believe we're still collecting
      its children. */
   typestack_preen( parser, td3, level-1 );

   if (dtag == DW_TAG_compile_unit
       || dtag == DW_TAG_type_unit
       || dtag == DW_TAG_partial_unit) {
      /* See if we can find DW_AT_language, since it is important for
         establishing array bounds (see DW_TAG_subrange_type below in
         this fn) */
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr != DW_AT_language)
            continue;
         if (cts.szB <= 0)
           goto_bad_DIE;
         switch (cts.u.val) {
            case DW_LANG_C89: case DW_LANG_C:
            case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
            case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
            case DW_LANG_Upc: case DW_LANG_C99:
               parser->language = 'C'; break;
            case DW_LANG_Fortran77: case DW_LANG_Fortran90:
            case DW_LANG_Fortran95:
               parser->language = 'F'; break;
            case DW_LANG_Ada83: case DW_LANG_Ada95: 
               parser->language = 'A'; break;
            case DW_LANG_Cobol74:
            case DW_LANG_Cobol85: case DW_LANG_Pascal83:
            case DW_LANG_Modula2: case DW_LANG_Java:
            case DW_LANG_PLI:
            case DW_LANG_D: case DW_LANG_Python:
            case DW_LANG_Mips_Assembler:
               parser->language = '?'; break;
            default:
               goto_bad_DIE;
         }
      }
   }

   if (dtag == DW_TAG_base_type) {
      /* We can pick up a new base type any time. */
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = D3_INVALID_CUOFF;
      typeE.tag   = Te_TyBase;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_name && cts.szB < 0) {
            typeE.Te.TyBase.name
               = ML_(cur_read_strdup)( cts.u.cur,
                                       "di.readdwarf3.ptD.base_type.1" );
         }
         if (attr == DW_AT_byte_size && cts.szB > 0) {
            typeE.Te.TyBase.szB = cts.u.val;
         }
         if (attr == DW_AT_encoding && cts.szB > 0) {
            switch (cts.u.val) {
               case DW_ATE_unsigned: case DW_ATE_unsigned_char:
               case DW_ATE_UTF: /* since DWARF4, e.g. char16_t from C++ */
               case DW_ATE_boolean:/* FIXME - is this correct? */
               case DW_ATE_unsigned_fixed:
                  typeE.Te.TyBase.enc = 'U'; break;
               case DW_ATE_signed: case DW_ATE_signed_char:
               case DW_ATE_signed_fixed:
                  typeE.Te.TyBase.enc = 'S'; break;
               case DW_ATE_float:
                  typeE.Te.TyBase.enc = 'F'; break;
               case DW_ATE_complex_float:
                  typeE.Te.TyBase.enc = 'C'; break;
               default:
                  goto_bad_DIE;
            }
         }
      }

      /* Invent a name if it doesn't have one.  gcc-4.3
         -ftree-vectorize is observed to emit nameless base types. */
      if (!typeE.Te.TyBase.name)
         typeE.Te.TyBase.name 
            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.2",
                                 "<anon_base_type>" );

      /* Do we have something that looks sane? */
      if (/* must have a name */
          typeE.Te.TyBase.name == NULL
          /* and a plausible size.  Yes, really 32: "complex long
             double" apparently has size=32 */
          || typeE.Te.TyBase.szB < 0 || typeE.Te.TyBase.szB > 32
          /* and a plausible encoding */
          || (typeE.Te.TyBase.enc != 'U'
              && typeE.Te.TyBase.enc != 'S' 
              && typeE.Te.TyBase.enc != 'F'
              && typeE.Te.TyBase.enc != 'C'))
         goto_bad_DIE;
      /* Last minute hack: if we see this
         <1><515>: DW_TAG_base_type
             DW_AT_byte_size   : 0
             DW_AT_encoding    : 5
             DW_AT_name        : void
         convert it into a real Void type. */
      if (typeE.Te.TyBase.szB == 0
          && 0 == VG_(strcmp)("void", typeE.Te.TyBase.name)) {
         ML_(TyEnt__make_EMPTY)(&typeE);
         typeE.tag = Te_TyVoid;
         typeE.Te.TyVoid.isFake = False; /* it's a real one! */
      }

      goto acquire_Type;
   }

   /*
    * An example of DW_TAG_rvalue_reference_type:
    *
    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
    *  <1><1014>: Abbrev Number: 55 (DW_TAG_rvalue_reference_type)
    *     <1015>   DW_AT_byte_size   : 4
    *     <1016>   DW_AT_type        : <0xe52>
    */
   if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type
       || dtag == DW_TAG_ptr_to_member_type
       || dtag == DW_TAG_rvalue_reference_type) {
      /* This seems legit for _pointer_type and _reference_type.  I
         don't know if rolling _ptr_to_member_type in here really is
         legit, but it's better than not handling it at all. */
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = D3_INVALID_CUOFF;
      switch (dtag) {
      case DW_TAG_pointer_type:
         typeE.tag = Te_TyPtr;
         break;
      case DW_TAG_reference_type:
         typeE.tag = Te_TyRef;
         break;
      case DW_TAG_ptr_to_member_type:
         typeE.tag = Te_TyPtrMbr;
         break;
      case DW_TAG_rvalue_reference_type:
         typeE.tag = Te_TyRvalRef;
         break;
      default:
         vg_assert(False);
      }
      /* target type defaults to void */
      typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
      /* These four type kinds don't *have* to specify their size, in
         which case we assume it's a machine word.  But if they do
         specify it, it must be a machine word :-)  This probably
         assumes that the word size of the Dwarf3 we're reading is the
         same size as that on the machine.  gcc appears to give a size
         whereas icc9 doesn't. */
      typeE.Te.TyPorR.szB = sizeof(UWord);
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_byte_size && cts.szB > 0) {
            typeE.Te.TyPorR.szB = cts.u.val;
         }
         if (attr == DW_AT_type && cts.szB > 0) {
            typeE.Te.TyPorR.typeR
               = cook_die_using_form( cc, (UWord)cts.u.val, form );
         }
      }
      /* Do we have something that looks sane? */
      if (typeE.Te.TyPorR.szB != sizeof(UWord))
         goto_bad_DIE;
      else
         goto acquire_Type;
   }

   if (dtag == DW_TAG_enumeration_type) {
      /* Create a new Type to hold the results. */
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = posn;
      typeE.tag   = Te_TyEnum;
      Bool is_decl = False;
      typeE.Te.TyEnum.atomRs
         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1", 
                       ML_(dinfo_free),
                       sizeof(UWord) );
      nf_i=0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_name && cts.szB < 0) {
            typeE.Te.TyEnum.name
               = ML_(cur_read_strdup)( cts.u.cur,
                                       "di.readdwarf3.pTD.enum_type.2" );
         }
         if (attr == DW_AT_byte_size && cts.szB > 0) {
            typeE.Te.TyEnum.szB = cts.u.val;
         }
         if (attr == DW_AT_declaration) {
            is_decl = True;
         }
      }

      if (!typeE.Te.TyEnum.name)
         typeE.Te.TyEnum.name 
            = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
                                 "<anon_enum_type>" );

      /* Do we have something that looks sane? */
      if (typeE.Te.TyEnum.szB == 0 
          /* we must know the size */
          /* but not for Ada, which uses such dummy
             enumerations as helper for gdb ada mode.
             Also GCC allows incomplete enums as GNU extension.
             http://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html
             These are marked as DW_AT_declaration and won't have
             a size. They can only be used in declaration or as
             pointer types.  You can't allocate variables or storage
             using such an enum type. (Also GCC seems to have a bug
             that will put such an enumeration_type into a .debug_types
             unit which should only contain complete types.) */
          && (parser->language != 'A' && !is_decl)) {
         goto_bad_DIE;
      }

      /* On't stack! */
      typestack_push( cc, parser, td3, &typeE, level );
      goto acquire_Type;
   }

   /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces
      DW_TAG_enumerator with only a DW_AT_name but no
      DW_AT_const_value.  This is in violation of the Dwarf3 standard,
      and appears to be a new "feature" of gcc - versions 4.3.x and
      earlier do not appear to do this.  So accept DW_TAG_enumerator
      which only have a name but no value.  An example:

      <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type)
         <181>   DW_AT_name        : (indirect string, offset: 0xda70):
                                     QtMsgType
         <185>   DW_AT_byte_size   : 4
         <186>   DW_AT_decl_file   : 14
         <187>   DW_AT_decl_line   : 1480
         <189>   DW_AT_sibling     : <0x1a7>
      <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator)
         <18e>   DW_AT_name        : (indirect string, offset: 0x9e18):
                                     QtDebugMsg
      <2><192>: Abbrev Number: 7 (DW_TAG_enumerator)
         <193>   DW_AT_name        : (indirect string, offset: 0x1505f):
                                     QtWarningMsg
      <2><197>: Abbrev Number: 7 (DW_TAG_enumerator)
         <198>   DW_AT_name        : (indirect string, offset: 0x16f4a):
                                     QtCriticalMsg
      <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator)
         <19d>   DW_AT_name        : (indirect string, offset: 0x156dd):
                                     QtFatalMsg
      <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator)
         <1a2>   DW_AT_name        : (indirect string, offset: 0x13660):
                                     QtSystemMsg
   */
   if (dtag == DW_TAG_enumerator) {
      VG_(memset)( &atomE, 0, sizeof(atomE) );
      atomE.cuOff = posn;
      atomE.tag   = Te_Atom;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_name && cts.szB < 0) {
            atomE.Te.Atom.name 
              = ML_(cur_read_strdup)( cts.u.cur,
                                      "di.readdwarf3.pTD.enumerator.1" );
         }
         if (attr == DW_AT_const_value && cts.szB > 0) {
            atomE.Te.Atom.value      = cts.u.val;
            atomE.Te.Atom.valueKnown = True;
         }
      }
      /* Do we have something that looks sane? */
      if (atomE.Te.Atom.name == NULL)
         goto_bad_DIE;
      /* Do we have a plausible parent? */
      if (typestack_is_empty(parser)) goto_bad_DIE;
      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
      if (parser->qparentE[parser->sp].tag != Te_TyEnum) goto_bad_DIE;
      /* Record this child in the parent */
      vg_assert(parser->qparentE[parser->sp].Te.TyEnum.atomRs);
      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyEnum.atomRs,
                    &atomE );
      /* And record the child itself */
      goto acquire_Atom;
   }

   /* Treat DW_TAG_class_type as if it was a DW_TAG_structure_type.  I
      don't know if this is correct, but it at least makes this reader
      usable for gcc-4.3 produced Dwarf3. */
   if (dtag == DW_TAG_structure_type || dtag == DW_TAG_class_type
       || dtag == DW_TAG_union_type) {
      Bool have_szB = False;
      Bool is_decl  = False;
      Bool is_spec  = False;
      /* Create a new Type to hold the results. */
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = posn;
      typeE.tag   = Te_TyStOrUn;
      typeE.Te.TyStOrUn.name = NULL;
      typeE.Te.TyStOrUn.typeR = D3_INVALID_CUOFF;
      typeE.Te.TyStOrUn.fieldRs
         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1", 
                       ML_(dinfo_free),
                       sizeof(UWord) );
      typeE.Te.TyStOrUn.complete = True;
      typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type 
                                   || dtag == DW_TAG_class_type;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_name && cts.szB < 0) {
            typeE.Te.TyStOrUn.name
               = ML_(cur_read_strdup)( cts.u.cur,
                                       "di.readdwarf3.ptD.struct_type.2" );
         }
         if (attr == DW_AT_byte_size && cts.szB >= 0) {
            typeE.Te.TyStOrUn.szB = cts.u.val;
            have_szB = True;
         }
         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
            is_decl = True;
         }
         if (attr == DW_AT_specification && cts.szB > 0 && cts.u.val > 0) {
            is_spec = True;
         }
         if (attr == DW_AT_signature && form == DW_FORM_ref_sig8
             && cts.szB > 0) {
            have_szB = True;
            typeE.Te.TyStOrUn.szB = 8;
            typeE.Te.TyStOrUn.typeR
               = cook_die_using_form( cc, (UWord)cts.u.val, form );
         }
      }
      /* Do we have something that looks sane? */
      if (is_decl && (!is_spec)) {
         /* It's a DW_AT_declaration.  We require the name but
            nothing else. */
         /* JRS 2012-06-28: following discussion w/ tromey, if the the
            type doesn't have name, just make one up, and accept it.
            It might be referred to by other DIEs, so ignoring it
            doesn't seem like a safe option. */
         if (typeE.Te.TyStOrUn.name == NULL)
            typeE.Te.TyStOrUn.name
               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.struct_type.3",
                                    "<anon_struct_type>" );
         typeE.Te.TyStOrUn.complete = False;
         /* JRS 2009 Aug 10: <possible kludge>? */
         /* Push this tyent on the stack, even though it's incomplete.
            It appears that gcc-4.4 on Fedora 11 will sometimes create
            DW_TAG_member entries for it, and so we need to have a
            plausible parent present in order for that to work.  See
            #200029 comments 8 and 9. */
         typestack_push( cc, parser, td3, &typeE, level );
         /* </possible kludge> */
         goto acquire_Type;
      }
      if ((!is_decl) /* && (!is_spec) */) {
         /* this is the common, ordinary case */
         /* The name can be present, or not */
         if (!have_szB) { 
            /* We must know the size.
               But in Ada, record with discriminants might have no size.
               But in C, VLA in the middle of a struct (gcc extension)
               might have no size.
               Instead, some GNAT dwarf extensions and/or dwarf entries
               allow to calculate the struct size at runtime.
               We cannot do that (yet?) so, the temporary kludge is to use
               a small size. */
            typeE.Te.TyStOrUn.szB = 1;
         }
         /* On't stack! */
         typestack_push( cc, parser, td3, &typeE, level );
         goto acquire_Type;
      }
      else {
         /* don't know how to handle any other variants just now */
         goto_bad_DIE;
      }
   }

   if (dtag == DW_TAG_member) {
      /* Acquire member entries for both DW_TAG_structure_type and
         DW_TAG_union_type.  They differ minorly, in that struct
         members must have a DW_AT_data_member_location expression
         whereas union members must not. */
      Bool parent_is_struct;
      VG_(memset)( &fieldE, 0, sizeof(fieldE) );
      fieldE.cuOff = posn;
      fieldE.tag   = Te_Field;
      fieldE.Te.Field.typeR = D3_INVALID_CUOFF;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_name && cts.szB < 0) {
            fieldE.Te.Field.name
               = ML_(cur_read_strdup)( cts.u.cur,
                                       "di.readdwarf3.ptD.member.1" );
         }
         if (attr == DW_AT_type && cts.szB > 0) {
            fieldE.Te.Field.typeR
               = cook_die_using_form( cc, (UWord)cts.u.val, form );
         }
         /* There are 2 different cases for DW_AT_data_member_location.
            If it is a constant class attribute, it contains byte offset
            from the beginning of the containing entity.
            Otherwise it is a location expression.  */
         if (attr == DW_AT_data_member_location && cts.szB > 0) {
            fieldE.Te.Field.nLoc = -1;
            fieldE.Te.Field.pos.offset = cts.u.val;
         }
         if (attr == DW_AT_data_member_location && cts.szB <= 0) {
            fieldE.Te.Field.nLoc = (UWord)(-cts.szB);
            fieldE.Te.Field.pos.loc
               = ML_(cur_read_memdup)( cts.u.cur, 
                                       (SizeT)fieldE.Te.Field.nLoc,
                                       "di.readdwarf3.ptD.member.2" );
         }
      }
      /* Do we have a plausible parent? */
      if (typestack_is_empty(parser)) goto_bad_DIE;
      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
      if (parser->qparentE[parser->sp].tag != Te_TyStOrUn) goto_bad_DIE;
      /* Do we have something that looks sane?  If this a member of a
         struct, we must have a location expression; but if a member
         of a union that is irrelevant (D3 spec sec 5.6.6).  We ought
         to reject in the latter case, but some compilers have been
         observed to emit constant-zero expressions.  So just ignore
         them. */
      parent_is_struct
         = parser->qparentE[parser->sp].Te.TyStOrUn.isStruct;
      if (!fieldE.Te.Field.name)
         fieldE.Te.Field.name
            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.3",
                                 "<anon_field>" );
      vg_assert(fieldE.Te.Field.name);
      if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
         goto_bad_DIE;
      if (fieldE.Te.Field.nLoc) {
         if (!parent_is_struct) {
            /* If this is a union type, pretend we haven't seen the data
               member location expression, as it is by definition
               redundant (it must be zero). */
            if (fieldE.Te.Field.nLoc > 0)
               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
            fieldE.Te.Field.pos.loc = NULL;
            fieldE.Te.Field.nLoc = 0;
         }
         /* Record this child in the parent */
         fieldE.Te.Field.isStruct = parent_is_struct;
         vg_assert(parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs);
         VG_(addToXA)( parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs,
                       &posn );
         /* And record the child itself */
         goto acquire_Field;
      } else {
         /* Member with no location - this can happen with static
            const members in C++ code which are compile time constants
            that do no exist in the class. They're not of any interest
            to us so we ignore them. */
         ML_(TyEnt__make_EMPTY)(&fieldE);
      }
   }

   if (dtag == DW_TAG_array_type) {
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = posn;
      typeE.tag   = Te_TyArray;
      typeE.Te.TyArray.typeR = D3_INVALID_CUOFF;
      typeE.Te.TyArray.boundRs
         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1",
                       ML_(dinfo_free),
                       sizeof(UWord) );
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_type && cts.szB > 0) {
            typeE.Te.TyArray.typeR
               = cook_die_using_form( cc, (UWord)cts.u.val, form );
         }
      }
      if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF)
         goto_bad_DIE;
      /* On't stack! */
      typestack_push( cc, parser, td3, &typeE, level );
      goto acquire_Type;
   }

   /* this is a subrange type defining the bounds of an array. */
   if (dtag == DW_TAG_subrange_type 
       && subrange_type_denotes_array_bounds(parser, dtag)) {
      Bool have_lower = False;
      Bool have_upper = False;
      Bool have_count = False;
      Long lower = 0;
      Long upper = 0;

      switch (parser->language) {
         case 'C': have_lower = True;  lower = 0; break;
         case 'F': have_lower = True;  lower = 1; break;
         case '?': have_lower = False; break;
         case 'A': have_lower = False; break;
         default:  vg_assert(0); /* assured us by handling of
                                    DW_TAG_compile_unit in this fn */
      }

      VG_(memset)( &boundE, 0, sizeof(boundE) );
      boundE.cuOff = D3_INVALID_CUOFF;
      boundE.tag   = Te_Bound;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_lower_bound && cts.szB > 0) {
            lower      = (Long)cts.u.val;
            have_lower = True;
         }
         if (attr == DW_AT_upper_bound && cts.szB > 0) {
            upper      = (Long)cts.u.val;
            have_upper = True;
         }
         if (attr == DW_AT_count && cts.szB > 0) {
            /*count    = (Long)cts.u.val;*/
            have_count = True;
         }
      }
      /* FIXME: potentially skip the rest if no parent present, since
         it could be the case that this subrange type is free-standing
         (not being used to describe the bounds of a containing array
         type) */
      /* Do we have a plausible parent? */
      if (typestack_is_empty(parser)) goto_bad_DIE;
      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
      if (parser->qparentE[parser->sp].tag != Te_TyArray) goto_bad_DIE;

      /* Figure out if we have a definite range or not */
      if (have_lower && have_upper && (!have_count)) {
         boundE.Te.Bound.knownL = True;
         boundE.Te.Bound.knownU = True;
         boundE.Te.Bound.boundL = lower;
         boundE.Te.Bound.boundU = upper;
      }
      else if (have_lower && (!have_upper) && (!have_count)) {
         boundE.Te.Bound.knownL = True;
         boundE.Te.Bound.knownU = False;
         boundE.Te.Bound.boundL = lower;
         boundE.Te.Bound.boundU = 0;
      }
      else if ((!have_lower) && have_upper && (!have_count)) {
         boundE.Te.Bound.knownL = False;
         boundE.Te.Bound.knownU = True;
         boundE.Te.Bound.boundL = 0;
         boundE.Te.Bound.boundU = upper;
      }
      else if ((!have_lower) && (!have_upper) && (!have_count)) {
         boundE.Te.Bound.knownL = False;
         boundE.Te.Bound.knownU = False;
         boundE.Te.Bound.boundL = 0;
         boundE.Te.Bound.boundU = 0;
      } else {
         /* FIXME: handle more cases */
         goto_bad_DIE;
      }

      /* Record this bound in the parent */
      boundE.cuOff = posn;
      vg_assert(parser->qparentE[parser->sp].Te.TyArray.boundRs);
      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyArray.boundRs,
                    &boundE.cuOff );
      /* And record the child itself */
      goto acquire_Bound;
   }

   /* typedef or subrange_type other than array bounds. */
   if (dtag == DW_TAG_typedef 
       || (dtag == DW_TAG_subrange_type 
           && !subrange_type_denotes_array_bounds(parser, dtag))) {
      /* subrange_type other than array bound is only for Ada. */
      vg_assert (dtag == DW_TAG_typedef || parser->language == 'A');
      /* We can pick up a new typedef/subrange_type any time. */
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = D3_INVALID_CUOFF;
      typeE.tag   = Te_TyTyDef;
      typeE.Te.TyTyDef.name = NULL;
      typeE.Te.TyTyDef.typeR = D3_INVALID_CUOFF;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_name && cts.szB < 0) {
            typeE.Te.TyTyDef.name
               = ML_(cur_read_strdup)( cts.u.cur,
                                       "di.readdwarf3.ptD.typedef.1" );
         }
         if (attr == DW_AT_type && cts.szB > 0) {
            typeE.Te.TyTyDef.typeR
               = cook_die_using_form( cc, (UWord)cts.u.val, form );
         }
      }
      /* Do we have something that looks sane?
         gcc gnat Ada generates minimal typedef
         such as the below
         <6><91cc>: DW_TAG_typedef
            DW_AT_abstract_ori: <9066>
         g++ for OMP can generate artificial functions that have
         parameters that refer to pointers to unnamed typedefs.
         See https://bugs.kde.org/show_bug.cgi?id=273475
         So we cannot require a name for a DW_TAG_typedef.
      */
      goto acquire_Type;
   }

   if (dtag == DW_TAG_subroutine_type) {
      /* function type? just record that one fact and ask no
         further questions. */
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = D3_INVALID_CUOFF;
      typeE.tag   = Te_TyFn;
      goto acquire_Type;
   }

   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type) {
      Int have_ty = 0;
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff = D3_INVALID_CUOFF;
      typeE.tag   = Te_TyQual;
      typeE.Te.TyQual.qual
         = dtag == DW_TAG_volatile_type ? 'V' : 'C';
      /* target type defaults to 'void' */
      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
      nf_i = 0;
      while (True) {
         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
         nf_i++;
         if (attr == 0 && form == 0) break;
         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
         if (attr == DW_AT_type && cts.szB > 0) {
            typeE.Te.TyQual.typeR
               = cook_die_using_form( cc, (UWord)cts.u.val, form );
            have_ty++;
         }
      }
      /* gcc sometimes generates DW_TAG_const/volatile_type without
         DW_AT_type and GDB appears to interpret the type as 'const
         void' (resp. 'volatile void').  So just allow it .. */
      if (have_ty == 1 || have_ty == 0)
         goto acquire_Type;
      else
         goto_bad_DIE;
   }

   /*
    * Treat DW_TAG_unspecified_type as type void. An example of DW_TAG_unspecified_type:
    *
    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
    *  <1><10d4>: Abbrev Number: 53 (DW_TAG_unspecified_type)
    *     <10d5>   DW_AT_name        : (indirect string, offset: 0xdb7): decltype(nullptr)
    */
   if (dtag == DW_TAG_unspecified_type) {
      VG_(memset)(&typeE, 0, sizeof(typeE));
      typeE.cuOff           = D3_INVALID_CUOFF;
      typeE.tag             = Te_TyQual;
      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
      goto acquire_Type;
   }

   /* else ignore this DIE */
   return;
   /*NOTREACHED*/

  acquire_Type:
   if (0) VG_(printf)("YYYY Acquire Type\n");
   vg_assert(ML_(TyEnt__is_type)( &typeE ));
   vg_assert(typeE.cuOff == D3_INVALID_CUOFF || typeE.cuOff == posn);
   typeE.cuOff = posn;
   VG_(addToXA)( tyents, &typeE );
   return;
   /*NOTREACHED*/

  acquire_Atom:
   if (0) VG_(printf)("YYYY Acquire Atom\n");
   vg_assert(atomE.tag == Te_Atom);
   vg_assert(atomE.cuOff == D3_INVALID_CUOFF || atomE.cuOff == posn);
   atomE.cuOff = posn;
   VG_(addToXA)( tyents, &atomE );
   return;
   /*NOTREACHED*/

  acquire_Field:
   /* For union members, Expr should be absent */
   if (0) VG_(printf)("YYYY Acquire Field\n");
   vg_assert(fieldE.tag == Te_Field);
   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
   if (fieldE.Te.Field.isStruct) {
      vg_assert(fieldE.Te.Field.nLoc != 0);
   } else {
      vg_assert(fieldE.Te.Field.nLoc == 0);
   }
   vg_assert(fieldE.cuOff == D3_INVALID_CUOFF || fieldE.cuOff == posn);
   fieldE.cuOff = posn;
   VG_(addToXA)( tyents, &fieldE );
   return;
   /*NOTREACHED*/

  acquire_Bound:
   if (0) VG_(printf)("YYYY Acquire Bound\n");
   vg_assert(boundE.tag == Te_Bound);
   vg_assert(boundE.cuOff == D3_INVALID_CUOFF || boundE.cuOff == posn);
   boundE.cuOff = posn;
   VG_(addToXA)( tyents, &boundE );
   return;
   /*NOTREACHED*/

  bad_DIE:
   dump_bad_die_and_barf(dtag, posn, level,
                         c_die, saved_die_c_offset,
                         abbv,
                         cc);
   /*NOTREACHED*/
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Compression of type DIE information                  ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

static UWord chase_cuOff ( Bool* changed,
                           XArray* /* of TyEnt */ ents,
                           TyEntIndexCache* ents_cache,
                           UWord cuOff )
{
   TyEnt* ent;
   ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff );

   if (!ent) {
      VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff);
      *changed = False;
      return cuOff;
   }

   vg_assert(ent->tag != Te_EMPTY);
   if (ent->tag != Te_INDIR) {
      *changed = False;
      return cuOff;
   } else {
      vg_assert(ent->Te.INDIR.indR < cuOff);
      *changed = True;
      return ent->Te.INDIR.indR;
   }
}

static
void chase_cuOffs_in_XArray ( Bool* changed,
                              XArray* /* of TyEnt */ ents,
                              TyEntIndexCache* ents_cache,
                              /*MOD*/XArray* /* of UWord */ cuOffs )
{
   Bool b2 = False;
   Word i, n = VG_(sizeXA)( cuOffs );
   for (i = 0; i < n; i++) {
      Bool   b = False;
      UWord* p = VG_(indexXA)( cuOffs, i );
      *p = chase_cuOff( &b, ents, ents_cache, *p );
      if (b)
         b2 = True;
   }
   *changed = b2;
}

static Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents,
                                    TyEntIndexCache* ents_cache,
                                    /*MOD*/TyEnt* te )
{
   Bool b, changed = False;
   switch (te->tag) {
      case Te_EMPTY:
         break;
      case Te_INDIR:
         te->Te.INDIR.indR
            = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR );
         if (b) changed = True;
         break;
      case Te_UNKNOWN:
         break;
      case Te_Atom:
         break;
      case Te_Field:
         te->Te.Field.typeR
            = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR );
         if (b) changed = True;
         break;
      case Te_Bound:
         break;
      case Te_TyBase:
         break;
      case Te_TyPtr:
      case Te_TyRef:
      case Te_TyPtrMbr:
      case Te_TyRvalRef:
         te->Te.TyPorR.typeR
            = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
         if (b) changed = True;
         break;
      case Te_TyTyDef:
         te->Te.TyTyDef.typeR
            = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR );
         if (b) changed = True;
         break;
      case Te_TyStOrUn:
         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs );
         if (b) changed = True;
         break;
      case Te_TyEnum:
         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs );
         if (b) changed = True;
         break;
      case Te_TyArray:
         te->Te.TyArray.typeR
            = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR );
         if (b) changed = True;
         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs );
         if (b) changed = True;
         break;
      case Te_TyFn:
         break;
      case Te_TyQual:
         te->Te.TyQual.typeR
            = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR );
         if (b) changed = True;
         break;
      case Te_TyVoid:
         break;
      default:
         ML_(pp_TyEnt)(te);
         vg_assert(0);
   }
   return changed;
}

/* Make a pass over 'ents'.  For each tyent, inspect the target of any
   'R' or 'Rs' fields (those which refer to other tyents), and replace
   any which point to INDIR nodes with the target of the indirection
   (which should not itself be an indirection).  In summary, this
   routine shorts out all references to indirection nodes. */
static
Word dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents,
                                     TyEntIndexCache* ents_cache )
{
   Word i, n, nChanged = 0;
   Bool b;
   n = VG_(sizeXA)( ents );
   for (i = 0; i < n; i++) {
      TyEnt* ent = VG_(indexXA)( ents, i );
      vg_assert(ent->tag != Te_EMPTY);
      /* We have to substitute everything, even indirections, so as to
         ensure that chains of indirections don't build up. */
      b = TyEnt__subst_R_fields( ents, ents_cache, ent );
      if (b)
         nChanged++;
   }

   return nChanged;
}


/* Make a pass over 'ents', building a dictionary of TyEnts as we go.
   Look up each new tyent in the dictionary in turn.  If it is already
   in the dictionary, replace this tyent with an indirection to the
   existing one, and delete any malloc'd stuff hanging off this one.
   In summary, this routine commons up all tyents that are identical
   as defined by TyEnt__cmp_by_all_except_cuOff. */
static
Word dedup_types_commoning_pass ( /*MOD*/XArray* /* of TyEnt */ ents )
{
   Word    n, i, nDeleted;
   WordFM* dict; /* TyEnt* -> void */
   TyEnt*  ent;
   UWord   keyW, valW;

   dict = VG_(newFM)(
             ML_(dinfo_zalloc), "di.readdwarf3.dtcp.1", 
             ML_(dinfo_free),
             (Word(*)(UWord,UWord)) ML_(TyEnt__cmp_by_all_except_cuOff)
          );

   nDeleted = 0;
   n = VG_(sizeXA)( ents );
   for (i = 0; i < n; i++) {
      ent = VG_(indexXA)( ents, i );
      vg_assert(ent->tag != Te_EMPTY);
     
      /* Ignore indirections, although check that they are
         not forming a cycle. */
      if (ent->tag == Te_INDIR) {
         vg_assert(ent->Te.INDIR.indR < ent->cuOff);
         continue;
      }

      keyW = valW = 0;
      if (VG_(lookupFM)( dict, &keyW, &valW, (UWord)ent )) {
         /* it's already in the dictionary. */
         TyEnt* old = (TyEnt*)keyW;
         vg_assert(valW == 0);
         vg_assert(old != ent);
         vg_assert(old->tag != Te_INDIR);
         /* since we are traversing the array in increasing order of
            cuOff: */
         vg_assert(old->cuOff < ent->cuOff); 
         /* So anyway, dump this entry and replace it with an
            indirection to the one in the dictionary.  Note that the
            assertion above guarantees that we cannot create cycles of
            indirections, since we are always creating an indirection
            to a tyent with a cuOff lower than this one. */
         ML_(TyEnt__make_EMPTY)( ent );
         ent->tag = Te_INDIR;
         ent->Te.INDIR.indR = old->cuOff;
         nDeleted++;
      } else {
         /* not in dictionary; add it and keep going. */
         VG_(addToFM)( dict, (UWord)ent, 0 );
      }
   }

   VG_(deleteFM)( dict, NULL, NULL );

   return nDeleted;
}


static
void dedup_types ( Bool td3, 
                   /*MOD*/XArray* /* of TyEnt */ ents,
                   TyEntIndexCache* ents_cache )
{
   Word m, n, i, nDel, nSubst, nThresh;
   if (0) td3 = True;

   n = VG_(sizeXA)( ents );

   /* If a commoning pass and a substitution pass both make fewer than
      this many changes, just stop.  It's pointless to burn up CPU
      time trying to compress the last 1% or so out of the array. */
   nThresh = n / 200;

   /* First we must sort .ents by its .cuOff fields, so we
      can index into it. */
   VG_(setCmpFnXA)( ents, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
   VG_(sortXA)( ents );

   /* Now repeatedly do commoning and substitution passes over
      the array, until there are no more changes. */
   do {
      nDel   = dedup_types_commoning_pass ( ents );
      nSubst = dedup_types_substitution_pass ( ents, ents_cache );
      vg_assert(nDel >= 0 && nSubst >= 0);
      TRACE_D3("   %ld deletions, %ld substitutions\n", nDel, nSubst);
   } while (nDel > nThresh || nSubst > nThresh);

   /* Sanity check: all INDIR nodes should point at a non-INDIR thing.
      In fact this should be true at the end of every loop iteration
      above (a commoning pass followed by a substitution pass), but
      checking it on every iteration is excessively expensive.  Note,
      this loop also computes 'm' for the stats printing below it. */
   m = 0;
   n = VG_(sizeXA)( ents );
   for (i = 0; i < n; i++) {
      TyEnt *ent, *ind;
      ent = VG_(indexXA)( ents, i );
      if (ent->tag != Te_INDIR) continue;
      m++;
      ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
                                         ent->Te.INDIR.indR );
      vg_assert(ind);
      vg_assert(ind->tag != Te_INDIR);
   }

   TRACE_D3("Overall: %ld before, %ld after\n", n, n-m);
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Resolution of references to type DIEs                ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

/* Make a pass through the (temporary) variables array.  Examine the
   type of each variable, check is it found, and chase any Te_INDIRs.
   Postcondition is: each variable has a typeR field that refers to a
   valid type in tyents, or a Te_UNKNOWN, and is certainly guaranteed
   not to refer to a Te_INDIR.  (This is so that we can throw all the
   Te_INDIRs away later). */

__attribute__((noinline))
static void resolve_variable_types (
               void (*barf)( const HChar* ) __attribute__((noreturn)),
               /*R-O*/XArray* /* of TyEnt */ ents,
               /*MOD*/TyEntIndexCache* ents_cache,
               /*MOD*/XArray* /* of TempVar* */ vars
            )
{
   Word i, n;
   n = VG_(sizeXA)( vars );
   for (i = 0; i < n; i++) {
      TempVar* var = *(TempVar**)VG_(indexXA)( vars, i );
      /* This is the stated type of the variable.  But it might be
         an indirection, so be careful. */
      TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
                                                var->typeR );
      if (ent && ent->tag == Te_INDIR) {
         ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, 
                                            ent->Te.INDIR.indR );
         vg_assert(ent);
         vg_assert(ent->tag != Te_INDIR);
      }

      /* Deal first with "normal" cases */
      if (ent && ML_(TyEnt__is_type)(ent)) {
         var->typeR = ent->cuOff;
         continue;
      }

      /* If there's no ent, it probably we did not manage to read a
         type at the cuOffset which is stated as being this variable's
         type.  Maybe a deficiency in parse_type_DIE.  Complain. */
      if (ent == NULL) {
         VG_(printf)("\n: Invalid cuOff = 0x%05lx\n", var->typeR );
         barf("resolve_variable_types: "
              "cuOff does not refer to a known type");
      }
      vg_assert(ent);
      /* If ent has any other tag, something bad happened, along the
         lines of var->typeR not referring to a type at all. */
      vg_assert(ent->tag == Te_UNKNOWN);
      /* Just accept it; the type will be useless, but at least keep
         going. */
      var->typeR = ent->cuOff;
   }
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- Parsing of Compilation Units                         ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

static Int cmp_TempVar_by_dioff ( const void* v1, const void* v2 ) {
   const TempVar* t1 = *(const TempVar *const *)v1;
   const TempVar* t2 = *(const TempVar *const *)v2;
   if (t1->dioff < t2->dioff) return -1;
   if (t1->dioff > t2->dioff) return 1;
   return 0;
}

static void read_DIE ( 
   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
   /*MOD*/XArray* /* of TyEnt */ tyents,
   /*MOD*/XArray* /* of TempVar* */ tempvars,
   /*MOD*/XArray* /* of GExpr* */ gexprs,
   /*MOD*/D3TypeParser* typarser,
   /*MOD*/D3VarParser* varparser,
   /*MOD*/D3InlParser* inlparser,
   Cursor* c, Bool td3, CUConst* cc, Int level
)
{
   g_abbv *abbv;
   ULong  atag, abbv_code;
   UInt   nf_i;
   UWord  posn;
   UInt   has_children;
   UWord  start_die_c_offset;
   UWord  after_die_c_offset;
   // If the DIE we will parse has a sibling and the parser(s) are
   // all indicating that parse_children is not necessary, then
   // we will skip the children by jumping to the sibling of this DIE
   // (if it has a sibling).
   UWord  sibling = 0;
   Bool   parse_children = False;

   /* --- Deal with this DIE --- */
   posn      = cook_die( cc, get_position_of_Cursor( c ) );
   abbv_code = get_ULEB128( c );
   abbv = get_abbv(cc, abbv_code);
   atag      = abbv->atag;
   TRACE_D3("\n");
   TRACE_D3(" <%d><%lx>: Abbrev Number: %llu (%s)\n",
            level, posn, abbv_code, ML_(pp_DW_TAG)( atag ) );

   if (atag == 0)
      cc->barf("read_DIE: invalid zero tag on DIE");

   has_children = abbv->has_children;
   if (has_children != DW_children_no && has_children != DW_children_yes)
      cc->barf("read_DIE: invalid has_children value");

   /* We're set up to look at the fields of this DIE.  Hand it off to
      any parser(s) that want to see it.  Since they will in general
      advance the DIE cursor, remember the current settings so that we
      can then back up and do one final pass over the DIE, to print out
      its contents. */
   start_die_c_offset  = get_position_of_Cursor( c );

   nf_i = 0;
   while (True) {
      FormContents cts;
      ULong at_name = abbv->nf[nf_i].at_name;
      ULong at_form = abbv->nf[nf_i].at_form;
      nf_i++;
      if (at_name == 0 && at_form == 0) break;
      TRACE_D3("     %18s: ", ML_(pp_DW_AT)(at_name));
      /* Get the form contents, but ignore them; the only purpose is
         to print them, if td3 is True */
      get_Form_contents( &cts, cc, c, td3, (DW_FORM)at_form );
      /* Except that we remember if this DIE has a sibling. */
      if (UNLIKELY(at_name == DW_AT_sibling && cts.szB > 0)) {
         sibling = cts.u.val;
      }
      TRACE_D3("\t");
      TRACE_D3("\n");
   }

   after_die_c_offset  = get_position_of_Cursor( c );

   if (VG_(clo_read_var_info)) {
      set_position_of_Cursor( c,     start_die_c_offset );

      parse_type_DIE( tyents,
                      typarser,
                      (DW_TAG)atag,
                      posn,
                      level,
                      c,     /* DIE cursor */
                      abbv,  /* abbrev */
                      cc,
                      td3 );

      set_position_of_Cursor( c,     start_die_c_offset );

      parse_var_DIE( rangestree,
                     tempvars,
                     gexprs,
                     varparser,
                     (DW_TAG)atag,
                     posn,
                     level,
                     c,     /* DIE cursor */
                     abbv,  /* abbrev */
                     cc,
                     td3 );

      parse_children = True;
      // type and var parsers do not have logic to skip childrens.
   }

   if (VG_(clo_read_inline_info)) {
      set_position_of_Cursor( c,     start_die_c_offset );

      parse_children = 
         parse_inl_DIE( inlparser,
                        (DW_TAG)atag,
                        posn,
                        level,
                        c,     /* DIE cursor */
                        abbv, /* abbrev */
                        cc,
                        td3 )
         || parse_children;
   }

   set_position_of_Cursor( c,     after_die_c_offset );

   /* --- Now recurse into its children, if any 
      and the parsing of the children is requested by a parser --- */
   if (has_children == DW_children_yes) {
      if (parse_children || sibling == 0) {
         if (0) TRACE_D3("BEGIN children of level %d\n", level);
         while (True) {
            atag = peek_ULEB128( c );
            if (atag == 0) break;
            read_DIE( rangestree, tyents, tempvars, gexprs,
                      typarser, varparser, inlparser,
                      c, td3, cc, level+1 );
         }
         /* Now we need to eat the terminating zero */
         atag = get_ULEB128( c );
         vg_assert(atag == 0);
         if (0) TRACE_D3("END children of level %d\n", level);
      } else {
         // We can skip the childrens, by jumping to the sibling
         TRACE_D3("SKIPPING DIE's children,"
                  "jumping to sibling <%d><%lx>\n",
                  level, sibling);
         set_position_of_Cursor( c, sibling );
      }
   }

}

static void trace_debug_loc (struct _DebugInfo* di,
                             __attribute__((noreturn)) void (*barf)( const HChar* ),
                             DiSlice escn_debug_loc)
{
#if 0
   /* This doesn't work properly because it assumes all entries are
      packed end to end, with no holes.  But that doesn't always
      appear to be the case, so it loses sync.  And the D3 spec
      doesn't appear to require a no-hole situation either. */
   /* Display .debug_loc */
   Addr  dl_base;
   UWord dl_offset;
   Cursor loc; /* for showing .debug_loc */
   Bool td3 = di->trace_symtab;

   TRACE_SYMTAB("\n");
   TRACE_SYMTAB("\n------ The contents of .debug_loc ------\n");
   TRACE_SYMTAB("    Offset   Begin    End      Expression\n");
   if (ML_(sli_is_valid)(escn_debug_loc)) {
      init_Cursor( &loc, escn_debug_loc, 0, barf, 
                   "Overrun whilst reading .debug_loc section(1)" );
      dl_base = 0;
      dl_offset = 0;
      while (True) {
         UWord  w1, w2;
         UWord  len;
         if (is_at_end_Cursor( &loc ))
            break;

         /* Read a (host-)word pair.  This is something of a hack since
            the word size to read is really dictated by the ELF file;
            however, we assume we're reading a file with the same
            word-sizeness as the host.  Reasonably enough. */
         w1 = get_UWord( &loc );
         w2 = get_UWord( &loc );

         if (w1 == 0 && w2 == 0) {
            /* end of list.  reset 'base' */
            TRACE_D3("    %08lx <End of list>\n", dl_offset);
            dl_base = 0;
            dl_offset = get_position_of_Cursor( &loc );
            continue;
         }

         if (w1 == -1UL) {
            /* new value for 'base' */
            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
                     dl_offset, w1, w2);
            dl_base = w2;
            continue;
         }

         /* else a location expression follows */
         TRACE_D3("    %08lx %08lx %08lx ",
                  dl_offset, w1 + dl_base, w2 + dl_base);
         len = (UWord)get_UShort( &loc );
         while (len > 0) {
            UChar byte = get_UChar( &loc );
            TRACE_D3("%02x", (UInt)byte);
            len--;
         }
         TRACE_SYMTAB("\n");
      }
   }
#endif
}

static void trace_debug_ranges (struct _DebugInfo* di,
                                __attribute__((noreturn)) void (*barf)( const HChar* ),
                                DiSlice escn_debug_ranges)
{
   Cursor ranges; /* for showing .debug_ranges */
   Addr  dr_base;
   UWord dr_offset;
   Bool td3 = di->trace_symtab;

   /* Display .debug_ranges */
   TRACE_SYMTAB("\n");
   TRACE_SYMTAB("\n------ The contents of .debug_ranges ------\n");
   TRACE_SYMTAB("    Offset   Begin    End\n");
   if (ML_(sli_is_valid)(escn_debug_ranges)) {
      init_Cursor( &ranges, escn_debug_ranges, 0, barf, 
                   "Overrun whilst reading .debug_ranges section(1)" );
      dr_base = 0;
      dr_offset = 0;
      while (True) {
         UWord  w1, w2;

         if (is_at_end_Cursor( &ranges ))
            break;

         /* Read a (host-)word pair.  This is something of a hack since
            the word size to read is really dictated by the ELF file;
            however, we assume we're reading a file with the same
            word-sizeness as the host.  Reasonably enough. */
         w1 = get_UWord( &ranges );
         w2 = get_UWord( &ranges );

         if (w1 == 0 && w2 == 0) {
            /* end of list.  reset 'base' */
            TRACE_D3("    %08lx <End of list>\n", dr_offset);
            dr_base = 0;
            dr_offset = get_position_of_Cursor( &ranges );
            continue;
         }

         if (w1 == -1UL) {
            /* new value for 'base' */
            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
                     dr_offset, w1, w2);
            dr_base = w2;
            continue;
         }

         /* else a range [w1+base, w2+base) is denoted */
         TRACE_D3("    %08lx %08lx %08lx\n",
                  dr_offset, w1 + dr_base, w2 + dr_base);
      }
   }
}

static void trace_debug_abbrev (struct _DebugInfo* di,
                                __attribute__((noreturn)) void (*barf)( const HChar* ),
                                DiSlice escn_debug_abbv)
{
   Cursor abbv; /* for showing .debug_abbrev */
   Bool td3 = di->trace_symtab;

   /* Display .debug_abbrev */
   TRACE_SYMTAB("\n");
   TRACE_SYMTAB("\n------ The contents of .debug_abbrev ------\n");
   if (ML_(sli_is_valid)(escn_debug_abbv)) {
      init_Cursor( &abbv, escn_debug_abbv, 0, barf, 
                   "Overrun whilst reading .debug_abbrev section" );
      while (True) {
         if (is_at_end_Cursor( &abbv ))
            break;
         /* Read one abbreviation table */
         TRACE_D3("  Number TAG\n");
         while (True) {
            ULong atag;
            UInt  has_children;
            ULong acode = get_ULEB128( &abbv );
            if (acode == 0) break; /* end of the table */
            atag = get_ULEB128( &abbv );
            has_children = get_UChar( &abbv );
            TRACE_D3("   %llu      %s    [%s]\n", 
                     acode, ML_(pp_DW_TAG)(atag),
                            ML_(pp_DW_children)(has_children));
            while (True) {
               ULong at_name = get_ULEB128( &abbv );
               ULong at_form = get_ULEB128( &abbv );
               if (at_name == 0 && at_form == 0) break;
               TRACE_D3("    %18s %s\n", 
                        ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form));
            }
         }
      }
   }
}

static
void new_dwarf3_reader_wrk ( 
   struct _DebugInfo* di,
   __attribute__((noreturn)) void (*barf)( const HChar* ),
   DiSlice escn_debug_info,      DiSlice escn_debug_types,
   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
   DiSlice escn_debug_str_alt
)
{
   XArray* /* of TyEnt */     tyents = NULL;
   XArray* /* of TyEnt */     tyents_to_keep = NULL;
   XArray* /* of GExpr* */    gexprs = NULL;
   XArray* /* of TempVar* */  tempvars = NULL;
   WordFM* /* of (XArray* of AddrRange, void) */ rangestree = NULL;
   TyEntIndexCache* tyents_cache = NULL;
   TyEntIndexCache* tyents_to_keep_cache = NULL;
   TempVar *varp, *varp2;
   GExpr* gexpr;
   Cursor info; /* primary cursor for parsing .debug_info */
   D3TypeParser typarser;
   D3VarParser varparser;
   D3InlParser inlparser;
   Word  i, j, n;
   Bool td3 = di->trace_symtab;
   XArray* /* of TempVar* */ dioff_lookup_tab;
   Int pass;
   VgHashTable signature_types = NULL;

   /* Display/trace various information, if requested. */
   if (td3) {
      trace_debug_loc    (di, barf, escn_debug_loc);
      trace_debug_ranges (di, barf, escn_debug_ranges);
      trace_debug_abbrev (di, barf, escn_debug_abbv);
      TRACE_SYMTAB("\n");
   }


   if (VG_(clo_read_var_info)) {
      /* We'll park the harvested type information in here.  Also create
         a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always
         have at least one type entry to refer to.  D3_FAKEVOID_CUOFF is
         huge and presumably will not occur in any valid DWARF3 file --
         it would need to have a .debug_info section 4GB long for that to
         happen.  These type entries end up in the DebugInfo. */
      tyents = VG_(newXA)( ML_(dinfo_zalloc), 
                           "di.readdwarf3.ndrw.1 (TyEnt temp array)",
                           ML_(dinfo_free), sizeof(TyEnt) );
      { TyEnt tyent;
        VG_(memset)(&tyent, 0, sizeof(tyent));
        tyent.tag   = Te_TyVoid;
        tyent.cuOff = D3_FAKEVOID_CUOFF;
        tyent.Te.TyVoid.isFake = True;
        VG_(addToXA)( tyents, &tyent );
      }
      { TyEnt tyent;
        VG_(memset)(&tyent, 0, sizeof(tyent));
        tyent.tag   = Te_UNKNOWN;
        tyent.cuOff = D3_INVALID_CUOFF;
        VG_(addToXA)( tyents, &tyent );
      }

      /* This is a tree used to unique-ify the range lists that are
         manufactured by parse_var_DIE.  References to the keys in the
         tree wind up in .rngMany fields in TempVars.  We'll need to
         delete this tree, and the XArrays attached to it, at the end of
         this function. */
      rangestree = VG_(newFM)( ML_(dinfo_zalloc),
                               "di.readdwarf3.ndrw.2 (rangestree)",
                               ML_(dinfo_free),
                               (Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange );

      /* List of variables we're accumulating.  These don't end up in the
         DebugInfo; instead their contents are handed to ML_(addVar) and
         the list elements are then deleted. */
      tempvars = VG_(newXA)( ML_(dinfo_zalloc),
                             "di.readdwarf3.ndrw.3 (TempVar*s array)",
                             ML_(dinfo_free), 
                             sizeof(TempVar*) );

      /* List of GExprs we're accumulating.  These wind up in the
         DebugInfo. */
      gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
                           ML_(dinfo_free), sizeof(GExpr*) );

      /* We need a D3TypeParser to keep track of partially constructed
         types.  It'll be discarded as soon as we've completed the CU,
         since the resulting information is tipped in to 'tyents' as it
         is generated. */
      VG_(memset)( &typarser, 0, sizeof(typarser) );
      typarser.sp = -1;
      typarser.language = '?';
      for (i = 0; i < N_D3_TYPE_STACK; i++) {
         typarser.qparentE[i].tag   = Te_EMPTY;
         typarser.qparentE[i].cuOff = D3_INVALID_CUOFF;
      }

      VG_(memset)( &varparser, 0, sizeof(varparser) );
      varparser.sp = -1;

      signature_types = VG_(HT_construct) ("signature_types");
   }

   if (VG_(clo_read_inline_info))
       VG_(memset)( &inlparser, 0, sizeof(inlparser) );

   /* Do an initial pass to scan the .debug_types section, if any, and
      fill in the signatured types hash table.  This lets us handle
      mapping from a type signature to a (cooked) DIE offset directly
      in get_Form_contents.  */
   if (VG_(clo_read_var_info) && ML_(sli_is_valid)(escn_debug_types)) {
      init_Cursor( &info, escn_debug_types, 0, barf,
                   "Overrun whilst reading .debug_types section" );
      TRACE_D3("\n------ Collecting signatures from "
               ".debug_types section ------\n");

      while (True) {
         UWord   cu_start_offset, cu_offset_now;
         CUConst cc;

         cu_start_offset = get_position_of_Cursor( &info );
         TRACE_D3("\n");
         TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
         /* parse_CU_header initialises the CU's abbv hash table.  */
         parse_CU_Header( &cc, td3, &info, escn_debug_abbv, True, False );

         /* Needed by cook_die.  */
         cc.types_cuOff_bias = escn_debug_info.szB;

         record_signatured_type( signature_types, cc.type_signature,
                                 cook_die( &cc, cc.type_offset ));

         /* Until proven otherwise we assume we don't need the icc9
            workaround in this case; see the DIE-reading loop below
            for details.  */
         cu_offset_now = (cu_start_offset + cc.unit_length
                          + (cc.is_dw64 ? 12 : 4));

         if (cu_offset_now >= escn_debug_types.szB) {
            clear_CUConst ( &cc);
            break;
         }

         set_position_of_Cursor ( &info, cu_offset_now );
      }
   }

   /* Perform three DIE-reading passes.  The first pass reads DIEs from
      alternate .debug_info (if any), the second pass reads DIEs from
      .debug_info, and the third pass reads DIEs from .debug_types.
      Moving the body of this loop into a separate function would
      require a large number of arguments to be passed in, so it is
      kept inline instead.  */
   for (pass = 0; pass < 3; ++pass) {
      ULong section_size;

      if (pass == 0) {
         if (!ML_(sli_is_valid)(escn_debug_info_alt))
	    continue;
         /* Now loop over the Compilation Units listed in the alternate
            .debug_info section (see D3SPEC sec 7.5) paras 1 and 2.
            Each compilation unit contains a Compilation Unit Header
            followed by precisely one DW_TAG_compile_unit or
            DW_TAG_partial_unit DIE. */
         init_Cursor( &info, escn_debug_info_alt, 0, barf,
                      "Overrun whilst reading alternate .debug_info section" );
         section_size = escn_debug_info_alt.szB;

         TRACE_D3("\n------ Parsing alternate .debug_info section ------\n");
      } else if (pass == 1) {
         /* Now loop over the Compilation Units listed in the .debug_info
            section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
            unit contains a Compilation Unit Header followed by precisely
            one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
         init_Cursor( &info, escn_debug_info, 0, barf,
                      "Overrun whilst reading .debug_info section" );
         section_size = escn_debug_info.szB;

         TRACE_D3("\n------ Parsing .debug_info section ------\n");
      } else {
         if (!ML_(sli_is_valid)(escn_debug_types))
            continue;
         init_Cursor( &info, escn_debug_types, 0, barf,
                      "Overrun whilst reading .debug_types section" );
         section_size = escn_debug_types.szB;

         TRACE_D3("\n------ Parsing .debug_types section ------\n");
      }

      while (True) {
         ULong   cu_start_offset, cu_offset_now;
         CUConst cc;
         /* It may be that the stated size of this CU is larger than the
            amount of stuff actually in it.  icc9 seems to generate CUs
            thusly.  We use these variables to figure out if this is
            indeed the case, and if so how many bytes we need to skip to
            get to the start of the next CU.  Not skipping those bytes
            causes us to misidentify the start of the next CU, and it all
            goes badly wrong after that (not surprisingly). */
         UWord cu_size_including_IniLen, cu_amount_used;

         /* It seems icc9 finishes the DIE info before debug_info_sz
            bytes have been used up.  So be flexible, and declare the
            sequence complete if there is not enough remaining bytes to
            hold even the smallest conceivable CU header.  (11 bytes I
            reckon). */
         /* JRS 23Jan09: I suspect this is no longer necessary now that
            the code below contains a 'while (cu_amount_used <
            cu_size_including_IniLen ...'  style loop, which skips over
            any leftover bytes at the end of a CU in the case where the
            CU's stated size is larger than its actual size (as
            determined by reading all its DIEs).  However, for prudence,
            I'll leave the following test in place.  I can't see that a
            CU header can be smaller than 11 bytes, so I don't think
            there's any harm possible through the test -- it just adds
            robustness. */
         Word avail = get_remaining_length_Cursor( &info );
         if (avail < 11) {
            if (avail > 0)
               TRACE_D3("new_dwarf3_reader_wrk: warning: "
                        "%ld unused bytes after end of DIEs\n", avail);
            break;
         }

         if (VG_(clo_read_var_info)) {
            /* Check the varparser's stack is in a sane state. */
            vg_assert(varparser.sp == -1);
            for (i = 0; i < N_D3_VAR_STACK; i++) {
               vg_assert(varparser.ranges[i] == NULL);
               vg_assert(varparser.level[i] == 0);
            }
            for (i = 0; i < N_D3_TYPE_STACK; i++) {
               vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
               vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
               vg_assert(typarser.qlevel[i] == 0);
            }
         }

         cu_start_offset = get_position_of_Cursor( &info );
         TRACE_D3("\n");
         TRACE_D3("  Compilation Unit @ offset 0x%llx:\n", cu_start_offset);
         /* parse_CU_header initialises the CU's hashtable of abbvs ht_abbvs */
         if (pass == 0) {
            parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt,
                             False, True );
         } else {
            parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
                             pass == 2, False );
         }
         cc.escn_debug_str      = pass == 0 ? escn_debug_str_alt
                                            : escn_debug_str;
         cc.escn_debug_ranges   = escn_debug_ranges;
         cc.escn_debug_loc      = escn_debug_loc;
         cc.escn_debug_line     = pass == 0 ? escn_debug_line_alt
                                            : escn_debug_line;
         cc.escn_debug_info     = pass == 0 ? escn_debug_info_alt
                                            : escn_debug_info;
         cc.escn_debug_types    = escn_debug_types;
         cc.escn_debug_info_alt = escn_debug_info_alt;
         cc.escn_debug_str_alt  = escn_debug_str_alt;
         cc.types_cuOff_bias    = escn_debug_info.szB;
         cc.alt_cuOff_bias      = escn_debug_info.szB + escn_debug_types.szB;
         cc.cu_start_offset     = cu_start_offset;
         cc.di = di;
         /* The CU's svma can be deduced by looking at the AT_low_pc
            value in the top level TAG_compile_unit, which is the topmost
            DIE.  We'll leave it for the 'varparser' to acquire that info
            and fill it in -- since it is the only party to want to know
            it. */
         cc.cu_svma_known = False;
         cc.cu_svma       = 0;

         if (VG_(clo_read_var_info)) {
            cc.signature_types = signature_types;

            /* Create a fake outermost-level range covering the entire
               address range.  So we always have *something* to catch all
               variable declarations. */
            varstack_push( &cc, &varparser, td3, 
                           unitary_range_list(0UL, ~0UL),
                           -1, False/*isFunc*/, NULL/*fbGX*/ );

            /* And set up the file name table.  When we come across the top
               level DIE for this CU (which is what the next call to
               read_DIE should process) we will copy all the file names out
               of the .debug_line img area and use this table to look up the
               copies when we later see filename numbers in DW_TAG_variables
               etc. */
            vg_assert(!varparser.filenameTable );
            varparser.filenameTable 
               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5var",
                             ML_(dinfo_free),
                             sizeof(UChar*) );
            vg_assert(varparser.filenameTable);
         }

         if (VG_(clo_read_inline_info)) {
            /* filename table for the inlined call parser */
            vg_assert(!inlparser.filenameTable );
            inlparser.filenameTable 
               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5inl",
                             ML_(dinfo_free),
                             sizeof(UChar*) );
            vg_assert(inlparser.filenameTable);
         }

         /* Now read the one-and-only top-level DIE for this CU. */
         vg_assert(!VG_(clo_read_var_info) || varparser.sp == 0);
         read_DIE( rangestree,
                   tyents, tempvars, gexprs,
                   &typarser, &varparser, &inlparser,
                   &info, td3, &cc, 0 );

         cu_offset_now = get_position_of_Cursor( &info );

         if (0) VG_(printf)("Travelled: %llu  size %llu\n",
                            cu_offset_now - cc.cu_start_offset,
                            cc.unit_length + (cc.is_dw64 ? 12 : 4));

         /* How big the CU claims it is .. */
         cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
         /* .. vs how big we have found it to be */
         cu_amount_used = cu_offset_now - cc.cu_start_offset;

         if (1) TRACE_D3("offset now %lld, d-i-size %lld\n",
                         cu_offset_now, section_size);
         if (cu_offset_now > section_size)
            barf("toplevel DIEs beyond end of CU");

         /* If the CU is bigger than it claims to be, we've got a serious
            problem. */
         if (cu_amount_used > cu_size_including_IniLen)
            barf("CU's actual size appears to be larger than it claims it is");

         /* If the CU is smaller than it claims to be, we need to skip some
            bytes.  Loop updates cu_offset_new and cu_amount_used. */
         while (cu_amount_used < cu_size_including_IniLen
                && get_remaining_length_Cursor( &info ) > 0) {
            if (0) VG_(printf)("SKIP\n");
            (void)get_UChar( &info );
            cu_offset_now = get_position_of_Cursor( &info );
            cu_amount_used = cu_offset_now - cc.cu_start_offset;
         }

         if (VG_(clo_read_var_info)) {
            /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
               anywhere else at all.  Our fake the-entire-address-space
               range is at level -1, so preening to -2 should completely
               empty the stack out. */
            TRACE_D3("\n");
            varstack_preen( &varparser, td3, -2 );
            /* Similarly, empty the type stack out. */
            typestack_preen( &typarser, td3, -2 );
         }

         if (VG_(clo_read_var_info)) {
            vg_assert(varparser.filenameTable );
            VG_(deleteXA)( varparser.filenameTable );
            varparser.filenameTable = NULL;
            vg_assert(inlparser.filenameTable );
         }
         if (VG_(clo_read_inline_info)) {
            VG_(deleteXA)( inlparser.filenameTable );
            inlparser.filenameTable = NULL;
         }
         clear_CUConst(&cc);

         if (cu_offset_now == section_size)
            break;
         /* else keep going */
      }
   }


   if (VG_(clo_read_var_info)) {
      /* From here on we're post-processing the stuff we got
         out of the .debug_info section. */
      if (td3) {
         TRACE_D3("\n");
         ML_(pp_TyEnts)(tyents, "Initial type entity (TyEnt) array");
         TRACE_D3("\n");
         TRACE_D3("------ Compressing type entries ------\n");
      }

      tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6",
                                        sizeof(TyEntIndexCache) );
      ML_(TyEntIndexCache__invalidate)( tyents_cache );
      dedup_types( td3, tyents, tyents_cache );
      if (td3) {
         TRACE_D3("\n");
         ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression");
      }

      TRACE_D3("\n");
      TRACE_D3("------ Resolving the types of variables ------\n" );
      resolve_variable_types( barf, tyents, tyents_cache, tempvars );

      /* Copy all the non-INDIR tyents into a new table.  For large
         .so's, about 90% of the tyents will by now have been resolved to
         INDIRs, and we no longer need them, and so don't need to store
         them. */
      tyents_to_keep
         = VG_(newXA)( ML_(dinfo_zalloc), 
                       "di.readdwarf3.ndrw.7 (TyEnt to-keep array)",
                       ML_(dinfo_free), sizeof(TyEnt) );
      n = VG_(sizeXA)( tyents );
      for (i = 0; i < n; i++) {
         TyEnt* ent = VG_(indexXA)( tyents, i );
         if (ent->tag != Te_INDIR)
            VG_(addToXA)( tyents_to_keep, ent );
      }

      VG_(deleteXA)( tyents );
      tyents = NULL;
      ML_(dinfo_free)( tyents_cache );
      tyents_cache = NULL;

      /* Sort tyents_to_keep so we can lookup in it.  A complete (if
         minor) waste of time, since tyents itself is sorted, but
         necessary since VG_(lookupXA) refuses to cooperate if we
         don't. */
      VG_(setCmpFnXA)( tyents_to_keep, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
      VG_(sortXA)( tyents_to_keep );

      /* Enable cacheing on tyents_to_keep */
      tyents_to_keep_cache
         = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8",
                              sizeof(TyEntIndexCache) );
      ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache );

      /* And record the tyents in the DebugInfo.  We do this before
         starting to hand variables to ML_(addVar), since if ML_(addVar)
         wants to do debug printing (of the types of said vars) then it
         will need the tyents.*/
      vg_assert(!di->admin_tyents);
      di->admin_tyents = tyents_to_keep;

      /* Bias all the location expressions. */
      TRACE_D3("\n");
      TRACE_D3("------ Biasing the location expressions ------\n" );

      n = VG_(sizeXA)( gexprs );
      for (i = 0; i < n; i++) {
         gexpr = *(GExpr**)VG_(indexXA)( gexprs, i );
         bias_GX( gexpr, di );
      }

      TRACE_D3("\n");
      TRACE_D3("------ Acquired the following variables: ------\n\n");

      /* Park (pointers to) all the vars in an XArray, so we can look up
         abstract origins quickly.  The array is sorted (hence, looked-up
         by) the .dioff fields.  Since the .dioffs should be in strictly
         ascending order, there is no need to sort the array after
         construction.  The ascendingness is however asserted for. */
      dioff_lookup_tab
         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9",
                       ML_(dinfo_free), 
                       sizeof(TempVar*) );
      vg_assert(dioff_lookup_tab);

      n = VG_(sizeXA)( tempvars );
      Word first_primary_var = 0;
      for (first_primary_var = 0;
           escn_debug_info_alt.szB/*really?*/ && first_primary_var < n;
           first_primary_var++) {
         varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var );
         if (varp->dioff < escn_debug_info.szB + escn_debug_types.szB)
            break;
      }
      for (i = 0; i < n; i++) {
         varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n );
         if (i > first_primary_var) {
            varp2 = *(TempVar**)VG_(indexXA)( tempvars,
                                              (i + first_primary_var - 1) % n );
            /* why should this hold?  Only, I think, because we've
               constructed the array by reading .debug_info sequentially,
               and so the array .dioff fields should reflect that, and be
               strictly ascending. */
            vg_assert(varp2->dioff < varp->dioff);
         }
         VG_(addToXA)( dioff_lookup_tab, &varp );
      }
      VG_(setCmpFnXA)( dioff_lookup_tab, cmp_TempVar_by_dioff );
      VG_(sortXA)( dioff_lookup_tab ); /* POINTLESS; FIXME: rm */

      /* Now visit each var.  Collect up as much info as possible for
         each var and hand it to ML_(addVar). */
      n = VG_(sizeXA)( tempvars );
      for (j = 0; j < n; j++) {
         TyEnt* ent;
         varp = *(TempVar**)VG_(indexXA)( tempvars, j );

         /* Possibly show .. */
         if (td3) {
            VG_(printf)("<%lx> addVar: level %d: %s :: ",
                        varp->dioff,
                        varp->level,
                        varp->name ? varp->name : "<anon_var>" );
            if (varp->typeR) {
               ML_(pp_TyEnt_C_ishly)( tyents_to_keep, varp->typeR );
            } else {
               VG_(printf)("NULL");
            }
            VG_(printf)("\n  Loc=");
            if (varp->gexpr) {
               ML_(pp_GX)(varp->gexpr);
            } else {
               VG_(printf)("NULL");
            }
            VG_(printf)("\n");
            if (varp->fbGX) {
               VG_(printf)("  FrB=");
               ML_(pp_GX)( varp->fbGX );
               VG_(printf)("\n");
            } else {
               VG_(printf)("  FrB=none\n");
            }
            VG_(printf)("  declared at: %s:%d\n",
                        varp->fName ? varp->fName : "NULL",
                        varp->fLine );
            if (varp->absOri != (UWord)D3_INVALID_CUOFF)
               VG_(printf)("  abstract origin: <%lx>\n", varp->absOri);
         }

         /* Skip variables which have no location.  These must be
            abstract instances; they are useless as-is since with no
            location they have no specified memory location.  They will
            presumably be referred to via the absOri fields of other
            variables. */
         if (!varp->gexpr) {
            TRACE_D3("  SKIP (no location)\n\n");
            continue;
         }

         /* So it has a location, at least.  If it refers to some other
            entry through its absOri field, pull in further info through
            that. */
         if (varp->absOri != (UWord)D3_INVALID_CUOFF) {
            Bool found;
            Word ixFirst, ixLast;
            TempVar key;
            TempVar* keyp = &key;
            TempVar *varAI;
            VG_(memset)(&key, 0, sizeof(key)); /* not necessary */
            key.dioff = varp->absOri; /* this is what we want to find */
            found = VG_(lookupXA)( dioff_lookup_tab, &keyp,
                                   &ixFirst, &ixLast );
            if (!found) {
               /* barf("DW_AT_abstract_origin can't be resolved"); */
               TRACE_D3("  SKIP (DW_AT_abstract_origin can't be resolved)\n\n");
               continue;
            }
            /* If the following fails, there is more than one entry with
               the same dioff.  Which can't happen. */
            vg_assert(ixFirst == ixLast);
            varAI = *(TempVar**)VG_(indexXA)( dioff_lookup_tab, ixFirst );
            /* stay sane */
            vg_assert(varAI);
            vg_assert(varAI->dioff == varp->absOri);

            /* Copy what useful info we can. */
            if (varAI->typeR && !varp->typeR)
               varp->typeR = varAI->typeR;
            if (varAI->name && !varp->name)
               varp->name = varAI->name;
            if (varAI->fName && !varp->fName)
               varp->fName = varAI->fName;
            if (varAI->fLine > 0 && varp->fLine == 0)
               varp->fLine = varAI->fLine;
         }

         /* Give it a name if it doesn't have one. */
         if (!varp->name)
            varp->name = ML_(addStr)( di, "<anon_var>", -1 );

         /* So now does it have enough info to be useful? */
         /* NOTE: re typeR: this is a hack.  If typeR is Te_UNKNOWN then
            the type didn't get resolved.  Really, in that case
            something's broken earlier on, and should be fixed, rather
            than just skipping the variable. */
         ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep,
                                            tyents_to_keep_cache, 
                                            varp->typeR );
         /* The next two assertions should be guaranteed by 
            our previous call to resolve_variable_types. */
         vg_assert(ent);
         vg_assert(ML_(TyEnt__is_type)(ent) || ent->tag == Te_UNKNOWN);

         if (ent->tag == Te_UNKNOWN) continue;

         vg_assert(varp->gexpr);
         vg_assert(varp->name);
         vg_assert(varp->typeR);
         vg_assert(varp->level >= 0);

         /* Ok.  So we're going to keep it.  Call ML_(addVar) once for
            each address range in which the variable exists. */
         TRACE_D3("  ACQUIRE for range(s) ");
         { AddrRange  oneRange;
           AddrRange* varPcRanges;
           Word       nVarPcRanges;
           /* Set up to iterate over address ranges, however
              represented. */
           if (varp->nRanges == 0 || varp->nRanges == 1) {
              vg_assert(!varp->rngMany);
              if (varp->nRanges == 0) {
                 vg_assert(varp->rngOneMin == 0);
                 vg_assert(varp->rngOneMax == 0);
              }
              nVarPcRanges = varp->nRanges;
              oneRange.aMin = varp->rngOneMin;
              oneRange.aMax = varp->rngOneMax;
              varPcRanges = &oneRange;
           } else {
              vg_assert(varp->rngMany);
              vg_assert(varp->rngOneMin == 0);
              vg_assert(varp->rngOneMax == 0);
              nVarPcRanges = VG_(sizeXA)(varp->rngMany);
              vg_assert(nVarPcRanges >= 2);
              vg_assert(nVarPcRanges == (Word)varp->nRanges);
              varPcRanges = VG_(indexXA)(varp->rngMany, 0);
           }
           if (varp->level == 0)
              vg_assert( nVarPcRanges == 1 );
           /* and iterate */
           for (i = 0; i < nVarPcRanges; i++) {
              Addr pcMin = varPcRanges[i].aMin;
              Addr pcMax = varPcRanges[i].aMax;
              vg_assert(pcMin <= pcMax);
              /* Level 0 is the global address range.  So at level 0 we
                 don't want to bias pcMin/pcMax; but at all other levels
                 we do since those are derived from svmas in the Dwarf
                 we're reading.  Be paranoid ... */
              if (varp->level == 0) {
                 vg_assert(pcMin == (Addr)0);
                 vg_assert(pcMax == ~(Addr)0);
              } else {
                 /* vg_assert(pcMin > (Addr)0);
                    No .. we can legitimately expect to see ranges like 
                    0x0-0x11D (pre-biasing, of course). */
                 vg_assert(pcMax < ~(Addr)0);
              }

              /* Apply text biasing, for non-global variables. */
              if (varp->level > 0) {
                 pcMin += di->text_debug_bias;
                 pcMax += di->text_debug_bias;
              } 

              if (i > 0 && (i%2) == 0) 
                 TRACE_D3("\n                       ");
              TRACE_D3("[%#lx,%#lx] ", pcMin, pcMax );

              ML_(addVar)(
                 di, varp->level, 
                     pcMin, pcMax,
                     varp->name,  varp->typeR,
                     varp->gexpr, varp->fbGX,
                     varp->fName, varp->fLine, td3 
              );
           }
         }

         TRACE_D3("\n\n");
         /* and move on to the next var */
      }

      /* Now free all the TempVars */
      n = VG_(sizeXA)( tempvars );
      for (i = 0; i < n; i++) {
         varp = *(TempVar**)VG_(indexXA)( tempvars, i );
         ML_(dinfo_free)(varp);
      }
      VG_(deleteXA)( tempvars );
      tempvars = NULL;

      /* and the temp lookup table */
      VG_(deleteXA)( dioff_lookup_tab );

      /* and the ranges tree.  Note that we need to also free the XArrays
         which constitute the keys, hence pass VG_(deleteXA) as a
         key-finalizer. */
      VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL );

      /* and the tyents_to_keep cache */
      ML_(dinfo_free)( tyents_to_keep_cache );
      tyents_to_keep_cache = NULL;

      vg_assert( varparser.filenameTable == NULL );

      /* And the signatured type hash.  */
      VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );

      /* record the GExprs in di so they can be freed later */
      vg_assert(!di->admin_gexprs);
      di->admin_gexprs = gexprs;
   }
}


/*------------------------------------------------------------*/
/*---                                                      ---*/
/*--- The "new" DWARF3 reader -- top level control logic   ---*/
/*---                                                      ---*/
/*------------------------------------------------------------*/

static Bool               d3rd_jmpbuf_valid  = False;
static const HChar*       d3rd_jmpbuf_reason = NULL;
static VG_MINIMAL_JMP_BUF(d3rd_jmpbuf);

static __attribute__((noreturn)) void barf ( const HChar* reason ) {
   vg_assert(d3rd_jmpbuf_valid);
   d3rd_jmpbuf_reason = reason;
   VG_MINIMAL_LONGJMP(d3rd_jmpbuf);
   /*NOTREACHED*/
   vg_assert(0);
}


void 
ML_(new_dwarf3_reader) (
   struct _DebugInfo* di,
   DiSlice escn_debug_info,      DiSlice escn_debug_types,
   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
   DiSlice escn_debug_str_alt
)
{
   volatile Int  jumped;
   volatile Bool td3 = di->trace_symtab;

   /* Run the _wrk function to read the dwarf3.  If it succeeds, it
      just returns normally.  If there is any failure, it longjmp's
      back here, having first set d3rd_jmpbuf_reason to something
      useful. */
   vg_assert(d3rd_jmpbuf_valid  == False);
   vg_assert(d3rd_jmpbuf_reason == NULL);

   d3rd_jmpbuf_valid = True;
   jumped = VG_MINIMAL_SETJMP(d3rd_jmpbuf);
   if (jumped == 0) {
      /* try this ... */
      new_dwarf3_reader_wrk( di, barf,
                             escn_debug_info,     escn_debug_types,
                             escn_debug_abbv,     escn_debug_line,
                             escn_debug_str,      escn_debug_ranges,
                             escn_debug_loc,      escn_debug_info_alt,
                             escn_debug_abbv_alt, escn_debug_line_alt,
                             escn_debug_str_alt );
      d3rd_jmpbuf_valid = False;
      TRACE_D3("\n------ .debug_info reading was successful ------\n");
   } else {
      /* It longjmp'd. */
      d3rd_jmpbuf_valid = False;
      /* Can't longjump without giving some sort of reason. */
      vg_assert(d3rd_jmpbuf_reason != NULL);

      TRACE_D3("\n------ .debug_info reading failed ------\n");

      ML_(symerr)(di, True, d3rd_jmpbuf_reason);
   }

   d3rd_jmpbuf_valid  = False;
   d3rd_jmpbuf_reason = NULL;
}



/* --- Unused code fragments which might be useful one day. --- */

#if 0
   /* Read the arange tables */
   TRACE_SYMTAB("\n");
   TRACE_SYMTAB("\n------ The contents of .debug_arange ------\n");
   init_Cursor( &aranges, debug_aranges_img, 
                debug_aranges_sz, 0, barf, 
                "Overrun whilst reading .debug_aranges section" );
   while (True) {
      ULong  len, d_i_offset;
      Bool   is64;
      UShort version;
      UChar  asize, segsize;

      if (is_at_end_Cursor( &aranges ))
         break;
      /* Read one arange thingy */
      /* initial_length field */
      len = get_Initial_Length( &is64, &aranges, 
               "in .debug_aranges: invalid initial-length field" );
      version    = get_UShort( &aranges );
      d_i_offset = get_Dwarfish_UWord( &aranges, is64 );
      asize      = get_UChar( &aranges );
      segsize    = get_UChar( &aranges );
      TRACE_D3("  Length:                   %llu\n", len);
      TRACE_D3("  Version:                  %d\n", (Int)version);
      TRACE_D3("  Offset into .debug_info:  %llx\n", d_i_offset);
      TRACE_D3("  Pointer Size:             %d\n", (Int)asize);
      TRACE_D3("  Segment Size:             %d\n", (Int)segsize);
      TRACE_D3("\n");
      TRACE_D3("    Address            Length\n");

      while ((get_position_of_Cursor( &aranges ) % (2 * asize)) > 0) {
         (void)get_UChar( & aranges );
      }
      while (True) {
         ULong address = get_Dwarfish_UWord( &aranges, asize==8 );
         ULong length = get_Dwarfish_UWord( &aranges, asize==8 );
         TRACE_D3("    0x%016llx 0x%llx\n", address, length);
         if (address == 0 && length == 0) break;
      }
   }
   TRACE_SYMTAB("\n");
#endif

#endif // defined(VGO_linux) || defined(VGO_darwin)

/*--------------------------------------------------------------------*/
/*--- end                                                          ---*/
/*--------------------------------------------------------------------*/
